lib.rs

   1pub mod display_map;
   2mod element;
   3pub mod movement;
   4
   5#[cfg(test)]
   6mod test;
   7
   8use buffer::*;
   9use clock::ReplicaId;
  10pub use display_map::DisplayPoint;
  11use display_map::*;
  12pub use element::*;
  13use gpui::{
  14    action, color::Color, fonts::TextStyle, geometry::vector::Vector2F, keymap::Binding,
  15    text_layout, AppContext, ClipboardItem, Element, ElementBox, Entity, ModelHandle,
  16    MutableAppContext, RenderContext, View, ViewContext, WeakViewHandle,
  17};
  18use serde::{Deserialize, Serialize};
  19use smallvec::SmallVec;
  20use smol::Timer;
  21use std::{
  22    cell::RefCell,
  23    cmp::{self, Ordering},
  24    mem,
  25    ops::{Range, RangeInclusive},
  26    rc::Rc,
  27    sync::Arc,
  28    time::Duration,
  29};
  30use sum_tree::Bias;
  31use theme::EditorStyle;
  32use util::post_inc;
  33
  34const CURSOR_BLINK_INTERVAL: Duration = Duration::from_millis(500);
  35const MAX_LINE_LEN: usize = 1024;
  36
  37action!(Cancel);
  38action!(Backspace);
  39action!(Delete);
  40action!(Insert, String);
  41action!(DeleteLine);
  42action!(DeleteToPreviousWordBoundary);
  43action!(DeleteToNextWordBoundary);
  44action!(DeleteToBeginningOfLine);
  45action!(DeleteToEndOfLine);
  46action!(CutToEndOfLine);
  47action!(DuplicateLine);
  48action!(MoveLineUp);
  49action!(MoveLineDown);
  50action!(Cut);
  51action!(Copy);
  52action!(Paste);
  53action!(Undo);
  54action!(Redo);
  55action!(MoveUp);
  56action!(MoveDown);
  57action!(MoveLeft);
  58action!(MoveRight);
  59action!(MoveToPreviousWordBoundary);
  60action!(MoveToNextWordBoundary);
  61action!(MoveToBeginningOfLine);
  62action!(MoveToEndOfLine);
  63action!(MoveToBeginning);
  64action!(MoveToEnd);
  65action!(SelectUp);
  66action!(SelectDown);
  67action!(SelectLeft);
  68action!(SelectRight);
  69action!(SelectToPreviousWordBoundary);
  70action!(SelectToNextWordBoundary);
  71action!(SelectToBeginningOfLine, bool);
  72action!(SelectToEndOfLine);
  73action!(SelectToBeginning);
  74action!(SelectToEnd);
  75action!(SelectAll);
  76action!(SelectLine);
  77action!(SplitSelectionIntoLines);
  78action!(AddSelectionAbove);
  79action!(AddSelectionBelow);
  80action!(SelectLargerSyntaxNode);
  81action!(SelectSmallerSyntaxNode);
  82action!(MoveToEnclosingBracket);
  83action!(PageUp);
  84action!(PageDown);
  85action!(Fold);
  86action!(Unfold);
  87action!(FoldSelectedRanges);
  88action!(Scroll, Vector2F);
  89action!(Select, SelectPhase);
  90
  91pub fn init(cx: &mut MutableAppContext) {
  92    cx.add_bindings(vec![
  93        Binding::new("escape", Cancel, Some("Editor")),
  94        Binding::new("backspace", Backspace, Some("Editor")),
  95        Binding::new("ctrl-h", Backspace, Some("Editor")),
  96        Binding::new("delete", Delete, Some("Editor")),
  97        Binding::new("ctrl-d", Delete, Some("Editor")),
  98        Binding::new("enter", Insert("\n".into()), Some("Editor && mode == full")),
  99        Binding::new(
 100            "alt-enter",
 101            Insert("\n".into()),
 102            Some("Editor && mode == auto_height"),
 103        ),
 104        Binding::new("tab", Insert("\t".into()), Some("Editor")),
 105        Binding::new("ctrl-shift-K", DeleteLine, Some("Editor")),
 106        Binding::new(
 107            "alt-backspace",
 108            DeleteToPreviousWordBoundary,
 109            Some("Editor"),
 110        ),
 111        Binding::new("alt-h", DeleteToPreviousWordBoundary, Some("Editor")),
 112        Binding::new("alt-delete", DeleteToNextWordBoundary, Some("Editor")),
 113        Binding::new("alt-d", DeleteToNextWordBoundary, Some("Editor")),
 114        Binding::new("cmd-backspace", DeleteToBeginningOfLine, Some("Editor")),
 115        Binding::new("cmd-delete", DeleteToEndOfLine, Some("Editor")),
 116        Binding::new("ctrl-k", CutToEndOfLine, Some("Editor")),
 117        Binding::new("cmd-shift-D", DuplicateLine, Some("Editor")),
 118        Binding::new("ctrl-cmd-up", MoveLineUp, Some("Editor")),
 119        Binding::new("ctrl-cmd-down", MoveLineDown, Some("Editor")),
 120        Binding::new("cmd-x", Cut, Some("Editor")),
 121        Binding::new("cmd-c", Copy, Some("Editor")),
 122        Binding::new("cmd-v", Paste, Some("Editor")),
 123        Binding::new("cmd-z", Undo, Some("Editor")),
 124        Binding::new("cmd-shift-Z", Redo, Some("Editor")),
 125        Binding::new("up", MoveUp, Some("Editor")),
 126        Binding::new("down", MoveDown, Some("Editor")),
 127        Binding::new("left", MoveLeft, Some("Editor")),
 128        Binding::new("right", MoveRight, Some("Editor")),
 129        Binding::new("ctrl-p", MoveUp, Some("Editor")),
 130        Binding::new("ctrl-n", MoveDown, Some("Editor")),
 131        Binding::new("ctrl-b", MoveLeft, Some("Editor")),
 132        Binding::new("ctrl-f", MoveRight, Some("Editor")),
 133        Binding::new("alt-left", MoveToPreviousWordBoundary, Some("Editor")),
 134        Binding::new("alt-b", MoveToPreviousWordBoundary, Some("Editor")),
 135        Binding::new("alt-right", MoveToNextWordBoundary, Some("Editor")),
 136        Binding::new("alt-f", MoveToNextWordBoundary, Some("Editor")),
 137        Binding::new("cmd-left", MoveToBeginningOfLine, Some("Editor")),
 138        Binding::new("ctrl-a", MoveToBeginningOfLine, Some("Editor")),
 139        Binding::new("cmd-right", MoveToEndOfLine, Some("Editor")),
 140        Binding::new("ctrl-e", MoveToEndOfLine, Some("Editor")),
 141        Binding::new("cmd-up", MoveToBeginning, Some("Editor")),
 142        Binding::new("cmd-down", MoveToEnd, Some("Editor")),
 143        Binding::new("shift-up", SelectUp, Some("Editor")),
 144        Binding::new("ctrl-shift-P", SelectUp, Some("Editor")),
 145        Binding::new("shift-down", SelectDown, Some("Editor")),
 146        Binding::new("ctrl-shift-N", SelectDown, Some("Editor")),
 147        Binding::new("shift-left", SelectLeft, Some("Editor")),
 148        Binding::new("ctrl-shift-B", SelectLeft, Some("Editor")),
 149        Binding::new("shift-right", SelectRight, Some("Editor")),
 150        Binding::new("ctrl-shift-F", SelectRight, Some("Editor")),
 151        Binding::new(
 152            "alt-shift-left",
 153            SelectToPreviousWordBoundary,
 154            Some("Editor"),
 155        ),
 156        Binding::new("alt-shift-B", SelectToPreviousWordBoundary, Some("Editor")),
 157        Binding::new("alt-shift-right", SelectToNextWordBoundary, Some("Editor")),
 158        Binding::new("alt-shift-F", SelectToNextWordBoundary, Some("Editor")),
 159        Binding::new(
 160            "cmd-shift-left",
 161            SelectToBeginningOfLine(true),
 162            Some("Editor"),
 163        ),
 164        Binding::new(
 165            "ctrl-shift-A",
 166            SelectToBeginningOfLine(true),
 167            Some("Editor"),
 168        ),
 169        Binding::new("cmd-shift-right", SelectToEndOfLine, Some("Editor")),
 170        Binding::new("ctrl-shift-E", SelectToEndOfLine, Some("Editor")),
 171        Binding::new("cmd-shift-up", SelectToBeginning, Some("Editor")),
 172        Binding::new("cmd-shift-down", SelectToEnd, Some("Editor")),
 173        Binding::new("cmd-a", SelectAll, Some("Editor")),
 174        Binding::new("cmd-l", SelectLine, Some("Editor")),
 175        Binding::new("cmd-shift-L", SplitSelectionIntoLines, Some("Editor")),
 176        Binding::new("cmd-alt-up", AddSelectionAbove, Some("Editor")),
 177        Binding::new("cmd-ctrl-p", AddSelectionAbove, Some("Editor")),
 178        Binding::new("cmd-alt-down", AddSelectionBelow, Some("Editor")),
 179        Binding::new("cmd-ctrl-n", AddSelectionBelow, Some("Editor")),
 180        Binding::new("alt-up", SelectLargerSyntaxNode, Some("Editor")),
 181        Binding::new("ctrl-w", SelectLargerSyntaxNode, Some("Editor")),
 182        Binding::new("alt-down", SelectSmallerSyntaxNode, Some("Editor")),
 183        Binding::new("ctrl-shift-W", SelectSmallerSyntaxNode, Some("Editor")),
 184        Binding::new("ctrl-m", MoveToEnclosingBracket, Some("Editor")),
 185        Binding::new("pageup", PageUp, Some("Editor")),
 186        Binding::new("pagedown", PageDown, Some("Editor")),
 187        Binding::new("alt-cmd-[", Fold, Some("Editor")),
 188        Binding::new("alt-cmd-]", Unfold, Some("Editor")),
 189        Binding::new("alt-cmd-f", FoldSelectedRanges, Some("Editor")),
 190    ]);
 191
 192    cx.add_action(|this: &mut Editor, action: &Scroll, cx| this.set_scroll_position(action.0, cx));
 193    cx.add_action(Editor::select);
 194    cx.add_action(Editor::cancel);
 195    cx.add_action(Editor::insert);
 196    cx.add_action(Editor::backspace);
 197    cx.add_action(Editor::delete);
 198    cx.add_action(Editor::delete_line);
 199    cx.add_action(Editor::delete_to_previous_word_boundary);
 200    cx.add_action(Editor::delete_to_next_word_boundary);
 201    cx.add_action(Editor::delete_to_beginning_of_line);
 202    cx.add_action(Editor::delete_to_end_of_line);
 203    cx.add_action(Editor::cut_to_end_of_line);
 204    cx.add_action(Editor::duplicate_line);
 205    cx.add_action(Editor::move_line_up);
 206    cx.add_action(Editor::move_line_down);
 207    cx.add_action(Editor::cut);
 208    cx.add_action(Editor::copy);
 209    cx.add_action(Editor::paste);
 210    cx.add_action(Editor::undo);
 211    cx.add_action(Editor::redo);
 212    cx.add_action(Editor::move_up);
 213    cx.add_action(Editor::move_down);
 214    cx.add_action(Editor::move_left);
 215    cx.add_action(Editor::move_right);
 216    cx.add_action(Editor::move_to_previous_word_boundary);
 217    cx.add_action(Editor::move_to_next_word_boundary);
 218    cx.add_action(Editor::move_to_beginning_of_line);
 219    cx.add_action(Editor::move_to_end_of_line);
 220    cx.add_action(Editor::move_to_beginning);
 221    cx.add_action(Editor::move_to_end);
 222    cx.add_action(Editor::select_up);
 223    cx.add_action(Editor::select_down);
 224    cx.add_action(Editor::select_left);
 225    cx.add_action(Editor::select_right);
 226    cx.add_action(Editor::select_to_previous_word_boundary);
 227    cx.add_action(Editor::select_to_next_word_boundary);
 228    cx.add_action(Editor::select_to_beginning_of_line);
 229    cx.add_action(Editor::select_to_end_of_line);
 230    cx.add_action(Editor::select_to_beginning);
 231    cx.add_action(Editor::select_to_end);
 232    cx.add_action(Editor::select_all);
 233    cx.add_action(Editor::select_line);
 234    cx.add_action(Editor::split_selection_into_lines);
 235    cx.add_action(Editor::add_selection_above);
 236    cx.add_action(Editor::add_selection_below);
 237    cx.add_action(Editor::select_larger_syntax_node);
 238    cx.add_action(Editor::select_smaller_syntax_node);
 239    cx.add_action(Editor::move_to_enclosing_bracket);
 240    cx.add_action(Editor::page_up);
 241    cx.add_action(Editor::page_down);
 242    cx.add_action(Editor::fold);
 243    cx.add_action(Editor::unfold);
 244    cx.add_action(Editor::fold_selected_ranges);
 245}
 246
 247trait SelectionExt {
 248    fn display_range(&self, map: &DisplayMapSnapshot) -> Range<DisplayPoint>;
 249    fn spanned_rows(
 250        &self,
 251        include_end_if_at_line_start: bool,
 252        map: &DisplayMapSnapshot,
 253    ) -> SpannedRows;
 254}
 255
 256struct SpannedRows {
 257    buffer_rows: Range<u32>,
 258    display_rows: Range<u32>,
 259}
 260
 261#[derive(Clone, Debug)]
 262pub enum SelectPhase {
 263    Begin {
 264        position: DisplayPoint,
 265        add: bool,
 266    },
 267    Update {
 268        position: DisplayPoint,
 269        scroll_position: Vector2F,
 270    },
 271    End,
 272}
 273
 274#[derive(Copy, Clone, PartialEq, Eq)]
 275pub enum EditorMode {
 276    SingleLine,
 277    AutoHeight { max_lines: usize },
 278    Full,
 279}
 280
 281#[derive(Clone)]
 282pub struct EditorSettings {
 283    pub tab_size: usize,
 284    pub style: EditorStyle,
 285}
 286
 287pub struct Editor {
 288    handle: WeakViewHandle<Self>,
 289    buffer: ModelHandle<Buffer>,
 290    display_map: ModelHandle<DisplayMap>,
 291    selection_set_id: SelectionSetId,
 292    pending_selection: Option<Selection>,
 293    next_selection_id: usize,
 294    add_selections_state: Option<AddSelectionsState>,
 295    select_larger_syntax_node_stack: Vec<Arc<[Selection]>>,
 296    scroll_position: Vector2F,
 297    scroll_top_anchor: Anchor,
 298    autoscroll_requested: bool,
 299    build_settings: Rc<RefCell<dyn Fn(&AppContext) -> EditorSettings>>,
 300    focused: bool,
 301    show_local_cursors: bool,
 302    blink_epoch: usize,
 303    blinking_paused: bool,
 304    mode: EditorMode,
 305    placeholder_text: Option<Arc<str>>,
 306}
 307
 308pub struct Snapshot {
 309    pub mode: EditorMode,
 310    pub display_snapshot: DisplayMapSnapshot,
 311    pub placeholder_text: Option<Arc<str>>,
 312    is_focused: bool,
 313    scroll_position: Vector2F,
 314    scroll_top_anchor: Anchor,
 315}
 316
 317struct AddSelectionsState {
 318    above: bool,
 319    stack: Vec<usize>,
 320}
 321
 322#[derive(Serialize, Deserialize)]
 323struct ClipboardSelection {
 324    len: usize,
 325    is_entire_line: bool,
 326}
 327
 328impl Editor {
 329    pub fn single_line(
 330        build_settings: impl 'static + Fn(&AppContext) -> EditorSettings,
 331        cx: &mut ViewContext<Self>,
 332    ) -> Self {
 333        let buffer = cx.add_model(|cx| Buffer::new(0, String::new(), cx));
 334        let mut view = Self::for_buffer(buffer, build_settings, cx);
 335        view.mode = EditorMode::SingleLine;
 336        view
 337    }
 338
 339    pub fn auto_height(
 340        max_lines: usize,
 341        build_settings: impl 'static + Fn(&AppContext) -> EditorSettings,
 342        cx: &mut ViewContext<Self>,
 343    ) -> Self {
 344        let buffer = cx.add_model(|cx| Buffer::new(0, String::new(), cx));
 345        let mut view = Self::for_buffer(buffer, build_settings, cx);
 346        view.mode = EditorMode::AutoHeight { max_lines };
 347        view
 348    }
 349
 350    pub fn for_buffer(
 351        buffer: ModelHandle<Buffer>,
 352        build_settings: impl 'static + Fn(&AppContext) -> EditorSettings,
 353        cx: &mut ViewContext<Self>,
 354    ) -> Self {
 355        Self::new(buffer, Rc::new(RefCell::new(build_settings)), cx)
 356    }
 357
 358    pub fn clone(&self, cx: &mut ViewContext<Self>) -> Self {
 359        let mut clone = Self::new(self.buffer.clone(), self.build_settings.clone(), cx);
 360        clone.scroll_position = self.scroll_position;
 361        clone.scroll_top_anchor = self.scroll_top_anchor.clone();
 362        clone
 363    }
 364
 365    pub fn new(
 366        buffer: ModelHandle<Buffer>,
 367        build_settings: Rc<RefCell<dyn Fn(&AppContext) -> EditorSettings>>,
 368        cx: &mut ViewContext<Self>,
 369    ) -> Self {
 370        let settings = build_settings.borrow_mut()(cx);
 371        let display_map = cx.add_model(|cx| {
 372            DisplayMap::new(
 373                buffer.clone(),
 374                settings.tab_size,
 375                settings.style.text.font_id,
 376                settings.style.text.font_size,
 377                None,
 378                cx,
 379            )
 380        });
 381        cx.observe(&buffer, Self::on_buffer_changed).detach();
 382        cx.subscribe(&buffer, Self::on_buffer_event).detach();
 383        cx.observe(&display_map, Self::on_display_map_changed)
 384            .detach();
 385
 386        let mut next_selection_id = 0;
 387        let selection_set_id = buffer.update(cx, |buffer, cx| {
 388            buffer.add_selection_set(
 389                vec![Selection {
 390                    id: post_inc(&mut next_selection_id),
 391                    start: buffer.anchor_before(0),
 392                    end: buffer.anchor_before(0),
 393                    reversed: false,
 394                    goal: SelectionGoal::None,
 395                }],
 396                cx,
 397            )
 398        });
 399        Self {
 400            handle: cx.handle().downgrade(),
 401            buffer,
 402            display_map,
 403            selection_set_id,
 404            pending_selection: None,
 405            next_selection_id,
 406            add_selections_state: None,
 407            select_larger_syntax_node_stack: Vec::new(),
 408            build_settings,
 409            scroll_position: Vector2F::zero(),
 410            scroll_top_anchor: Anchor::min(),
 411            autoscroll_requested: false,
 412            focused: false,
 413            show_local_cursors: false,
 414            blink_epoch: 0,
 415            blinking_paused: false,
 416            mode: EditorMode::Full,
 417            placeholder_text: None,
 418        }
 419    }
 420
 421    pub fn replica_id(&self, cx: &AppContext) -> ReplicaId {
 422        self.buffer.read(cx).replica_id()
 423    }
 424
 425    pub fn buffer(&self) -> &ModelHandle<Buffer> {
 426        &self.buffer
 427    }
 428
 429    pub fn snapshot(&mut self, cx: &mut MutableAppContext) -> Snapshot {
 430        Snapshot {
 431            mode: self.mode,
 432            display_snapshot: self.display_map.update(cx, |map, cx| map.snapshot(cx)),
 433            scroll_position: self.scroll_position,
 434            scroll_top_anchor: self.scroll_top_anchor.clone(),
 435            placeholder_text: self.placeholder_text.clone(),
 436            is_focused: self
 437                .handle
 438                .upgrade(cx)
 439                .map_or(false, |handle| handle.is_focused(cx)),
 440        }
 441    }
 442
 443    pub fn language<'a>(&self, cx: &'a AppContext) -> Option<&'a Arc<Language>> {
 444        self.buffer.read(cx).language()
 445    }
 446
 447    pub fn set_placeholder_text(
 448        &mut self,
 449        placeholder_text: impl Into<Arc<str>>,
 450        cx: &mut ViewContext<Self>,
 451    ) {
 452        self.placeholder_text = Some(placeholder_text.into());
 453        cx.notify();
 454    }
 455
 456    fn set_scroll_position(&mut self, mut scroll_position: Vector2F, cx: &mut ViewContext<Self>) {
 457        let map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
 458        let scroll_top_buffer_offset =
 459            DisplayPoint::new(scroll_position.y() as u32, 0).to_buffer_offset(&map, Bias::Right);
 460        self.scroll_top_anchor = self
 461            .buffer
 462            .read(cx)
 463            .anchor_at(scroll_top_buffer_offset, Bias::Right);
 464        scroll_position.set_y(scroll_position.y().fract());
 465        self.scroll_position = scroll_position;
 466        cx.notify();
 467    }
 468
 469    pub fn clamp_scroll_left(&mut self, max: f32) -> bool {
 470        if max < self.scroll_position.x() {
 471            self.scroll_position.set_x(max);
 472            true
 473        } else {
 474            false
 475        }
 476    }
 477
 478    pub fn autoscroll_vertically(
 479        &mut self,
 480        viewport_height: f32,
 481        line_height: f32,
 482        cx: &mut ViewContext<Self>,
 483    ) -> bool {
 484        let visible_lines = viewport_height / line_height;
 485        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
 486        let mut scroll_position =
 487            compute_scroll_position(&display_map, self.scroll_position, &self.scroll_top_anchor);
 488        let max_scroll_top = if matches!(self.mode, EditorMode::AutoHeight { .. }) {
 489            (display_map.max_point().row() as f32 - visible_lines + 1.).max(0.)
 490        } else {
 491            display_map.max_point().row().saturating_sub(1) as f32
 492        };
 493        if scroll_position.y() > max_scroll_top {
 494            scroll_position.set_y(max_scroll_top);
 495            self.set_scroll_position(scroll_position, cx);
 496        }
 497
 498        if self.autoscroll_requested {
 499            self.autoscroll_requested = false;
 500        } else {
 501            return false;
 502        }
 503
 504        let selections = self.selections(cx);
 505        let first_cursor_top = selections
 506            .first()
 507            .unwrap()
 508            .head()
 509            .to_display_point(&display_map, Bias::Left)
 510            .row() as f32;
 511        let last_cursor_bottom = selections
 512            .last()
 513            .unwrap()
 514            .head()
 515            .to_display_point(&display_map, Bias::Right)
 516            .row() as f32
 517            + 1.0;
 518
 519        let margin = if matches!(self.mode, EditorMode::AutoHeight { .. }) {
 520            0.
 521        } else {
 522            ((visible_lines - (last_cursor_bottom - first_cursor_top)) / 2.0)
 523                .floor()
 524                .min(3.0)
 525        };
 526        if margin < 0.0 {
 527            return false;
 528        }
 529
 530        let target_top = (first_cursor_top - margin).max(0.0);
 531        let target_bottom = last_cursor_bottom + margin;
 532        let start_row = scroll_position.y();
 533        let end_row = start_row + visible_lines;
 534
 535        if target_top < start_row {
 536            scroll_position.set_y(target_top);
 537            self.set_scroll_position(scroll_position, cx);
 538        } else if target_bottom >= end_row {
 539            scroll_position.set_y(target_bottom - visible_lines);
 540            self.set_scroll_position(scroll_position, cx);
 541        }
 542
 543        true
 544    }
 545
 546    pub fn autoscroll_horizontally(
 547        &mut self,
 548        start_row: u32,
 549        viewport_width: f32,
 550        scroll_width: f32,
 551        max_glyph_width: f32,
 552        layouts: &[text_layout::Line],
 553        cx: &mut ViewContext<Self>,
 554    ) -> bool {
 555        let selections = self.selections(cx);
 556        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
 557        let mut target_left = std::f32::INFINITY;
 558        let mut target_right = 0.0_f32;
 559        for selection in selections.iter() {
 560            let head = selection.head().to_display_point(&display_map, Bias::Left);
 561            let start_column = head.column().saturating_sub(3);
 562            let end_column = cmp::min(display_map.line_len(head.row()), head.column() + 3);
 563            target_left = target_left
 564                .min(layouts[(head.row() - start_row) as usize].x_for_index(start_column as usize));
 565            target_right = target_right.max(
 566                layouts[(head.row() - start_row) as usize].x_for_index(end_column as usize)
 567                    + max_glyph_width,
 568            );
 569        }
 570        target_right = target_right.min(scroll_width);
 571
 572        if target_right - target_left > viewport_width {
 573            return false;
 574        }
 575
 576        let scroll_left = self.scroll_position.x() * max_glyph_width;
 577        let scroll_right = scroll_left + viewport_width;
 578
 579        if target_left < scroll_left {
 580            self.scroll_position.set_x(target_left / max_glyph_width);
 581            true
 582        } else if target_right > scroll_right {
 583            self.scroll_position
 584                .set_x((target_right - viewport_width) / max_glyph_width);
 585            true
 586        } else {
 587            false
 588        }
 589    }
 590
 591    fn select(&mut self, Select(phase): &Select, cx: &mut ViewContext<Self>) {
 592        match phase {
 593            SelectPhase::Begin { position, add } => self.begin_selection(*position, *add, cx),
 594            SelectPhase::Update {
 595                position,
 596                scroll_position,
 597            } => self.update_selection(*position, *scroll_position, cx),
 598            SelectPhase::End => self.end_selection(cx),
 599        }
 600    }
 601
 602    fn begin_selection(&mut self, position: DisplayPoint, add: bool, cx: &mut ViewContext<Self>) {
 603        if !self.focused {
 604            cx.focus_self();
 605            cx.emit(Event::Activate);
 606        }
 607
 608        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
 609        let cursor = display_map.anchor_before(position, Bias::Left);
 610        let selection = Selection {
 611            id: post_inc(&mut self.next_selection_id),
 612            start: cursor.clone(),
 613            end: cursor,
 614            reversed: false,
 615            goal: SelectionGoal::None,
 616        };
 617
 618        if !add {
 619            self.update_selections(Vec::new(), false, cx);
 620        }
 621        self.pending_selection = Some(selection);
 622
 623        cx.notify();
 624    }
 625
 626    fn update_selection(
 627        &mut self,
 628        position: DisplayPoint,
 629        scroll_position: Vector2F,
 630        cx: &mut ViewContext<Self>,
 631    ) {
 632        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
 633        let buffer = self.buffer.read(cx);
 634        let cursor = display_map.anchor_before(position, Bias::Left);
 635        if let Some(selection) = self.pending_selection.as_mut() {
 636            selection.set_head(buffer, cursor);
 637        } else {
 638            log::error!("update_selection dispatched with no pending selection");
 639            return;
 640        }
 641
 642        self.set_scroll_position(scroll_position, cx);
 643        cx.notify();
 644    }
 645
 646    fn end_selection(&mut self, cx: &mut ViewContext<Self>) {
 647        if let Some(selection) = self.pending_selection.take() {
 648            let mut selections = self.selections(cx).to_vec();
 649            let ix = self.selection_insertion_index(&selections, &selection.start, cx.as_ref());
 650            selections.insert(ix, selection);
 651            self.update_selections(selections, false, cx);
 652        }
 653    }
 654
 655    pub fn is_selecting(&self) -> bool {
 656        self.pending_selection.is_some()
 657    }
 658
 659    pub fn cancel(&mut self, _: &Cancel, cx: &mut ViewContext<Self>) {
 660        if let Some(pending_selection) = self.pending_selection.take() {
 661            let selections = self.selections(cx);
 662            if selections.is_empty() {
 663                self.update_selections(vec![pending_selection], true, cx);
 664            }
 665        } else {
 666            let selections = self.selections(cx);
 667            let mut oldest_selection = selections.iter().min_by_key(|s| s.id).unwrap().clone();
 668            if selections.len() == 1 {
 669                oldest_selection.start = oldest_selection.head().clone();
 670                oldest_selection.end = oldest_selection.head().clone();
 671            }
 672            self.update_selections(vec![oldest_selection], true, cx);
 673        }
 674    }
 675
 676    fn select_ranges<I, T>(&mut self, ranges: I, autoscroll: bool, cx: &mut ViewContext<Self>)
 677    where
 678        I: IntoIterator<Item = Range<T>>,
 679        T: ToOffset,
 680    {
 681        let buffer = self.buffer.read(cx);
 682        let mut selections = Vec::new();
 683        for range in ranges {
 684            let mut start = range.start.to_offset(buffer);
 685            let mut end = range.end.to_offset(buffer);
 686            let reversed = if start > end {
 687                mem::swap(&mut start, &mut end);
 688                true
 689            } else {
 690                false
 691            };
 692            selections.push(Selection {
 693                id: post_inc(&mut self.next_selection_id),
 694                start: buffer.anchor_before(start),
 695                end: buffer.anchor_before(end),
 696                reversed,
 697                goal: SelectionGoal::None,
 698            });
 699        }
 700        self.update_selections(selections, autoscroll, cx);
 701    }
 702
 703    #[cfg(test)]
 704    fn select_display_ranges<'a, T>(
 705        &mut self,
 706        ranges: T,
 707        cx: &mut ViewContext<Self>,
 708    ) -> anyhow::Result<()>
 709    where
 710        T: IntoIterator<Item = &'a Range<DisplayPoint>>,
 711    {
 712        let mut selections = Vec::new();
 713        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
 714        for range in ranges {
 715            let mut start = range.start;
 716            let mut end = range.end;
 717            let reversed = if start > end {
 718                mem::swap(&mut start, &mut end);
 719                true
 720            } else {
 721                false
 722            };
 723
 724            selections.push(Selection {
 725                id: post_inc(&mut self.next_selection_id),
 726                start: display_map.anchor_before(start, Bias::Left),
 727                end: display_map.anchor_before(end, Bias::Left),
 728                reversed,
 729                goal: SelectionGoal::None,
 730            });
 731        }
 732        self.update_selections(selections, false, cx);
 733        Ok(())
 734    }
 735
 736    pub fn insert(&mut self, action: &Insert, cx: &mut ViewContext<Self>) {
 737        let mut old_selections = SmallVec::<[_; 32]>::new();
 738        {
 739            let selections = self.selections(cx);
 740            let buffer = self.buffer.read(cx);
 741            for selection in selections.iter() {
 742                let start = selection.start.to_offset(buffer);
 743                let end = selection.end.to_offset(buffer);
 744                old_selections.push((selection.id, start..end));
 745            }
 746        }
 747
 748        self.start_transaction(cx);
 749        let mut new_selections = Vec::new();
 750        self.buffer.update(cx, |buffer, cx| {
 751            let edit_ranges = old_selections.iter().map(|(_, range)| range.clone());
 752            buffer.edit(edit_ranges, action.0.as_str(), cx);
 753            let text_len = action.0.len() as isize;
 754            let mut delta = 0_isize;
 755            new_selections = old_selections
 756                .into_iter()
 757                .map(|(id, range)| {
 758                    let start = range.start as isize;
 759                    let end = range.end as isize;
 760                    let anchor = buffer.anchor_before((start + delta + text_len) as usize);
 761                    let deleted_count = end - start;
 762                    delta += text_len - deleted_count;
 763                    Selection {
 764                        id,
 765                        start: anchor.clone(),
 766                        end: anchor,
 767                        reversed: false,
 768                        goal: SelectionGoal::None,
 769                    }
 770                })
 771                .collect();
 772        });
 773
 774        self.update_selections(new_selections, true, cx);
 775        self.end_transaction(cx);
 776    }
 777
 778    pub fn clear(&mut self, cx: &mut ViewContext<Self>) {
 779        self.start_transaction(cx);
 780        self.select_all(&SelectAll, cx);
 781        self.insert(&Insert(String::new()), cx);
 782        self.end_transaction(cx);
 783    }
 784
 785    pub fn backspace(&mut self, _: &Backspace, cx: &mut ViewContext<Self>) {
 786        self.start_transaction(cx);
 787        let mut selections = self.selections(cx).to_vec();
 788        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
 789        {
 790            let buffer = self.buffer.read(cx);
 791            for selection in &mut selections {
 792                let range = selection.point_range(buffer);
 793                if range.start == range.end {
 794                    let head = selection.head().to_display_point(&display_map, Bias::Left);
 795                    let cursor = display_map
 796                        .anchor_before(movement::left(&display_map, head).unwrap(), Bias::Left);
 797                    selection.set_head(&buffer, cursor);
 798                    selection.goal = SelectionGoal::None;
 799                }
 800            }
 801        }
 802
 803        self.update_selections(selections, true, cx);
 804        self.insert(&Insert(String::new()), cx);
 805        self.end_transaction(cx);
 806    }
 807
 808    pub fn delete(&mut self, _: &Delete, cx: &mut ViewContext<Self>) {
 809        self.start_transaction(cx);
 810        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
 811        let mut selections = self.selections(cx).to_vec();
 812        {
 813            let buffer = self.buffer.read(cx);
 814            for selection in &mut selections {
 815                let range = selection.point_range(buffer);
 816                if range.start == range.end {
 817                    let head = selection.head().to_display_point(&display_map, Bias::Left);
 818                    let cursor = display_map
 819                        .anchor_before(movement::right(&display_map, head).unwrap(), Bias::Right);
 820                    selection.set_head(&buffer, cursor);
 821                    selection.goal = SelectionGoal::None;
 822                }
 823            }
 824        }
 825
 826        self.update_selections(selections, true, cx);
 827        self.insert(&Insert(String::new()), cx);
 828        self.end_transaction(cx);
 829    }
 830
 831    pub fn delete_line(&mut self, _: &DeleteLine, cx: &mut ViewContext<Self>) {
 832        self.start_transaction(cx);
 833
 834        let selections = self.selections(cx);
 835        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
 836        let buffer = self.buffer.read(cx);
 837
 838        let mut new_cursors = Vec::new();
 839        let mut edit_ranges = Vec::new();
 840
 841        let mut selections = selections.iter().peekable();
 842        while let Some(selection) = selections.next() {
 843            let mut rows = selection.spanned_rows(false, &display_map).buffer_rows;
 844            let goal_display_column = selection
 845                .head()
 846                .to_display_point(&display_map, Bias::Left)
 847                .column();
 848
 849            // Accumulate contiguous regions of rows that we want to delete.
 850            while let Some(next_selection) = selections.peek() {
 851                let next_rows = next_selection.spanned_rows(false, &display_map).buffer_rows;
 852                if next_rows.start <= rows.end {
 853                    rows.end = next_rows.end;
 854                    selections.next().unwrap();
 855                } else {
 856                    break;
 857                }
 858            }
 859
 860            let mut edit_start = Point::new(rows.start, 0).to_offset(buffer);
 861            let edit_end;
 862            let cursor_buffer_row;
 863            if buffer.max_point().row >= rows.end {
 864                // If there's a line after the range, delete the \n from the end of the row range
 865                // and position the cursor on the next line.
 866                edit_end = Point::new(rows.end, 0).to_offset(buffer);
 867                cursor_buffer_row = rows.end;
 868            } else {
 869                // If there isn't a line after the range, delete the \n from the line before the
 870                // start of the row range and position the cursor there.
 871                edit_start = edit_start.saturating_sub(1);
 872                edit_end = buffer.len();
 873                cursor_buffer_row = rows.start.saturating_sub(1);
 874            }
 875
 876            let mut cursor =
 877                Point::new(cursor_buffer_row, 0).to_display_point(&display_map, Bias::Left);
 878            *cursor.column_mut() =
 879                cmp::min(goal_display_column, display_map.line_len(cursor.row()));
 880
 881            new_cursors.push((
 882                selection.id,
 883                cursor.to_buffer_point(&display_map, Bias::Left),
 884            ));
 885            edit_ranges.push(edit_start..edit_end);
 886        }
 887
 888        new_cursors.sort_unstable_by_key(|(_, range)| range.clone());
 889        let new_selections = new_cursors
 890            .into_iter()
 891            .map(|(id, cursor)| {
 892                let anchor = buffer.anchor_before(cursor);
 893                Selection {
 894                    id,
 895                    start: anchor.clone(),
 896                    end: anchor,
 897                    reversed: false,
 898                    goal: SelectionGoal::None,
 899                }
 900            })
 901            .collect();
 902        self.buffer
 903            .update(cx, |buffer, cx| buffer.edit(edit_ranges, "", cx));
 904        self.update_selections(new_selections, true, cx);
 905        self.end_transaction(cx);
 906    }
 907
 908    pub fn duplicate_line(&mut self, _: &DuplicateLine, cx: &mut ViewContext<Self>) {
 909        self.start_transaction(cx);
 910
 911        let mut selections = self.selections(cx).to_vec();
 912        {
 913            // Temporarily bias selections right to allow newly duplicate lines to push them down
 914            // when the selections are at the beginning of a line.
 915            let buffer = self.buffer.read(cx);
 916            for selection in &mut selections {
 917                selection.start = selection.start.bias_right(buffer);
 918                selection.end = selection.end.bias_right(buffer);
 919            }
 920        }
 921        self.update_selections(selections.clone(), false, cx);
 922
 923        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
 924        let buffer = self.buffer.read(cx);
 925
 926        let mut edits = Vec::new();
 927        let mut selections_iter = selections.iter_mut().peekable();
 928        while let Some(selection) = selections_iter.next() {
 929            // Avoid duplicating the same lines twice.
 930            let mut rows = selection.spanned_rows(false, &display_map).buffer_rows;
 931            while let Some(next_selection) = selections_iter.peek() {
 932                let next_rows = next_selection.spanned_rows(false, &display_map).buffer_rows;
 933                if next_rows.start <= rows.end - 1 {
 934                    rows.end = next_rows.end;
 935                    selections_iter.next().unwrap();
 936                } else {
 937                    break;
 938                }
 939            }
 940
 941            // Copy the text from the selected row region and splice it at the start of the region.
 942            let start = Point::new(rows.start, 0);
 943            let end = Point::new(rows.end - 1, buffer.line_len(rows.end - 1));
 944            let text = buffer
 945                .text_for_range(start..end)
 946                .chain(Some("\n"))
 947                .collect::<String>();
 948            edits.push((start, text));
 949        }
 950
 951        self.buffer.update(cx, |buffer, cx| {
 952            for (offset, text) in edits.into_iter().rev() {
 953                buffer.edit(Some(offset..offset), text, cx);
 954            }
 955        });
 956
 957        // Restore bias on selections.
 958        let buffer = self.buffer.read(cx);
 959        for selection in &mut selections {
 960            selection.start = selection.start.bias_left(buffer);
 961            selection.end = selection.end.bias_left(buffer);
 962        }
 963        self.update_selections(selections, true, cx);
 964
 965        self.end_transaction(cx);
 966    }
 967
 968    pub fn move_line_up(&mut self, _: &MoveLineUp, cx: &mut ViewContext<Self>) {
 969        self.start_transaction(cx);
 970
 971        let selections = self.selections(cx);
 972        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
 973        let buffer = self.buffer.read(cx);
 974
 975        let mut edits = Vec::new();
 976        let mut new_selection_ranges = Vec::new();
 977        let mut old_folds = Vec::new();
 978        let mut new_folds = Vec::new();
 979
 980        let mut selections = selections.iter().peekable();
 981        let mut contiguous_selections = Vec::new();
 982        while let Some(selection) = selections.next() {
 983            // Accumulate contiguous regions of rows that we want to move.
 984            contiguous_selections.push(selection.point_range(buffer));
 985            let SpannedRows {
 986                mut buffer_rows,
 987                mut display_rows,
 988            } = selection.spanned_rows(false, &display_map);
 989
 990            while let Some(next_selection) = selections.peek() {
 991                let SpannedRows {
 992                    buffer_rows: next_buffer_rows,
 993                    display_rows: next_display_rows,
 994                } = next_selection.spanned_rows(false, &display_map);
 995                if next_buffer_rows.start <= buffer_rows.end {
 996                    buffer_rows.end = next_buffer_rows.end;
 997                    display_rows.end = next_display_rows.end;
 998                    contiguous_selections.push(next_selection.point_range(buffer));
 999                    selections.next().unwrap();
1000                } else {
1001                    break;
1002                }
1003            }
1004
1005            // Cut the text from the selected rows and paste it at the start of the previous line.
1006            if display_rows.start != 0 {
1007                let start = Point::new(buffer_rows.start, 0).to_offset(buffer);
1008                let end = Point::new(buffer_rows.end - 1, buffer.line_len(buffer_rows.end - 1))
1009                    .to_offset(buffer);
1010
1011                let prev_row_display_start = DisplayPoint::new(display_rows.start - 1, 0);
1012                let prev_row_buffer_start = display_map.prev_row_boundary(prev_row_display_start).1;
1013                let prev_row_buffer_start_offset = prev_row_buffer_start.to_offset(buffer);
1014
1015                let mut text = String::new();
1016                text.extend(buffer.text_for_range(start..end));
1017                text.push('\n');
1018                edits.push((
1019                    prev_row_buffer_start_offset..prev_row_buffer_start_offset,
1020                    text,
1021                ));
1022                edits.push((start - 1..end, String::new()));
1023
1024                let row_delta = buffer_rows.start - prev_row_buffer_start.row;
1025
1026                // Move selections up.
1027                for range in &mut contiguous_selections {
1028                    range.start.row -= row_delta;
1029                    range.end.row -= row_delta;
1030                }
1031
1032                // Move folds up.
1033                old_folds.push(start..end);
1034                for fold in display_map.folds_in_range(start..end) {
1035                    let mut start = fold.start.to_point(buffer);
1036                    let mut end = fold.end.to_point(buffer);
1037                    start.row -= row_delta;
1038                    end.row -= row_delta;
1039                    new_folds.push(start..end);
1040                }
1041            }
1042
1043            new_selection_ranges.extend(contiguous_selections.drain(..));
1044        }
1045
1046        self.unfold_ranges(old_folds, cx);
1047        self.buffer.update(cx, |buffer, cx| {
1048            for (range, text) in edits.into_iter().rev() {
1049                buffer.edit(Some(range), text, cx);
1050            }
1051        });
1052        self.fold_ranges(new_folds, cx);
1053        self.select_ranges(new_selection_ranges, true, cx);
1054
1055        self.end_transaction(cx);
1056    }
1057
1058    pub fn move_line_down(&mut self, _: &MoveLineDown, cx: &mut ViewContext<Self>) {
1059        self.start_transaction(cx);
1060
1061        let selections = self.selections(cx);
1062        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
1063        let buffer = self.buffer.read(cx);
1064
1065        let mut edits = Vec::new();
1066        let mut new_selection_ranges = Vec::new();
1067        let mut old_folds = Vec::new();
1068        let mut new_folds = Vec::new();
1069
1070        let mut selections = selections.iter().peekable();
1071        let mut contiguous_selections = Vec::new();
1072        while let Some(selection) = selections.next() {
1073            // Accumulate contiguous regions of rows that we want to move.
1074            contiguous_selections.push(selection.point_range(buffer));
1075            let SpannedRows {
1076                mut buffer_rows,
1077                mut display_rows,
1078            } = selection.spanned_rows(false, &display_map);
1079            while let Some(next_selection) = selections.peek() {
1080                let SpannedRows {
1081                    buffer_rows: next_buffer_rows,
1082                    display_rows: next_display_rows,
1083                } = next_selection.spanned_rows(false, &display_map);
1084                if next_buffer_rows.start <= buffer_rows.end {
1085                    buffer_rows.end = next_buffer_rows.end;
1086                    display_rows.end = next_display_rows.end;
1087                    contiguous_selections.push(next_selection.point_range(buffer));
1088                    selections.next().unwrap();
1089                } else {
1090                    break;
1091                }
1092            }
1093
1094            // Cut the text from the selected rows and paste it at the end of the next line.
1095            if display_rows.end <= display_map.max_point().row() {
1096                let start = Point::new(buffer_rows.start, 0).to_offset(buffer);
1097                let end = Point::new(buffer_rows.end - 1, buffer.line_len(buffer_rows.end - 1))
1098                    .to_offset(buffer);
1099
1100                let next_row_display_end =
1101                    DisplayPoint::new(display_rows.end, display_map.line_len(display_rows.end));
1102                let next_row_buffer_end = display_map.next_row_boundary(next_row_display_end).1;
1103                let next_row_buffer_end_offset = next_row_buffer_end.to_offset(buffer);
1104
1105                let mut text = String::new();
1106                text.push('\n');
1107                text.extend(buffer.text_for_range(start..end));
1108                edits.push((start..end + 1, String::new()));
1109                edits.push((next_row_buffer_end_offset..next_row_buffer_end_offset, text));
1110
1111                let row_delta = next_row_buffer_end.row - buffer_rows.end + 1;
1112
1113                // Move selections down.
1114                for range in &mut contiguous_selections {
1115                    range.start.row += row_delta;
1116                    range.end.row += row_delta;
1117                }
1118
1119                // Move folds down.
1120                old_folds.push(start..end);
1121                for fold in display_map.folds_in_range(start..end) {
1122                    let mut start = fold.start.to_point(buffer);
1123                    let mut end = fold.end.to_point(buffer);
1124                    start.row += row_delta;
1125                    end.row += row_delta;
1126                    new_folds.push(start..end);
1127                }
1128            }
1129
1130            new_selection_ranges.extend(contiguous_selections.drain(..));
1131        }
1132
1133        self.unfold_ranges(old_folds, cx);
1134        self.buffer.update(cx, |buffer, cx| {
1135            for (range, text) in edits.into_iter().rev() {
1136                buffer.edit(Some(range), text, cx);
1137            }
1138        });
1139        self.fold_ranges(new_folds, cx);
1140        self.select_ranges(new_selection_ranges, true, cx);
1141
1142        self.end_transaction(cx);
1143    }
1144
1145    pub fn cut(&mut self, _: &Cut, cx: &mut ViewContext<Self>) {
1146        self.start_transaction(cx);
1147        let mut text = String::new();
1148        let mut selections = self.selections(cx).to_vec();
1149        let mut clipboard_selections = Vec::with_capacity(selections.len());
1150        {
1151            let buffer = self.buffer.read(cx);
1152            let max_point = buffer.max_point();
1153            for selection in &mut selections {
1154                let mut start = selection.start.to_point(buffer);
1155                let mut end = selection.end.to_point(buffer);
1156                let is_entire_line = start == end;
1157                if is_entire_line {
1158                    start = Point::new(start.row, 0);
1159                    end = cmp::min(max_point, Point::new(start.row + 1, 0));
1160                    selection.start = buffer.anchor_before(start);
1161                    selection.end = buffer.anchor_before(end);
1162                }
1163                let mut len = 0;
1164                for chunk in buffer.text_for_range(start..end) {
1165                    text.push_str(chunk);
1166                    len += chunk.len();
1167                }
1168                clipboard_selections.push(ClipboardSelection {
1169                    len,
1170                    is_entire_line,
1171                });
1172            }
1173        }
1174        self.update_selections(selections, true, cx);
1175        self.insert(&Insert(String::new()), cx);
1176        self.end_transaction(cx);
1177
1178        cx.as_mut()
1179            .write_to_clipboard(ClipboardItem::new(text).with_metadata(clipboard_selections));
1180    }
1181
1182    pub fn copy(&mut self, _: &Copy, cx: &mut ViewContext<Self>) {
1183        let selections = self.selections(cx);
1184        let buffer = self.buffer.read(cx);
1185        let max_point = buffer.max_point();
1186        let mut text = String::new();
1187        let mut clipboard_selections = Vec::with_capacity(selections.len());
1188        for selection in selections.iter() {
1189            let mut start = selection.start.to_point(buffer);
1190            let mut end = selection.end.to_point(buffer);
1191            let is_entire_line = start == end;
1192            if is_entire_line {
1193                start = Point::new(start.row, 0);
1194                end = cmp::min(max_point, Point::new(start.row + 1, 0));
1195            }
1196            let mut len = 0;
1197            for chunk in buffer.text_for_range(start..end) {
1198                text.push_str(chunk);
1199                len += chunk.len();
1200            }
1201            clipboard_selections.push(ClipboardSelection {
1202                len,
1203                is_entire_line,
1204            });
1205        }
1206
1207        cx.as_mut()
1208            .write_to_clipboard(ClipboardItem::new(text).with_metadata(clipboard_selections));
1209    }
1210
1211    pub fn paste(&mut self, _: &Paste, cx: &mut ViewContext<Self>) {
1212        if let Some(item) = cx.as_mut().read_from_clipboard() {
1213            let clipboard_text = item.text();
1214            if let Some(mut clipboard_selections) = item.metadata::<Vec<ClipboardSelection>>() {
1215                let selections = self.selections(cx);
1216                let all_selections_were_entire_line =
1217                    clipboard_selections.iter().all(|s| s.is_entire_line);
1218                if clipboard_selections.len() != selections.len() {
1219                    clipboard_selections.clear();
1220                }
1221
1222                self.start_transaction(cx);
1223                let mut start_offset = 0;
1224                let mut new_selections = Vec::with_capacity(selections.len());
1225                for (i, selection) in selections.iter().enumerate() {
1226                    let to_insert;
1227                    let entire_line;
1228                    if let Some(clipboard_selection) = clipboard_selections.get(i) {
1229                        let end_offset = start_offset + clipboard_selection.len;
1230                        to_insert = &clipboard_text[start_offset..end_offset];
1231                        entire_line = clipboard_selection.is_entire_line;
1232                        start_offset = end_offset
1233                    } else {
1234                        to_insert = clipboard_text.as_str();
1235                        entire_line = all_selections_were_entire_line;
1236                    }
1237
1238                    self.buffer.update(cx, |buffer, cx| {
1239                        let selection_start = selection.start.to_point(&*buffer);
1240                        let selection_end = selection.end.to_point(&*buffer);
1241
1242                        // If the corresponding selection was empty when this slice of the
1243                        // clipboard text was written, then the entire line containing the
1244                        // selection was copied. If this selection is also currently empty,
1245                        // then paste the line before the current line of the buffer.
1246                        let new_selection_start = selection.end.bias_right(buffer);
1247                        if selection_start == selection_end && entire_line {
1248                            let line_start = Point::new(selection_start.row, 0);
1249                            buffer.edit(Some(line_start..line_start), to_insert, cx);
1250                        } else {
1251                            buffer.edit(Some(&selection.start..&selection.end), to_insert, cx);
1252                        };
1253
1254                        let new_selection_start = new_selection_start.bias_left(buffer);
1255                        new_selections.push(Selection {
1256                            id: selection.id,
1257                            start: new_selection_start.clone(),
1258                            end: new_selection_start,
1259                            reversed: false,
1260                            goal: SelectionGoal::None,
1261                        });
1262                    });
1263                }
1264                self.update_selections(new_selections, true, cx);
1265                self.end_transaction(cx);
1266            } else {
1267                self.insert(&Insert(clipboard_text.into()), cx);
1268            }
1269        }
1270    }
1271
1272    pub fn undo(&mut self, _: &Undo, cx: &mut ViewContext<Self>) {
1273        self.buffer.update(cx, |buffer, cx| buffer.undo(cx));
1274    }
1275
1276    pub fn redo(&mut self, _: &Redo, cx: &mut ViewContext<Self>) {
1277        self.buffer.update(cx, |buffer, cx| buffer.redo(cx));
1278    }
1279
1280    pub fn move_left(&mut self, _: &MoveLeft, cx: &mut ViewContext<Self>) {
1281        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
1282        let mut selections = self.selections(cx).to_vec();
1283        {
1284            for selection in &mut selections {
1285                let start = selection.start.to_display_point(&display_map, Bias::Left);
1286                let end = selection.end.to_display_point(&display_map, Bias::Left);
1287
1288                if start != end {
1289                    selection.end = selection.start.clone();
1290                } else {
1291                    let cursor = display_map
1292                        .anchor_before(movement::left(&display_map, start).unwrap(), Bias::Left);
1293                    selection.start = cursor.clone();
1294                    selection.end = cursor;
1295                }
1296                selection.reversed = false;
1297                selection.goal = SelectionGoal::None;
1298            }
1299        }
1300        self.update_selections(selections, true, cx);
1301    }
1302
1303    pub fn select_left(&mut self, _: &SelectLeft, cx: &mut ViewContext<Self>) {
1304        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
1305        let mut selections = self.selections(cx).to_vec();
1306        {
1307            let buffer = self.buffer.read(cx);
1308            for selection in &mut selections {
1309                let head = selection.head().to_display_point(&display_map, Bias::Left);
1310                let cursor = display_map
1311                    .anchor_before(movement::left(&display_map, head).unwrap(), Bias::Left);
1312                selection.set_head(&buffer, cursor);
1313                selection.goal = SelectionGoal::None;
1314            }
1315        }
1316        self.update_selections(selections, true, cx);
1317    }
1318
1319    pub fn move_right(&mut self, _: &MoveRight, cx: &mut ViewContext<Self>) {
1320        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
1321        let mut selections = self.selections(cx).to_vec();
1322        {
1323            for selection in &mut selections {
1324                let start = selection.start.to_display_point(&display_map, Bias::Left);
1325                let end = selection.end.to_display_point(&display_map, Bias::Left);
1326
1327                if start != end {
1328                    selection.start = selection.end.clone();
1329                } else {
1330                    let cursor = display_map
1331                        .anchor_before(movement::right(&display_map, end).unwrap(), Bias::Right);
1332                    selection.start = cursor.clone();
1333                    selection.end = cursor;
1334                }
1335                selection.reversed = false;
1336                selection.goal = SelectionGoal::None;
1337            }
1338        }
1339        self.update_selections(selections, true, cx);
1340    }
1341
1342    pub fn select_right(&mut self, _: &SelectRight, cx: &mut ViewContext<Self>) {
1343        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
1344        let mut selections = self.selections(cx).to_vec();
1345        {
1346            let app = cx.as_ref();
1347            let buffer = self.buffer.read(app);
1348            for selection in &mut selections {
1349                let head = selection.head().to_display_point(&display_map, Bias::Left);
1350                let cursor = display_map
1351                    .anchor_before(movement::right(&display_map, head).unwrap(), Bias::Right);
1352                selection.set_head(&buffer, cursor);
1353                selection.goal = SelectionGoal::None;
1354            }
1355        }
1356        self.update_selections(selections, true, cx);
1357    }
1358
1359    pub fn move_up(&mut self, _: &MoveUp, cx: &mut ViewContext<Self>) {
1360        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
1361        if matches!(self.mode, EditorMode::SingleLine) {
1362            cx.propagate_action();
1363        } else {
1364            let mut selections = self.selections(cx).to_vec();
1365            {
1366                for selection in &mut selections {
1367                    let start = selection.start.to_display_point(&display_map, Bias::Left);
1368                    let end = selection.end.to_display_point(&display_map, Bias::Left);
1369                    if start != end {
1370                        selection.goal = SelectionGoal::None;
1371                    }
1372
1373                    let (start, goal) = movement::up(&display_map, start, selection.goal).unwrap();
1374                    let cursor = display_map.anchor_before(start, Bias::Left);
1375                    selection.start = cursor.clone();
1376                    selection.end = cursor;
1377                    selection.goal = goal;
1378                    selection.reversed = false;
1379                }
1380            }
1381            self.update_selections(selections, true, cx);
1382        }
1383    }
1384
1385    pub fn select_up(&mut self, _: &SelectUp, cx: &mut ViewContext<Self>) {
1386        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
1387        let mut selections = self.selections(cx).to_vec();
1388        {
1389            let app = cx.as_ref();
1390            let buffer = self.buffer.read(app);
1391            for selection in &mut selections {
1392                let head = selection.head().to_display_point(&display_map, Bias::Left);
1393                let (head, goal) = movement::up(&display_map, head, selection.goal).unwrap();
1394                selection.set_head(&buffer, display_map.anchor_before(head, Bias::Left));
1395                selection.goal = goal;
1396            }
1397        }
1398        self.update_selections(selections, true, cx);
1399    }
1400
1401    pub fn move_down(&mut self, _: &MoveDown, cx: &mut ViewContext<Self>) {
1402        if matches!(self.mode, EditorMode::SingleLine) {
1403            cx.propagate_action();
1404        } else {
1405            let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
1406            let mut selections = self.selections(cx).to_vec();
1407            {
1408                for selection in &mut selections {
1409                    let start = selection.start.to_display_point(&display_map, Bias::Left);
1410                    let end = selection.end.to_display_point(&display_map, Bias::Left);
1411                    if start != end {
1412                        selection.goal = SelectionGoal::None;
1413                    }
1414
1415                    let (start, goal) = movement::down(&display_map, end, selection.goal).unwrap();
1416                    let cursor = display_map.anchor_before(start, Bias::Right);
1417                    selection.start = cursor.clone();
1418                    selection.end = cursor;
1419                    selection.goal = goal;
1420                    selection.reversed = false;
1421                }
1422            }
1423            self.update_selections(selections, true, cx);
1424        }
1425    }
1426
1427    pub fn select_down(&mut self, _: &SelectDown, cx: &mut ViewContext<Self>) {
1428        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
1429        let mut selections = self.selections(cx).to_vec();
1430        {
1431            let app = cx.as_ref();
1432            let buffer = self.buffer.read(app);
1433            for selection in &mut selections {
1434                let head = selection.head().to_display_point(&display_map, Bias::Left);
1435                let (head, goal) = movement::down(&display_map, head, selection.goal).unwrap();
1436                selection.set_head(&buffer, display_map.anchor_before(head, Bias::Right));
1437                selection.goal = goal;
1438            }
1439        }
1440        self.update_selections(selections, true, cx);
1441    }
1442
1443    pub fn move_to_previous_word_boundary(
1444        &mut self,
1445        _: &MoveToPreviousWordBoundary,
1446        cx: &mut ViewContext<Self>,
1447    ) {
1448        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
1449        let mut selections = self.selections(cx).to_vec();
1450        {
1451            for selection in &mut selections {
1452                let head = selection.head().to_display_point(&display_map, Bias::Left);
1453                let new_head = movement::prev_word_boundary(&display_map, head).unwrap();
1454                let anchor = display_map.anchor_before(new_head, Bias::Left);
1455                selection.start = anchor.clone();
1456                selection.end = anchor;
1457                selection.reversed = false;
1458                selection.goal = SelectionGoal::None;
1459            }
1460        }
1461        self.update_selections(selections, true, cx);
1462    }
1463
1464    pub fn select_to_previous_word_boundary(
1465        &mut self,
1466        _: &SelectToPreviousWordBoundary,
1467        cx: &mut ViewContext<Self>,
1468    ) {
1469        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
1470        let mut selections = self.selections(cx).to_vec();
1471        {
1472            let buffer = self.buffer.read(cx);
1473            for selection in &mut selections {
1474                let head = selection.head().to_display_point(&display_map, Bias::Left);
1475                let new_head = movement::prev_word_boundary(&display_map, head).unwrap();
1476                let anchor = display_map.anchor_before(new_head, Bias::Left);
1477                selection.set_head(buffer, anchor);
1478                selection.goal = SelectionGoal::None;
1479            }
1480        }
1481        self.update_selections(selections, true, cx);
1482    }
1483
1484    pub fn delete_to_previous_word_boundary(
1485        &mut self,
1486        _: &DeleteToPreviousWordBoundary,
1487        cx: &mut ViewContext<Self>,
1488    ) {
1489        self.start_transaction(cx);
1490        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
1491        let mut selections = self.selections(cx).to_vec();
1492        {
1493            let buffer = self.buffer.read(cx);
1494            for selection in &mut selections {
1495                let range = selection.point_range(buffer);
1496                if range.start == range.end {
1497                    let head = selection.head().to_display_point(&display_map, Bias::Left);
1498                    let cursor = display_map.anchor_before(
1499                        movement::prev_word_boundary(&display_map, head).unwrap(),
1500                        Bias::Right,
1501                    );
1502                    selection.set_head(&buffer, cursor);
1503                    selection.goal = SelectionGoal::None;
1504                }
1505            }
1506        }
1507
1508        self.update_selections(selections, true, cx);
1509        self.insert(&Insert(String::new()), cx);
1510        self.end_transaction(cx);
1511    }
1512
1513    pub fn move_to_next_word_boundary(
1514        &mut self,
1515        _: &MoveToNextWordBoundary,
1516        cx: &mut ViewContext<Self>,
1517    ) {
1518        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
1519        let mut selections = self.selections(cx).to_vec();
1520        {
1521            for selection in &mut selections {
1522                let head = selection.head().to_display_point(&display_map, Bias::Left);
1523                let new_head = movement::next_word_boundary(&display_map, head).unwrap();
1524                let anchor = display_map.anchor_before(new_head, Bias::Left);
1525                selection.start = anchor.clone();
1526                selection.end = anchor;
1527                selection.reversed = false;
1528                selection.goal = SelectionGoal::None;
1529            }
1530        }
1531        self.update_selections(selections, true, cx);
1532    }
1533
1534    pub fn select_to_next_word_boundary(
1535        &mut self,
1536        _: &SelectToNextWordBoundary,
1537        cx: &mut ViewContext<Self>,
1538    ) {
1539        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
1540        let mut selections = self.selections(cx).to_vec();
1541        {
1542            let buffer = self.buffer.read(cx);
1543            for selection in &mut selections {
1544                let head = selection.head().to_display_point(&display_map, Bias::Left);
1545                let new_head = movement::next_word_boundary(&display_map, head).unwrap();
1546                let anchor = display_map.anchor_before(new_head, Bias::Left);
1547                selection.set_head(buffer, anchor);
1548                selection.goal = SelectionGoal::None;
1549            }
1550        }
1551        self.update_selections(selections, true, cx);
1552    }
1553
1554    pub fn delete_to_next_word_boundary(
1555        &mut self,
1556        _: &DeleteToNextWordBoundary,
1557        cx: &mut ViewContext<Self>,
1558    ) {
1559        self.start_transaction(cx);
1560        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
1561        let mut selections = self.selections(cx).to_vec();
1562        {
1563            let buffer = self.buffer.read(cx);
1564            for selection in &mut selections {
1565                let range = selection.point_range(buffer);
1566                if range.start == range.end {
1567                    let head = selection.head().to_display_point(&display_map, Bias::Left);
1568                    let cursor = display_map.anchor_before(
1569                        movement::next_word_boundary(&display_map, head).unwrap(),
1570                        Bias::Right,
1571                    );
1572                    selection.set_head(&buffer, cursor);
1573                    selection.goal = SelectionGoal::None;
1574                }
1575            }
1576        }
1577
1578        self.update_selections(selections, true, cx);
1579        self.insert(&Insert(String::new()), cx);
1580        self.end_transaction(cx);
1581    }
1582
1583    pub fn move_to_beginning_of_line(
1584        &mut self,
1585        _: &MoveToBeginningOfLine,
1586        cx: &mut ViewContext<Self>,
1587    ) {
1588        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
1589        let mut selections = self.selections(cx).to_vec();
1590        {
1591            for selection in &mut selections {
1592                let head = selection.head().to_display_point(&display_map, Bias::Left);
1593                let new_head = movement::line_beginning(&display_map, head, true).unwrap();
1594                let anchor = display_map.anchor_before(new_head, Bias::Left);
1595                selection.start = anchor.clone();
1596                selection.end = anchor;
1597                selection.reversed = false;
1598                selection.goal = SelectionGoal::None;
1599            }
1600        }
1601        self.update_selections(selections, true, cx);
1602    }
1603
1604    pub fn select_to_beginning_of_line(
1605        &mut self,
1606        SelectToBeginningOfLine(toggle_indent): &SelectToBeginningOfLine,
1607        cx: &mut ViewContext<Self>,
1608    ) {
1609        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
1610        let mut selections = self.selections(cx).to_vec();
1611        {
1612            let buffer = self.buffer.read(cx);
1613            for selection in &mut selections {
1614                let head = selection.head().to_display_point(&display_map, Bias::Left);
1615                let new_head =
1616                    movement::line_beginning(&display_map, head, *toggle_indent).unwrap();
1617                let anchor = display_map.anchor_before(new_head, Bias::Left);
1618                selection.set_head(buffer, anchor);
1619                selection.goal = SelectionGoal::None;
1620            }
1621        }
1622        self.update_selections(selections, true, cx);
1623    }
1624
1625    pub fn delete_to_beginning_of_line(
1626        &mut self,
1627        _: &DeleteToBeginningOfLine,
1628        cx: &mut ViewContext<Self>,
1629    ) {
1630        self.start_transaction(cx);
1631        self.select_to_beginning_of_line(&SelectToBeginningOfLine(false), cx);
1632        self.backspace(&Backspace, cx);
1633        self.end_transaction(cx);
1634    }
1635
1636    pub fn move_to_end_of_line(&mut self, _: &MoveToEndOfLine, cx: &mut ViewContext<Self>) {
1637        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
1638        let mut selections = self.selections(cx).to_vec();
1639        {
1640            for selection in &mut selections {
1641                let head = selection.head().to_display_point(&display_map, Bias::Left);
1642                let new_head = movement::line_end(&display_map, head).unwrap();
1643                let anchor = display_map.anchor_before(new_head, Bias::Left);
1644                selection.start = anchor.clone();
1645                selection.end = anchor;
1646                selection.reversed = false;
1647                selection.goal = SelectionGoal::None;
1648            }
1649        }
1650        self.update_selections(selections, true, cx);
1651    }
1652
1653    pub fn select_to_end_of_line(&mut self, _: &SelectToEndOfLine, cx: &mut ViewContext<Self>) {
1654        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
1655        let mut selections = self.selections(cx).to_vec();
1656        {
1657            let buffer = self.buffer.read(cx);
1658            for selection in &mut selections {
1659                let head = selection.head().to_display_point(&display_map, Bias::Left);
1660                let new_head = movement::line_end(&display_map, head).unwrap();
1661                let anchor = display_map.anchor_before(new_head, Bias::Left);
1662                selection.set_head(buffer, anchor);
1663                selection.goal = SelectionGoal::None;
1664            }
1665        }
1666        self.update_selections(selections, true, cx);
1667    }
1668
1669    pub fn delete_to_end_of_line(&mut self, _: &DeleteToEndOfLine, cx: &mut ViewContext<Self>) {
1670        self.start_transaction(cx);
1671        self.select_to_end_of_line(&SelectToEndOfLine, cx);
1672        self.delete(&Delete, cx);
1673        self.end_transaction(cx);
1674    }
1675
1676    pub fn cut_to_end_of_line(&mut self, _: &CutToEndOfLine, cx: &mut ViewContext<Self>) {
1677        self.start_transaction(cx);
1678        self.select_to_end_of_line(&SelectToEndOfLine, cx);
1679        self.cut(&Cut, cx);
1680        self.end_transaction(cx);
1681    }
1682
1683    pub fn move_to_beginning(&mut self, _: &MoveToBeginning, cx: &mut ViewContext<Self>) {
1684        let buffer = self.buffer.read(cx);
1685        let cursor = buffer.anchor_before(Point::new(0, 0));
1686        let selection = Selection {
1687            id: post_inc(&mut self.next_selection_id),
1688            start: cursor.clone(),
1689            end: cursor,
1690            reversed: false,
1691            goal: SelectionGoal::None,
1692        };
1693        self.update_selections(vec![selection], true, cx);
1694    }
1695
1696    pub fn select_to_beginning(&mut self, _: &SelectToBeginning, cx: &mut ViewContext<Self>) {
1697        let mut selection = self.selections(cx).last().unwrap().clone();
1698        selection.set_head(self.buffer.read(cx), Anchor::min());
1699        self.update_selections(vec![selection], true, cx);
1700    }
1701
1702    pub fn move_to_end(&mut self, _: &MoveToEnd, cx: &mut ViewContext<Self>) {
1703        let buffer = self.buffer.read(cx);
1704        let cursor = buffer.anchor_before(buffer.max_point());
1705        let selection = Selection {
1706            id: post_inc(&mut self.next_selection_id),
1707            start: cursor.clone(),
1708            end: cursor,
1709            reversed: false,
1710            goal: SelectionGoal::None,
1711        };
1712        self.update_selections(vec![selection], true, cx);
1713    }
1714
1715    pub fn select_to_end(&mut self, _: &SelectToEnd, cx: &mut ViewContext<Self>) {
1716        let mut selection = self.selections(cx).last().unwrap().clone();
1717        selection.set_head(self.buffer.read(cx), Anchor::max());
1718        self.update_selections(vec![selection], true, cx);
1719    }
1720
1721    pub fn select_all(&mut self, _: &SelectAll, cx: &mut ViewContext<Self>) {
1722        let selection = Selection {
1723            id: post_inc(&mut self.next_selection_id),
1724            start: Anchor::min(),
1725            end: Anchor::max(),
1726            reversed: false,
1727            goal: SelectionGoal::None,
1728        };
1729        self.update_selections(vec![selection], false, cx);
1730    }
1731
1732    pub fn select_line(&mut self, _: &SelectLine, cx: &mut ViewContext<Self>) {
1733        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
1734        let mut selections = self.selections(cx).to_vec();
1735        let buffer = self.buffer.read(cx);
1736        let max_point = buffer.max_point();
1737        for selection in &mut selections {
1738            let rows = selection.spanned_rows(true, &display_map).buffer_rows;
1739            selection.start = buffer.anchor_before(Point::new(rows.start, 0));
1740            selection.end = buffer.anchor_before(cmp::min(max_point, Point::new(rows.end, 0)));
1741            selection.reversed = false;
1742        }
1743        self.update_selections(selections, true, cx);
1744    }
1745
1746    pub fn split_selection_into_lines(
1747        &mut self,
1748        _: &SplitSelectionIntoLines,
1749        cx: &mut ViewContext<Self>,
1750    ) {
1751        let selections = self.selections(cx);
1752        let buffer = self.buffer.read(cx);
1753
1754        let mut to_unfold = Vec::new();
1755        let mut new_selections = Vec::new();
1756        for selection in selections.iter() {
1757            let range = selection.point_range(buffer).sorted();
1758            if range.start.row != range.end.row {
1759                new_selections.push(Selection {
1760                    id: post_inc(&mut self.next_selection_id),
1761                    start: selection.start.clone(),
1762                    end: selection.start.clone(),
1763                    reversed: false,
1764                    goal: SelectionGoal::None,
1765                });
1766            }
1767            for row in range.start.row + 1..range.end.row {
1768                let cursor = buffer.anchor_before(Point::new(row, buffer.line_len(row)));
1769                new_selections.push(Selection {
1770                    id: post_inc(&mut self.next_selection_id),
1771                    start: cursor.clone(),
1772                    end: cursor,
1773                    reversed: false,
1774                    goal: SelectionGoal::None,
1775                });
1776            }
1777            new_selections.push(Selection {
1778                id: selection.id,
1779                start: selection.end.clone(),
1780                end: selection.end.clone(),
1781                reversed: false,
1782                goal: SelectionGoal::None,
1783            });
1784            to_unfold.push(range);
1785        }
1786        self.unfold_ranges(to_unfold, cx);
1787        self.update_selections(new_selections, true, cx);
1788    }
1789
1790    pub fn add_selection_above(&mut self, _: &AddSelectionAbove, cx: &mut ViewContext<Self>) {
1791        self.add_selection(true, cx);
1792    }
1793
1794    pub fn add_selection_below(&mut self, _: &AddSelectionBelow, cx: &mut ViewContext<Self>) {
1795        self.add_selection(false, cx);
1796    }
1797
1798    fn add_selection(&mut self, above: bool, cx: &mut ViewContext<Self>) {
1799        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
1800        let mut selections = self.selections(cx).to_vec();
1801        let mut state = self.add_selections_state.take().unwrap_or_else(|| {
1802            let oldest_selection = selections.iter().min_by_key(|s| s.id).unwrap().clone();
1803            let range = oldest_selection.display_range(&display_map).sorted();
1804            let columns = cmp::min(range.start.column(), range.end.column())
1805                ..cmp::max(range.start.column(), range.end.column());
1806
1807            selections.clear();
1808            let mut stack = Vec::new();
1809            for row in range.start.row()..=range.end.row() {
1810                if let Some(selection) = self.build_columnar_selection(
1811                    &display_map,
1812                    row,
1813                    &columns,
1814                    oldest_selection.reversed,
1815                ) {
1816                    stack.push(selection.id);
1817                    selections.push(selection);
1818                }
1819            }
1820
1821            if above {
1822                stack.reverse();
1823            }
1824
1825            AddSelectionsState { above, stack }
1826        });
1827
1828        let last_added_selection = *state.stack.last().unwrap();
1829        let mut new_selections = Vec::new();
1830        if above == state.above {
1831            let end_row = if above {
1832                0
1833            } else {
1834                display_map.max_point().row()
1835            };
1836
1837            'outer: for selection in selections {
1838                if selection.id == last_added_selection {
1839                    let range = selection.display_range(&display_map).sorted();
1840                    debug_assert_eq!(range.start.row(), range.end.row());
1841                    let mut row = range.start.row();
1842                    let columns = if let SelectionGoal::ColumnRange { start, end } = selection.goal
1843                    {
1844                        start..end
1845                    } else {
1846                        cmp::min(range.start.column(), range.end.column())
1847                            ..cmp::max(range.start.column(), range.end.column())
1848                    };
1849
1850                    while row != end_row {
1851                        if above {
1852                            row -= 1;
1853                        } else {
1854                            row += 1;
1855                        }
1856
1857                        if let Some(new_selection) = self.build_columnar_selection(
1858                            &display_map,
1859                            row,
1860                            &columns,
1861                            selection.reversed,
1862                        ) {
1863                            state.stack.push(new_selection.id);
1864                            if above {
1865                                new_selections.push(new_selection);
1866                                new_selections.push(selection);
1867                            } else {
1868                                new_selections.push(selection);
1869                                new_selections.push(new_selection);
1870                            }
1871
1872                            continue 'outer;
1873                        }
1874                    }
1875                }
1876
1877                new_selections.push(selection);
1878            }
1879        } else {
1880            new_selections = selections;
1881            new_selections.retain(|s| s.id != last_added_selection);
1882            state.stack.pop();
1883        }
1884
1885        self.update_selections(new_selections, true, cx);
1886        if state.stack.len() > 1 {
1887            self.add_selections_state = Some(state);
1888        }
1889    }
1890
1891    pub fn select_larger_syntax_node(
1892        &mut self,
1893        _: &SelectLargerSyntaxNode,
1894        cx: &mut ViewContext<Self>,
1895    ) {
1896        let old_selections = self.selections(cx);
1897        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
1898        let buffer = self.buffer.read(cx);
1899
1900        let mut stack = mem::take(&mut self.select_larger_syntax_node_stack);
1901        let mut selected_larger_node = false;
1902        let mut new_selection_ranges = Vec::new();
1903        for selection in old_selections.iter() {
1904            let old_range = selection.start.to_offset(buffer)..selection.end.to_offset(buffer);
1905            let mut new_range = old_range.clone();
1906            while let Some(containing_range) = buffer.range_for_syntax_ancestor(new_range.clone()) {
1907                new_range = containing_range;
1908                if !display_map.intersects_fold(new_range.start)
1909                    && !display_map.intersects_fold(new_range.end)
1910                {
1911                    break;
1912                }
1913            }
1914
1915            selected_larger_node |= new_range != old_range;
1916            new_selection_ranges.push((selection.id, new_range, selection.reversed));
1917        }
1918
1919        if selected_larger_node {
1920            stack.push(old_selections);
1921            new_selection_ranges.sort_unstable_by_key(|(_, range, _)| range.start.clone());
1922            let new_selections = new_selection_ranges
1923                .into_iter()
1924                .map(|(id, range, reversed)| Selection {
1925                    id,
1926                    start: buffer.anchor_before(range.start),
1927                    end: buffer.anchor_before(range.end),
1928                    reversed,
1929                    goal: SelectionGoal::None,
1930                })
1931                .collect();
1932            self.update_selections(new_selections, true, cx);
1933        }
1934        self.select_larger_syntax_node_stack = stack;
1935    }
1936
1937    pub fn select_smaller_syntax_node(
1938        &mut self,
1939        _: &SelectSmallerSyntaxNode,
1940        cx: &mut ViewContext<Self>,
1941    ) {
1942        let mut stack = mem::take(&mut self.select_larger_syntax_node_stack);
1943        if let Some(selections) = stack.pop() {
1944            self.update_selections(selections.to_vec(), true, cx);
1945        }
1946        self.select_larger_syntax_node_stack = stack;
1947    }
1948
1949    pub fn move_to_enclosing_bracket(
1950        &mut self,
1951        _: &MoveToEnclosingBracket,
1952        cx: &mut ViewContext<Self>,
1953    ) {
1954        let mut selections = self.selections(cx).to_vec();
1955        let buffer = self.buffer.read(cx.as_ref());
1956        for selection in &mut selections {
1957            let selection_range = selection.offset_range(buffer);
1958            if let Some((open_range, close_range)) =
1959                buffer.enclosing_bracket_ranges(selection_range.clone())
1960            {
1961                let close_range = close_range.to_inclusive();
1962                let destination = if close_range.contains(&selection_range.start)
1963                    && close_range.contains(&selection_range.end)
1964                {
1965                    open_range.end
1966                } else {
1967                    *close_range.start()
1968                };
1969                selection.start = buffer.anchor_before(destination);
1970                selection.end = selection.start.clone();
1971            }
1972        }
1973
1974        self.update_selections(selections, true, cx);
1975    }
1976
1977    fn build_columnar_selection(
1978        &mut self,
1979        display_map: &DisplayMapSnapshot,
1980        row: u32,
1981        columns: &Range<u32>,
1982        reversed: bool,
1983    ) -> Option<Selection> {
1984        let is_empty = columns.start == columns.end;
1985        let line_len = display_map.line_len(row);
1986        if columns.start < line_len || (is_empty && columns.start == line_len) {
1987            let start = DisplayPoint::new(row, columns.start);
1988            let end = DisplayPoint::new(row, cmp::min(columns.end, line_len));
1989            Some(Selection {
1990                id: post_inc(&mut self.next_selection_id),
1991                start: display_map.anchor_before(start, Bias::Left),
1992                end: display_map.anchor_before(end, Bias::Left),
1993                reversed,
1994                goal: SelectionGoal::ColumnRange {
1995                    start: columns.start,
1996                    end: columns.end,
1997                },
1998            })
1999        } else {
2000            None
2001        }
2002    }
2003
2004    pub fn active_selection_sets<'a>(
2005        &'a self,
2006        cx: &'a AppContext,
2007    ) -> impl 'a + Iterator<Item = SelectionSetId> {
2008        let buffer = self.buffer.read(cx);
2009        let replica_id = buffer.replica_id();
2010        buffer
2011            .selection_sets()
2012            .filter(move |(set_id, set)| {
2013                set.active && (set_id.replica_id != replica_id || **set_id == self.selection_set_id)
2014            })
2015            .map(|(set_id, _)| *set_id)
2016    }
2017
2018    pub fn selections_in_range<'a>(
2019        &'a self,
2020        set_id: SelectionSetId,
2021        range: Range<DisplayPoint>,
2022        cx: &'a mut MutableAppContext,
2023    ) -> impl 'a + Iterator<Item = Range<DisplayPoint>> {
2024        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
2025        let buffer = self.buffer.read(cx);
2026        let selections = &buffer.selection_set(set_id).unwrap().selections;
2027        let start = display_map.anchor_before(range.start, Bias::Left);
2028        let start_index = self.selection_insertion_index(selections, &start, cx);
2029        let pending_selection = if set_id.replica_id == self.buffer.read(cx).replica_id() {
2030            self.pending_selection.as_ref().and_then(|s| {
2031                let selection_range = s.display_range(&display_map);
2032                if selection_range.start <= range.end || selection_range.end <= range.end {
2033                    Some(selection_range)
2034                } else {
2035                    None
2036                }
2037            })
2038        } else {
2039            None
2040        };
2041        selections[start_index..]
2042            .iter()
2043            .map(move |s| s.display_range(&display_map))
2044            .take_while(move |r| r.start <= range.end || r.end <= range.end)
2045            .chain(pending_selection)
2046    }
2047
2048    fn selection_insertion_index(
2049        &self,
2050        selections: &[Selection],
2051        start: &Anchor,
2052        cx: &AppContext,
2053    ) -> usize {
2054        let buffer = self.buffer.read(cx);
2055        match selections.binary_search_by(|probe| probe.start.cmp(&start, buffer).unwrap()) {
2056            Ok(index) => index,
2057            Err(index) => {
2058                if index > 0
2059                    && selections[index - 1].end.cmp(&start, buffer).unwrap() == Ordering::Greater
2060                {
2061                    index - 1
2062                } else {
2063                    index
2064                }
2065            }
2066        }
2067    }
2068
2069    fn selections(&mut self, cx: &mut ViewContext<Self>) -> Arc<[Selection]> {
2070        self.end_selection(cx);
2071        let buffer = self.buffer.read(cx);
2072        buffer
2073            .selection_set(self.selection_set_id)
2074            .unwrap()
2075            .selections
2076            .clone()
2077    }
2078
2079    fn update_selections(
2080        &mut self,
2081        mut selections: Vec<Selection>,
2082        autoscroll: bool,
2083        cx: &mut ViewContext<Self>,
2084    ) {
2085        // Merge overlapping selections.
2086        let buffer = self.buffer.read(cx);
2087        let mut i = 1;
2088        while i < selections.len() {
2089            if selections[i - 1]
2090                .end
2091                .cmp(&selections[i].start, buffer)
2092                .unwrap()
2093                >= Ordering::Equal
2094            {
2095                let removed = selections.remove(i);
2096                if removed.start.cmp(&selections[i - 1].start, buffer).unwrap() < Ordering::Equal {
2097                    selections[i - 1].start = removed.start;
2098                }
2099                if removed.end.cmp(&selections[i - 1].end, buffer).unwrap() > Ordering::Equal {
2100                    selections[i - 1].end = removed.end;
2101                }
2102            } else {
2103                i += 1;
2104            }
2105        }
2106
2107        self.buffer.update(cx, |buffer, cx| {
2108            buffer
2109                .update_selection_set(self.selection_set_id, selections, cx)
2110                .unwrap();
2111        });
2112        self.pause_cursor_blinking(cx);
2113
2114        if autoscroll {
2115            self.autoscroll_requested = true;
2116            cx.notify();
2117        }
2118
2119        self.add_selections_state = None;
2120        self.select_larger_syntax_node_stack.clear();
2121    }
2122
2123    fn start_transaction(&self, cx: &mut ViewContext<Self>) {
2124        self.buffer.update(cx, |buffer, _| {
2125            buffer
2126                .start_transaction(Some(self.selection_set_id))
2127                .unwrap()
2128        });
2129    }
2130
2131    fn end_transaction(&self, cx: &mut ViewContext<Self>) {
2132        self.buffer.update(cx, |buffer, cx| {
2133            buffer
2134                .end_transaction(Some(self.selection_set_id), cx)
2135                .unwrap()
2136        });
2137    }
2138
2139    pub fn page_up(&mut self, _: &PageUp, _: &mut ViewContext<Self>) {
2140        log::info!("Editor::page_up");
2141    }
2142
2143    pub fn page_down(&mut self, _: &PageDown, _: &mut ViewContext<Self>) {
2144        log::info!("Editor::page_down");
2145    }
2146
2147    pub fn fold(&mut self, _: &Fold, cx: &mut ViewContext<Self>) {
2148        let mut fold_ranges = Vec::new();
2149
2150        let selections = self.selections(cx);
2151        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
2152        for selection in selections.iter() {
2153            let range = selection.display_range(&display_map).sorted();
2154            let buffer_start_row = range.start.to_buffer_point(&display_map, Bias::Left).row;
2155
2156            for row in (0..=range.end.row()).rev() {
2157                if self.is_line_foldable(&display_map, row) && !display_map.is_line_folded(row) {
2158                    let fold_range = self.foldable_range_for_line(&display_map, row);
2159                    if fold_range.end.row >= buffer_start_row {
2160                        fold_ranges.push(fold_range);
2161                        if row <= range.start.row() {
2162                            break;
2163                        }
2164                    }
2165                }
2166            }
2167        }
2168
2169        self.fold_ranges(fold_ranges, cx);
2170    }
2171
2172    pub fn unfold(&mut self, _: &Unfold, cx: &mut ViewContext<Self>) {
2173        let selections = self.selections(cx);
2174        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
2175        let buffer = self.buffer.read(cx);
2176        let ranges = selections
2177            .iter()
2178            .map(|s| {
2179                let range = s.display_range(&display_map).sorted();
2180                let mut start = range.start.to_buffer_point(&display_map, Bias::Left);
2181                let mut end = range.end.to_buffer_point(&display_map, Bias::Left);
2182                start.column = 0;
2183                end.column = buffer.line_len(end.row);
2184                start..end
2185            })
2186            .collect::<Vec<_>>();
2187        self.unfold_ranges(ranges, cx);
2188    }
2189
2190    fn is_line_foldable(&self, display_map: &DisplayMapSnapshot, display_row: u32) -> bool {
2191        let max_point = display_map.max_point();
2192        if display_row >= max_point.row() {
2193            false
2194        } else {
2195            let (start_indent, is_blank) = display_map.line_indent(display_row);
2196            if is_blank {
2197                false
2198            } else {
2199                for display_row in display_row + 1..=max_point.row() {
2200                    let (indent, is_blank) = display_map.line_indent(display_row);
2201                    if !is_blank {
2202                        return indent > start_indent;
2203                    }
2204                }
2205                false
2206            }
2207        }
2208    }
2209
2210    fn foldable_range_for_line(
2211        &self,
2212        display_map: &DisplayMapSnapshot,
2213        start_row: u32,
2214    ) -> Range<Point> {
2215        let max_point = display_map.max_point();
2216
2217        let (start_indent, _) = display_map.line_indent(start_row);
2218        let start = DisplayPoint::new(start_row, display_map.line_len(start_row));
2219        let mut end = None;
2220        for row in start_row + 1..=max_point.row() {
2221            let (indent, is_blank) = display_map.line_indent(row);
2222            if !is_blank && indent <= start_indent {
2223                end = Some(DisplayPoint::new(row - 1, display_map.line_len(row - 1)));
2224                break;
2225            }
2226        }
2227
2228        let end = end.unwrap_or(max_point);
2229        return start.to_buffer_point(display_map, Bias::Left)
2230            ..end.to_buffer_point(display_map, Bias::Left);
2231    }
2232
2233    pub fn fold_selected_ranges(&mut self, _: &FoldSelectedRanges, cx: &mut ViewContext<Self>) {
2234        let selections = self.selections(cx);
2235        let buffer = self.buffer.read(cx);
2236        let ranges = selections
2237            .iter()
2238            .map(|s| s.point_range(buffer).sorted())
2239            .collect();
2240        self.fold_ranges(ranges, cx);
2241    }
2242
2243    fn fold_ranges<T: ToOffset>(&mut self, ranges: Vec<Range<T>>, cx: &mut ViewContext<Self>) {
2244        if !ranges.is_empty() {
2245            self.display_map.update(cx, |map, cx| map.fold(ranges, cx));
2246            self.autoscroll_requested = true;
2247            cx.notify();
2248        }
2249    }
2250
2251    fn unfold_ranges<T: ToOffset>(&mut self, ranges: Vec<Range<T>>, cx: &mut ViewContext<Self>) {
2252        if !ranges.is_empty() {
2253            self.display_map
2254                .update(cx, |map, cx| map.unfold(ranges, cx));
2255            self.autoscroll_requested = true;
2256            cx.notify();
2257        }
2258    }
2259
2260    pub fn longest_row(&self, cx: &mut MutableAppContext) -> u32 {
2261        self.display_map
2262            .update(cx, |map, cx| map.snapshot(cx))
2263            .longest_row()
2264    }
2265
2266    pub fn max_point(&self, cx: &mut MutableAppContext) -> DisplayPoint {
2267        self.display_map
2268            .update(cx, |map, cx| map.snapshot(cx))
2269            .max_point()
2270    }
2271
2272    pub fn text(&self, cx: &AppContext) -> String {
2273        self.buffer.read(cx).text()
2274    }
2275
2276    pub fn display_text(&self, cx: &mut MutableAppContext) -> String {
2277        self.display_map
2278            .update(cx, |map, cx| map.snapshot(cx))
2279            .text()
2280    }
2281
2282    // pub fn font_size(&self) -> f32 {
2283    //     self.settings.font_size
2284    // }
2285
2286    pub fn set_wrap_width(&self, width: f32, cx: &mut MutableAppContext) -> bool {
2287        self.display_map
2288            .update(cx, |map, cx| map.set_wrap_width(Some(width), cx))
2289    }
2290
2291    fn next_blink_epoch(&mut self) -> usize {
2292        self.blink_epoch += 1;
2293        self.blink_epoch
2294    }
2295
2296    fn pause_cursor_blinking(&mut self, cx: &mut ViewContext<Self>) {
2297        self.show_local_cursors = true;
2298        cx.notify();
2299
2300        let epoch = self.next_blink_epoch();
2301        cx.spawn(|this, mut cx| {
2302            let this = this.downgrade();
2303            async move {
2304                Timer::after(CURSOR_BLINK_INTERVAL).await;
2305                if let Some(this) = cx.read(|cx| this.upgrade(cx)) {
2306                    this.update(&mut cx, |this, cx| this.resume_cursor_blinking(epoch, cx))
2307                }
2308            }
2309        })
2310        .detach();
2311    }
2312
2313    fn resume_cursor_blinking(&mut self, epoch: usize, cx: &mut ViewContext<Self>) {
2314        if epoch == self.blink_epoch {
2315            self.blinking_paused = false;
2316            self.blink_cursors(epoch, cx);
2317        }
2318    }
2319
2320    fn blink_cursors(&mut self, epoch: usize, cx: &mut ViewContext<Self>) {
2321        if epoch == self.blink_epoch && self.focused && !self.blinking_paused {
2322            self.show_local_cursors = !self.show_local_cursors;
2323            cx.notify();
2324
2325            let epoch = self.next_blink_epoch();
2326            cx.spawn(|this, mut cx| {
2327                let this = this.downgrade();
2328                async move {
2329                    Timer::after(CURSOR_BLINK_INTERVAL).await;
2330                    if let Some(this) = cx.read(|cx| this.upgrade(cx)) {
2331                        this.update(&mut cx, |this, cx| this.blink_cursors(epoch, cx));
2332                    }
2333                }
2334            })
2335            .detach();
2336        }
2337    }
2338
2339    pub fn show_local_cursors(&self) -> bool {
2340        self.show_local_cursors
2341    }
2342
2343    fn on_buffer_changed(&mut self, _: ModelHandle<Buffer>, cx: &mut ViewContext<Self>) {
2344        cx.notify();
2345    }
2346
2347    fn on_buffer_event(
2348        &mut self,
2349        _: ModelHandle<Buffer>,
2350        event: &buffer::Event,
2351        cx: &mut ViewContext<Self>,
2352    ) {
2353        match event {
2354            buffer::Event::Edited => cx.emit(Event::Edited),
2355            buffer::Event::Dirtied => cx.emit(Event::Dirtied),
2356            buffer::Event::Saved => cx.emit(Event::Saved),
2357            buffer::Event::FileHandleChanged => cx.emit(Event::FileHandleChanged),
2358            buffer::Event::Reloaded => cx.emit(Event::FileHandleChanged),
2359            buffer::Event::Closed => cx.emit(Event::Closed),
2360            buffer::Event::Reparsed => {}
2361        }
2362    }
2363
2364    fn on_display_map_changed(&mut self, _: ModelHandle<DisplayMap>, cx: &mut ViewContext<Self>) {
2365        cx.notify();
2366    }
2367}
2368
2369impl Snapshot {
2370    pub fn is_empty(&self) -> bool {
2371        self.display_snapshot.is_empty()
2372    }
2373
2374    pub fn is_focused(&self) -> bool {
2375        self.is_focused
2376    }
2377
2378    pub fn placeholder_text(&self) -> Option<&Arc<str>> {
2379        self.placeholder_text.as_ref()
2380    }
2381
2382    pub fn buffer_row_count(&self) -> u32 {
2383        self.display_snapshot.buffer_row_count()
2384    }
2385
2386    pub fn buffer_rows(&self, start_row: u32) -> BufferRows {
2387        self.display_snapshot.buffer_rows(start_row)
2388    }
2389
2390    pub fn highlighted_chunks_for_rows(
2391        &mut self,
2392        display_rows: Range<u32>,
2393    ) -> display_map::HighlightedChunks {
2394        self.display_snapshot
2395            .highlighted_chunks_for_rows(display_rows)
2396    }
2397
2398    pub fn scroll_position(&self) -> Vector2F {
2399        compute_scroll_position(
2400            &self.display_snapshot,
2401            self.scroll_position,
2402            &self.scroll_top_anchor,
2403        )
2404    }
2405
2406    pub fn max_point(&self) -> DisplayPoint {
2407        self.display_snapshot.max_point()
2408    }
2409
2410    pub fn longest_row(&self) -> u32 {
2411        self.display_snapshot.longest_row()
2412    }
2413
2414    pub fn line_len(&self, display_row: u32) -> u32 {
2415        self.display_snapshot.line_len(display_row)
2416    }
2417
2418    pub fn line(&self, display_row: u32) -> String {
2419        self.display_snapshot.line(display_row)
2420    }
2421
2422    pub fn prev_row_boundary(&self, point: DisplayPoint) -> (DisplayPoint, Point) {
2423        self.display_snapshot.prev_row_boundary(point)
2424    }
2425
2426    pub fn next_row_boundary(&self, point: DisplayPoint) -> (DisplayPoint, Point) {
2427        self.display_snapshot.next_row_boundary(point)
2428    }
2429}
2430
2431impl EditorSettings {
2432    #[cfg(any(test, feature = "test-support"))]
2433    pub fn test(cx: &AppContext) -> Self {
2434        Self {
2435            tab_size: 4,
2436            style: {
2437                let font_cache: &gpui::FontCache = cx.font_cache();
2438                let font_family_name = Arc::from("Monaco");
2439                let font_properties = Default::default();
2440                let font_family_id = font_cache.load_family(&[&font_family_name]).unwrap();
2441                let font_id = font_cache
2442                    .select_font(font_family_id, &font_properties)
2443                    .unwrap();
2444                EditorStyle {
2445                    text: TextStyle {
2446                        font_family_name,
2447                        font_family_id,
2448                        font_id,
2449                        font_size: 14.,
2450                        color: Color::from_u32(0xff0000ff),
2451                        font_properties,
2452                        underline: false,
2453                    },
2454                    placeholder_text: None,
2455                    background: Default::default(),
2456                    gutter_background: Default::default(),
2457                    active_line_background: Default::default(),
2458                    line_number: Default::default(),
2459                    line_number_active: Default::default(),
2460                    selection: Default::default(),
2461                    guest_selections: Default::default(),
2462                    syntax: Default::default(),
2463                }
2464            },
2465        }
2466    }
2467}
2468
2469fn compute_scroll_position(
2470    snapshot: &DisplayMapSnapshot,
2471    mut scroll_position: Vector2F,
2472    scroll_top_anchor: &Anchor,
2473) -> Vector2F {
2474    let scroll_top = scroll_top_anchor
2475        .to_display_point(snapshot, Bias::Left)
2476        .row() as f32;
2477    scroll_position.set_y(scroll_top + scroll_position.y());
2478    scroll_position
2479}
2480
2481pub enum Event {
2482    Activate,
2483    Edited,
2484    Blurred,
2485    Dirtied,
2486    Saved,
2487    FileHandleChanged,
2488    Closed,
2489}
2490
2491impl Entity for Editor {
2492    type Event = Event;
2493
2494    fn release(&mut self, cx: &mut MutableAppContext) {
2495        self.buffer.update(cx, |buffer, cx| {
2496            buffer
2497                .remove_selection_set(self.selection_set_id, cx)
2498                .unwrap();
2499        });
2500    }
2501}
2502
2503impl View for Editor {
2504    fn render(&mut self, cx: &mut RenderContext<Self>) -> ElementBox {
2505        let settings = self.build_settings.borrow_mut()(cx);
2506        self.display_map.update(cx, |map, cx| {
2507            map.set_font(
2508                settings.style.text.font_id,
2509                settings.style.text.font_size,
2510                cx,
2511            )
2512        });
2513        EditorElement::new(self.handle.clone(), settings).boxed()
2514    }
2515
2516    fn ui_name() -> &'static str {
2517        "Editor"
2518    }
2519
2520    fn on_focus(&mut self, cx: &mut ViewContext<Self>) {
2521        self.focused = true;
2522        self.blink_cursors(self.blink_epoch, cx);
2523        self.buffer.update(cx, |buffer, cx| {
2524            buffer
2525                .set_active_selection_set(Some(self.selection_set_id), cx)
2526                .unwrap();
2527        });
2528    }
2529
2530    fn on_blur(&mut self, cx: &mut ViewContext<Self>) {
2531        self.focused = false;
2532        self.show_local_cursors = false;
2533        self.buffer.update(cx, |buffer, cx| {
2534            buffer.set_active_selection_set(None, cx).unwrap();
2535        });
2536        cx.emit(Event::Blurred);
2537        cx.notify();
2538    }
2539
2540    fn keymap_context(&self, _: &AppContext) -> gpui::keymap::Context {
2541        let mut cx = Self::default_keymap_context();
2542        let mode = match self.mode {
2543            EditorMode::SingleLine => "single_line",
2544            EditorMode::AutoHeight { .. } => "auto_height",
2545            EditorMode::Full => "full",
2546        };
2547        cx.map.insert("mode".into(), mode.into());
2548        cx
2549    }
2550}
2551
2552impl SelectionExt for Selection {
2553    fn display_range(&self, map: &DisplayMapSnapshot) -> Range<DisplayPoint> {
2554        let start = self.start.to_display_point(map, Bias::Left);
2555        let end = self.end.to_display_point(map, Bias::Left);
2556        if self.reversed {
2557            end..start
2558        } else {
2559            start..end
2560        }
2561    }
2562
2563    fn spanned_rows(
2564        &self,
2565        include_end_if_at_line_start: bool,
2566        map: &DisplayMapSnapshot,
2567    ) -> SpannedRows {
2568        let display_start = self.start.to_display_point(map, Bias::Left);
2569        let mut display_end = self.end.to_display_point(map, Bias::Right);
2570        if !include_end_if_at_line_start
2571            && display_end.row() != map.max_point().row()
2572            && display_start.row() != display_end.row()
2573            && display_end.column() == 0
2574        {
2575            *display_end.row_mut() -= 1;
2576        }
2577
2578        let (display_start, buffer_start) = map.prev_row_boundary(display_start);
2579        let (display_end, buffer_end) = map.next_row_boundary(display_end);
2580
2581        SpannedRows {
2582            buffer_rows: buffer_start.row..buffer_end.row + 1,
2583            display_rows: display_start.row()..display_end.row() + 1,
2584        }
2585    }
2586}
2587
2588#[cfg(test)]
2589mod tests {
2590    use super::*;
2591    use crate::test::sample_text;
2592    use buffer::{History, Point};
2593    use unindent::Unindent;
2594
2595    #[gpui::test]
2596    fn test_selection_with_mouse(cx: &mut gpui::MutableAppContext) {
2597        let buffer = cx.add_model(|cx| Buffer::new(0, "aaaaaa\nbbbbbb\ncccccc\ndddddd\n", cx));
2598        let settings = EditorSettings::test(cx);
2599        let (_, editor) =
2600            cx.add_window(Default::default(), |cx| build_editor(buffer, settings, cx));
2601
2602        editor.update(cx, |view, cx| {
2603            view.begin_selection(DisplayPoint::new(2, 2), false, cx);
2604        });
2605
2606        assert_eq!(
2607            editor.update(cx, |view, cx| view.selection_ranges(cx)),
2608            [DisplayPoint::new(2, 2)..DisplayPoint::new(2, 2)]
2609        );
2610
2611        editor.update(cx, |view, cx| {
2612            view.update_selection(DisplayPoint::new(3, 3), Vector2F::zero(), cx);
2613        });
2614
2615        assert_eq!(
2616            editor.update(cx, |view, cx| view.selection_ranges(cx)),
2617            [DisplayPoint::new(2, 2)..DisplayPoint::new(3, 3)]
2618        );
2619
2620        editor.update(cx, |view, cx| {
2621            view.update_selection(DisplayPoint::new(1, 1), Vector2F::zero(), cx);
2622        });
2623
2624        assert_eq!(
2625            editor.update(cx, |view, cx| view.selection_ranges(cx)),
2626            [DisplayPoint::new(2, 2)..DisplayPoint::new(1, 1)]
2627        );
2628
2629        editor.update(cx, |view, cx| {
2630            view.end_selection(cx);
2631            view.update_selection(DisplayPoint::new(3, 3), Vector2F::zero(), cx);
2632        });
2633
2634        assert_eq!(
2635            editor.update(cx, |view, cx| view.selection_ranges(cx)),
2636            [DisplayPoint::new(2, 2)..DisplayPoint::new(1, 1)]
2637        );
2638
2639        editor.update(cx, |view, cx| {
2640            view.begin_selection(DisplayPoint::new(3, 3), true, cx);
2641            view.update_selection(DisplayPoint::new(0, 0), Vector2F::zero(), cx);
2642        });
2643
2644        assert_eq!(
2645            editor.update(cx, |view, cx| view.selection_ranges(cx)),
2646            [
2647                DisplayPoint::new(2, 2)..DisplayPoint::new(1, 1),
2648                DisplayPoint::new(3, 3)..DisplayPoint::new(0, 0)
2649            ]
2650        );
2651
2652        editor.update(cx, |view, cx| {
2653            view.end_selection(cx);
2654        });
2655
2656        assert_eq!(
2657            editor.update(cx, |view, cx| view.selection_ranges(cx)),
2658            [DisplayPoint::new(3, 3)..DisplayPoint::new(0, 0)]
2659        );
2660    }
2661
2662    #[gpui::test]
2663    fn test_canceling_pending_selection(cx: &mut gpui::MutableAppContext) {
2664        let buffer = cx.add_model(|cx| Buffer::new(0, "aaaaaa\nbbbbbb\ncccccc\ndddddd\n", cx));
2665        let settings = EditorSettings::test(cx);
2666        let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer, settings, cx));
2667
2668        view.update(cx, |view, cx| {
2669            view.begin_selection(DisplayPoint::new(2, 2), false, cx);
2670            assert_eq!(
2671                view.selection_ranges(cx),
2672                [DisplayPoint::new(2, 2)..DisplayPoint::new(2, 2)]
2673            );
2674        });
2675
2676        view.update(cx, |view, cx| {
2677            view.update_selection(DisplayPoint::new(3, 3), Vector2F::zero(), cx);
2678            assert_eq!(
2679                view.selection_ranges(cx),
2680                [DisplayPoint::new(2, 2)..DisplayPoint::new(3, 3)]
2681            );
2682        });
2683
2684        view.update(cx, |view, cx| {
2685            view.cancel(&Cancel, cx);
2686            view.update_selection(DisplayPoint::new(1, 1), Vector2F::zero(), cx);
2687            assert_eq!(
2688                view.selection_ranges(cx),
2689                [DisplayPoint::new(2, 2)..DisplayPoint::new(3, 3)]
2690            );
2691        });
2692    }
2693
2694    #[gpui::test]
2695    fn test_cancel(cx: &mut gpui::MutableAppContext) {
2696        let buffer = cx.add_model(|cx| Buffer::new(0, "aaaaaa\nbbbbbb\ncccccc\ndddddd\n", cx));
2697        let settings = EditorSettings::test(cx);
2698        let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer, settings, cx));
2699
2700        view.update(cx, |view, cx| {
2701            view.begin_selection(DisplayPoint::new(3, 4), false, cx);
2702            view.update_selection(DisplayPoint::new(1, 1), Vector2F::zero(), cx);
2703            view.end_selection(cx);
2704
2705            view.begin_selection(DisplayPoint::new(0, 1), true, cx);
2706            view.update_selection(DisplayPoint::new(0, 3), Vector2F::zero(), cx);
2707            view.end_selection(cx);
2708            assert_eq!(
2709                view.selection_ranges(cx),
2710                [
2711                    DisplayPoint::new(0, 1)..DisplayPoint::new(0, 3),
2712                    DisplayPoint::new(3, 4)..DisplayPoint::new(1, 1),
2713                ]
2714            );
2715        });
2716
2717        view.update(cx, |view, cx| {
2718            view.cancel(&Cancel, cx);
2719            assert_eq!(
2720                view.selection_ranges(cx),
2721                [DisplayPoint::new(3, 4)..DisplayPoint::new(1, 1)]
2722            );
2723        });
2724
2725        view.update(cx, |view, cx| {
2726            view.cancel(&Cancel, cx);
2727            assert_eq!(
2728                view.selection_ranges(cx),
2729                [DisplayPoint::new(1, 1)..DisplayPoint::new(1, 1)]
2730            );
2731        });
2732    }
2733
2734    #[gpui::test]
2735    fn test_fold(cx: &mut gpui::MutableAppContext) {
2736        let buffer = cx.add_model(|cx| {
2737            Buffer::new(
2738                0,
2739                "
2740                    impl Foo {
2741                        // Hello!
2742
2743                        fn a() {
2744                            1
2745                        }
2746
2747                        fn b() {
2748                            2
2749                        }
2750
2751                        fn c() {
2752                            3
2753                        }
2754                    }
2755                "
2756                .unindent(),
2757                cx,
2758            )
2759        });
2760        let settings = EditorSettings::test(&cx);
2761        let (_, view) = cx.add_window(Default::default(), |cx| {
2762            build_editor(buffer.clone(), settings, cx)
2763        });
2764
2765        view.update(cx, |view, cx| {
2766            view.select_display_ranges(&[DisplayPoint::new(8, 0)..DisplayPoint::new(12, 0)], cx)
2767                .unwrap();
2768            view.fold(&Fold, cx);
2769            assert_eq!(
2770                view.display_text(cx),
2771                "
2772                    impl Foo {
2773                        // Hello!
2774
2775                        fn a() {
2776                            1
2777                        }
2778
2779                        fn b() {…
2780                        }
2781
2782                        fn c() {…
2783                        }
2784                    }
2785                "
2786                .unindent(),
2787            );
2788
2789            view.fold(&Fold, cx);
2790            assert_eq!(
2791                view.display_text(cx),
2792                "
2793                    impl Foo {…
2794                    }
2795                "
2796                .unindent(),
2797            );
2798
2799            view.unfold(&Unfold, cx);
2800            assert_eq!(
2801                view.display_text(cx),
2802                "
2803                    impl Foo {
2804                        // Hello!
2805
2806                        fn a() {
2807                            1
2808                        }
2809
2810                        fn b() {…
2811                        }
2812
2813                        fn c() {…
2814                        }
2815                    }
2816                "
2817                .unindent(),
2818            );
2819
2820            view.unfold(&Unfold, cx);
2821            assert_eq!(view.display_text(cx), buffer.read(cx).text());
2822        });
2823    }
2824
2825    #[gpui::test]
2826    fn test_move_cursor(cx: &mut gpui::MutableAppContext) {
2827        let buffer = cx.add_model(|cx| Buffer::new(0, sample_text(6, 6), cx));
2828        let settings = EditorSettings::test(&cx);
2829        let (_, view) = cx.add_window(Default::default(), |cx| {
2830            build_editor(buffer.clone(), settings, cx)
2831        });
2832
2833        buffer.update(cx, |buffer, cx| {
2834            buffer.edit(
2835                vec![
2836                    Point::new(1, 0)..Point::new(1, 0),
2837                    Point::new(1, 1)..Point::new(1, 1),
2838                ],
2839                "\t",
2840                cx,
2841            );
2842        });
2843
2844        view.update(cx, |view, cx| {
2845            assert_eq!(
2846                view.selection_ranges(cx),
2847                &[DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0)]
2848            );
2849
2850            view.move_down(&MoveDown, cx);
2851            assert_eq!(
2852                view.selection_ranges(cx),
2853                &[DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0)]
2854            );
2855
2856            view.move_right(&MoveRight, cx);
2857            assert_eq!(
2858                view.selection_ranges(cx),
2859                &[DisplayPoint::new(1, 4)..DisplayPoint::new(1, 4)]
2860            );
2861
2862            view.move_left(&MoveLeft, cx);
2863            assert_eq!(
2864                view.selection_ranges(cx),
2865                &[DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0)]
2866            );
2867
2868            view.move_up(&MoveUp, cx);
2869            assert_eq!(
2870                view.selection_ranges(cx),
2871                &[DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0)]
2872            );
2873
2874            view.move_to_end(&MoveToEnd, cx);
2875            assert_eq!(
2876                view.selection_ranges(cx),
2877                &[DisplayPoint::new(5, 6)..DisplayPoint::new(5, 6)]
2878            );
2879
2880            view.move_to_beginning(&MoveToBeginning, cx);
2881            assert_eq!(
2882                view.selection_ranges(cx),
2883                &[DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0)]
2884            );
2885
2886            view.select_display_ranges(&[DisplayPoint::new(0, 1)..DisplayPoint::new(0, 2)], cx)
2887                .unwrap();
2888            view.select_to_beginning(&SelectToBeginning, cx);
2889            assert_eq!(
2890                view.selection_ranges(cx),
2891                &[DisplayPoint::new(0, 1)..DisplayPoint::new(0, 0)]
2892            );
2893
2894            view.select_to_end(&SelectToEnd, cx);
2895            assert_eq!(
2896                view.selection_ranges(cx),
2897                &[DisplayPoint::new(0, 1)..DisplayPoint::new(5, 6)]
2898            );
2899        });
2900    }
2901
2902    #[gpui::test]
2903    fn test_move_cursor_multibyte(cx: &mut gpui::MutableAppContext) {
2904        let buffer = cx.add_model(|cx| Buffer::new(0, "ⓐⓑⓒⓓⓔ\nabcde\nαβγδε\n", cx));
2905        let settings = EditorSettings::test(&cx);
2906        let (_, view) = cx.add_window(Default::default(), |cx| {
2907            build_editor(buffer.clone(), settings, cx)
2908        });
2909
2910        assert_eq!('ⓐ'.len_utf8(), 3);
2911        assert_eq!('α'.len_utf8(), 2);
2912
2913        view.update(cx, |view, cx| {
2914            view.fold_ranges(
2915                vec![
2916                    Point::new(0, 6)..Point::new(0, 12),
2917                    Point::new(1, 2)..Point::new(1, 4),
2918                    Point::new(2, 4)..Point::new(2, 8),
2919                ],
2920                cx,
2921            );
2922            assert_eq!(view.display_text(cx), "ⓐⓑ…ⓔ\nab…e\nαβ…ε\n");
2923
2924            view.move_right(&MoveRight, cx);
2925            assert_eq!(view.selection_ranges(cx), &[empty_range(0, "".len())]);
2926            view.move_right(&MoveRight, cx);
2927            assert_eq!(view.selection_ranges(cx), &[empty_range(0, "ⓐⓑ".len())]);
2928            view.move_right(&MoveRight, cx);
2929            assert_eq!(view.selection_ranges(cx), &[empty_range(0, "ⓐⓑ…".len())]);
2930
2931            view.move_down(&MoveDown, cx);
2932            assert_eq!(view.selection_ranges(cx), &[empty_range(1, "ab…".len())]);
2933            view.move_left(&MoveLeft, cx);
2934            assert_eq!(view.selection_ranges(cx), &[empty_range(1, "ab".len())]);
2935            view.move_left(&MoveLeft, cx);
2936            assert_eq!(view.selection_ranges(cx), &[empty_range(1, "a".len())]);
2937
2938            view.move_down(&MoveDown, cx);
2939            assert_eq!(view.selection_ranges(cx), &[empty_range(2, "α".len())]);
2940            view.move_right(&MoveRight, cx);
2941            assert_eq!(view.selection_ranges(cx), &[empty_range(2, "αβ".len())]);
2942            view.move_right(&MoveRight, cx);
2943            assert_eq!(view.selection_ranges(cx), &[empty_range(2, "αβ…".len())]);
2944            view.move_right(&MoveRight, cx);
2945            assert_eq!(view.selection_ranges(cx), &[empty_range(2, "αβ…ε".len())]);
2946
2947            view.move_up(&MoveUp, cx);
2948            assert_eq!(view.selection_ranges(cx), &[empty_range(1, "ab…e".len())]);
2949            view.move_up(&MoveUp, cx);
2950            assert_eq!(view.selection_ranges(cx), &[empty_range(0, "ⓐⓑ…ⓔ".len())]);
2951            view.move_left(&MoveLeft, cx);
2952            assert_eq!(view.selection_ranges(cx), &[empty_range(0, "ⓐⓑ…".len())]);
2953            view.move_left(&MoveLeft, cx);
2954            assert_eq!(view.selection_ranges(cx), &[empty_range(0, "ⓐⓑ".len())]);
2955            view.move_left(&MoveLeft, cx);
2956            assert_eq!(view.selection_ranges(cx), &[empty_range(0, "".len())]);
2957        });
2958    }
2959
2960    #[gpui::test]
2961    fn test_move_cursor_different_line_lengths(cx: &mut gpui::MutableAppContext) {
2962        let buffer = cx.add_model(|cx| Buffer::new(0, "ⓐⓑⓒⓓⓔ\nabcd\nαβγ\nabcd\nⓐⓑⓒⓓⓔ\n", cx));
2963        let settings = EditorSettings::test(&cx);
2964        let (_, view) = cx.add_window(Default::default(), |cx| {
2965            build_editor(buffer.clone(), settings, cx)
2966        });
2967        view.update(cx, |view, cx| {
2968            view.select_display_ranges(&[empty_range(0, "ⓐⓑⓒⓓⓔ".len())], cx)
2969                .unwrap();
2970
2971            view.move_down(&MoveDown, cx);
2972            assert_eq!(view.selection_ranges(cx), &[empty_range(1, "abcd".len())]);
2973
2974            view.move_down(&MoveDown, cx);
2975            assert_eq!(view.selection_ranges(cx), &[empty_range(2, "αβγ".len())]);
2976
2977            view.move_down(&MoveDown, cx);
2978            assert_eq!(view.selection_ranges(cx), &[empty_range(3, "abcd".len())]);
2979
2980            view.move_down(&MoveDown, cx);
2981            assert_eq!(view.selection_ranges(cx), &[empty_range(4, "ⓐⓑⓒⓓⓔ".len())]);
2982
2983            view.move_up(&MoveUp, cx);
2984            assert_eq!(view.selection_ranges(cx), &[empty_range(3, "abcd".len())]);
2985
2986            view.move_up(&MoveUp, cx);
2987            assert_eq!(view.selection_ranges(cx), &[empty_range(2, "αβγ".len())]);
2988        });
2989    }
2990
2991    #[gpui::test]
2992    fn test_beginning_end_of_line(cx: &mut gpui::MutableAppContext) {
2993        let buffer = cx.add_model(|cx| Buffer::new(0, "abc\n  def", cx));
2994        let settings = EditorSettings::test(&cx);
2995        let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer, settings, cx));
2996        view.update(cx, |view, cx| {
2997            view.select_display_ranges(
2998                &[
2999                    DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1),
3000                    DisplayPoint::new(1, 4)..DisplayPoint::new(1, 4),
3001                ],
3002                cx,
3003            )
3004            .unwrap();
3005        });
3006
3007        view.update(cx, |view, cx| {
3008            view.move_to_beginning_of_line(&MoveToBeginningOfLine, cx);
3009            assert_eq!(
3010                view.selection_ranges(cx),
3011                &[
3012                    DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0),
3013                    DisplayPoint::new(1, 2)..DisplayPoint::new(1, 2),
3014                ]
3015            );
3016        });
3017
3018        view.update(cx, |view, cx| {
3019            view.move_to_beginning_of_line(&MoveToBeginningOfLine, cx);
3020            assert_eq!(
3021                view.selection_ranges(cx),
3022                &[
3023                    DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0),
3024                    DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0),
3025                ]
3026            );
3027        });
3028
3029        view.update(cx, |view, cx| {
3030            view.move_to_beginning_of_line(&MoveToBeginningOfLine, cx);
3031            assert_eq!(
3032                view.selection_ranges(cx),
3033                &[
3034                    DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0),
3035                    DisplayPoint::new(1, 2)..DisplayPoint::new(1, 2),
3036                ]
3037            );
3038        });
3039
3040        view.update(cx, |view, cx| {
3041            view.move_to_end_of_line(&MoveToEndOfLine, cx);
3042            assert_eq!(
3043                view.selection_ranges(cx),
3044                &[
3045                    DisplayPoint::new(0, 3)..DisplayPoint::new(0, 3),
3046                    DisplayPoint::new(1, 5)..DisplayPoint::new(1, 5),
3047                ]
3048            );
3049        });
3050
3051        // Moving to the end of line again is a no-op.
3052        view.update(cx, |view, cx| {
3053            view.move_to_end_of_line(&MoveToEndOfLine, cx);
3054            assert_eq!(
3055                view.selection_ranges(cx),
3056                &[
3057                    DisplayPoint::new(0, 3)..DisplayPoint::new(0, 3),
3058                    DisplayPoint::new(1, 5)..DisplayPoint::new(1, 5),
3059                ]
3060            );
3061        });
3062
3063        view.update(cx, |view, cx| {
3064            view.move_left(&MoveLeft, cx);
3065            view.select_to_beginning_of_line(&SelectToBeginningOfLine(true), cx);
3066            assert_eq!(
3067                view.selection_ranges(cx),
3068                &[
3069                    DisplayPoint::new(0, 2)..DisplayPoint::new(0, 0),
3070                    DisplayPoint::new(1, 4)..DisplayPoint::new(1, 2),
3071                ]
3072            );
3073        });
3074
3075        view.update(cx, |view, cx| {
3076            view.select_to_beginning_of_line(&SelectToBeginningOfLine(true), cx);
3077            assert_eq!(
3078                view.selection_ranges(cx),
3079                &[
3080                    DisplayPoint::new(0, 2)..DisplayPoint::new(0, 0),
3081                    DisplayPoint::new(1, 4)..DisplayPoint::new(1, 0),
3082                ]
3083            );
3084        });
3085
3086        view.update(cx, |view, cx| {
3087            view.select_to_beginning_of_line(&SelectToBeginningOfLine(true), cx);
3088            assert_eq!(
3089                view.selection_ranges(cx),
3090                &[
3091                    DisplayPoint::new(0, 2)..DisplayPoint::new(0, 0),
3092                    DisplayPoint::new(1, 4)..DisplayPoint::new(1, 2),
3093                ]
3094            );
3095        });
3096
3097        view.update(cx, |view, cx| {
3098            view.select_to_end_of_line(&SelectToEndOfLine, cx);
3099            assert_eq!(
3100                view.selection_ranges(cx),
3101                &[
3102                    DisplayPoint::new(0, 2)..DisplayPoint::new(0, 3),
3103                    DisplayPoint::new(1, 4)..DisplayPoint::new(1, 5),
3104                ]
3105            );
3106        });
3107
3108        view.update(cx, |view, cx| {
3109            view.delete_to_end_of_line(&DeleteToEndOfLine, cx);
3110            assert_eq!(view.display_text(cx), "ab\n  de");
3111            assert_eq!(
3112                view.selection_ranges(cx),
3113                &[
3114                    DisplayPoint::new(0, 2)..DisplayPoint::new(0, 2),
3115                    DisplayPoint::new(1, 4)..DisplayPoint::new(1, 4),
3116                ]
3117            );
3118        });
3119
3120        view.update(cx, |view, cx| {
3121            view.delete_to_beginning_of_line(&DeleteToBeginningOfLine, cx);
3122            assert_eq!(view.display_text(cx), "\n");
3123            assert_eq!(
3124                view.selection_ranges(cx),
3125                &[
3126                    DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0),
3127                    DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0),
3128                ]
3129            );
3130        });
3131    }
3132
3133    #[gpui::test]
3134    fn test_prev_next_word_boundary(cx: &mut gpui::MutableAppContext) {
3135        let buffer =
3136            cx.add_model(|cx| Buffer::new(0, "use std::str::{foo, bar}\n\n  {baz.qux()}", cx));
3137        let settings = EditorSettings::test(&cx);
3138        let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer, settings, cx));
3139        view.update(cx, |view, cx| {
3140            view.select_display_ranges(
3141                &[
3142                    DisplayPoint::new(0, 11)..DisplayPoint::new(0, 11),
3143                    DisplayPoint::new(2, 4)..DisplayPoint::new(2, 4),
3144                ],
3145                cx,
3146            )
3147            .unwrap();
3148        });
3149
3150        view.update(cx, |view, cx| {
3151            view.move_to_previous_word_boundary(&MoveToPreviousWordBoundary, cx);
3152            assert_eq!(
3153                view.selection_ranges(cx),
3154                &[
3155                    DisplayPoint::new(0, 9)..DisplayPoint::new(0, 9),
3156                    DisplayPoint::new(2, 3)..DisplayPoint::new(2, 3),
3157                ]
3158            );
3159        });
3160
3161        view.update(cx, |view, cx| {
3162            view.move_to_previous_word_boundary(&MoveToPreviousWordBoundary, cx);
3163            assert_eq!(
3164                view.selection_ranges(cx),
3165                &[
3166                    DisplayPoint::new(0, 7)..DisplayPoint::new(0, 7),
3167                    DisplayPoint::new(2, 2)..DisplayPoint::new(2, 2),
3168                ]
3169            );
3170        });
3171
3172        view.update(cx, |view, cx| {
3173            view.move_to_previous_word_boundary(&MoveToPreviousWordBoundary, cx);
3174            assert_eq!(
3175                view.selection_ranges(cx),
3176                &[
3177                    DisplayPoint::new(0, 4)..DisplayPoint::new(0, 4),
3178                    DisplayPoint::new(2, 0)..DisplayPoint::new(2, 0),
3179                ]
3180            );
3181        });
3182
3183        view.update(cx, |view, cx| {
3184            view.move_to_previous_word_boundary(&MoveToPreviousWordBoundary, cx);
3185            assert_eq!(
3186                view.selection_ranges(cx),
3187                &[
3188                    DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0),
3189                    DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0),
3190                ]
3191            );
3192        });
3193
3194        view.update(cx, |view, cx| {
3195            view.move_to_previous_word_boundary(&MoveToPreviousWordBoundary, cx);
3196            assert_eq!(
3197                view.selection_ranges(cx),
3198                &[
3199                    DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0),
3200                    DisplayPoint::new(0, 23)..DisplayPoint::new(0, 23),
3201                ]
3202            );
3203        });
3204
3205        view.update(cx, |view, cx| {
3206            view.move_to_next_word_boundary(&MoveToNextWordBoundary, cx);
3207            assert_eq!(
3208                view.selection_ranges(cx),
3209                &[
3210                    DisplayPoint::new(0, 3)..DisplayPoint::new(0, 3),
3211                    DisplayPoint::new(0, 24)..DisplayPoint::new(0, 24),
3212                ]
3213            );
3214        });
3215
3216        view.update(cx, |view, cx| {
3217            view.move_to_next_word_boundary(&MoveToNextWordBoundary, cx);
3218            assert_eq!(
3219                view.selection_ranges(cx),
3220                &[
3221                    DisplayPoint::new(0, 7)..DisplayPoint::new(0, 7),
3222                    DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0),
3223                ]
3224            );
3225        });
3226
3227        view.update(cx, |view, cx| {
3228            view.move_to_next_word_boundary(&MoveToNextWordBoundary, cx);
3229            assert_eq!(
3230                view.selection_ranges(cx),
3231                &[
3232                    DisplayPoint::new(0, 9)..DisplayPoint::new(0, 9),
3233                    DisplayPoint::new(2, 3)..DisplayPoint::new(2, 3),
3234                ]
3235            );
3236        });
3237
3238        view.update(cx, |view, cx| {
3239            view.move_right(&MoveRight, cx);
3240            view.select_to_previous_word_boundary(&SelectToPreviousWordBoundary, cx);
3241            assert_eq!(
3242                view.selection_ranges(cx),
3243                &[
3244                    DisplayPoint::new(0, 10)..DisplayPoint::new(0, 9),
3245                    DisplayPoint::new(2, 4)..DisplayPoint::new(2, 3),
3246                ]
3247            );
3248        });
3249
3250        view.update(cx, |view, cx| {
3251            view.select_to_previous_word_boundary(&SelectToPreviousWordBoundary, cx);
3252            assert_eq!(
3253                view.selection_ranges(cx),
3254                &[
3255                    DisplayPoint::new(0, 10)..DisplayPoint::new(0, 7),
3256                    DisplayPoint::new(2, 4)..DisplayPoint::new(2, 2),
3257                ]
3258            );
3259        });
3260
3261        view.update(cx, |view, cx| {
3262            view.select_to_next_word_boundary(&SelectToNextWordBoundary, cx);
3263            assert_eq!(
3264                view.selection_ranges(cx),
3265                &[
3266                    DisplayPoint::new(0, 10)..DisplayPoint::new(0, 9),
3267                    DisplayPoint::new(2, 4)..DisplayPoint::new(2, 3),
3268                ]
3269            );
3270        });
3271    }
3272
3273    #[gpui::test]
3274    fn test_prev_next_word_bounds_with_soft_wrap(cx: &mut gpui::MutableAppContext) {
3275        let buffer =
3276            cx.add_model(|cx| Buffer::new(0, "use one::{\n    two::three::four::five\n};", cx));
3277        let settings = EditorSettings::test(&cx);
3278        let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer, settings, cx));
3279
3280        view.update(cx, |view, cx| {
3281            view.set_wrap_width(140., cx);
3282            assert_eq!(
3283                view.display_text(cx),
3284                "use one::{\n    two::three::\n    four::five\n};"
3285            );
3286
3287            view.select_display_ranges(&[DisplayPoint::new(1, 7)..DisplayPoint::new(1, 7)], cx)
3288                .unwrap();
3289
3290            view.move_to_next_word_boundary(&MoveToNextWordBoundary, cx);
3291            assert_eq!(
3292                view.selection_ranges(cx),
3293                &[DisplayPoint::new(1, 9)..DisplayPoint::new(1, 9)]
3294            );
3295
3296            view.move_to_next_word_boundary(&MoveToNextWordBoundary, cx);
3297            assert_eq!(
3298                view.selection_ranges(cx),
3299                &[DisplayPoint::new(1, 14)..DisplayPoint::new(1, 14)]
3300            );
3301
3302            view.move_to_next_word_boundary(&MoveToNextWordBoundary, cx);
3303            assert_eq!(
3304                view.selection_ranges(cx),
3305                &[DisplayPoint::new(2, 4)..DisplayPoint::new(2, 4)]
3306            );
3307
3308            view.move_to_next_word_boundary(&MoveToNextWordBoundary, cx);
3309            assert_eq!(
3310                view.selection_ranges(cx),
3311                &[DisplayPoint::new(2, 8)..DisplayPoint::new(2, 8)]
3312            );
3313
3314            view.move_to_previous_word_boundary(&MoveToPreviousWordBoundary, cx);
3315            assert_eq!(
3316                view.selection_ranges(cx),
3317                &[DisplayPoint::new(2, 4)..DisplayPoint::new(2, 4)]
3318            );
3319
3320            view.move_to_previous_word_boundary(&MoveToPreviousWordBoundary, cx);
3321            assert_eq!(
3322                view.selection_ranges(cx),
3323                &[DisplayPoint::new(1, 14)..DisplayPoint::new(1, 14)]
3324            );
3325        });
3326    }
3327
3328    #[gpui::test]
3329    fn test_delete_to_word_boundary(cx: &mut gpui::MutableAppContext) {
3330        let buffer = cx.add_model(|cx| Buffer::new(0, "one two three four", cx));
3331        let settings = EditorSettings::test(&cx);
3332        let (_, view) = cx.add_window(Default::default(), |cx| {
3333            build_editor(buffer.clone(), settings, cx)
3334        });
3335
3336        view.update(cx, |view, cx| {
3337            view.select_display_ranges(
3338                &[
3339                    // an empty selection - the preceding word fragment is deleted
3340                    DisplayPoint::new(0, 2)..DisplayPoint::new(0, 2),
3341                    // characters selected - they are deleted
3342                    DisplayPoint::new(0, 9)..DisplayPoint::new(0, 12),
3343                ],
3344                cx,
3345            )
3346            .unwrap();
3347            view.delete_to_previous_word_boundary(&DeleteToPreviousWordBoundary, cx);
3348        });
3349
3350        assert_eq!(buffer.read(cx).text(), "e two te four");
3351
3352        view.update(cx, |view, cx| {
3353            view.select_display_ranges(
3354                &[
3355                    // an empty selection - the following word fragment is deleted
3356                    DisplayPoint::new(0, 3)..DisplayPoint::new(0, 3),
3357                    // characters selected - they are deleted
3358                    DisplayPoint::new(0, 9)..DisplayPoint::new(0, 10),
3359                ],
3360                cx,
3361            )
3362            .unwrap();
3363            view.delete_to_next_word_boundary(&DeleteToNextWordBoundary, cx);
3364        });
3365
3366        assert_eq!(buffer.read(cx).text(), "e t te our");
3367    }
3368
3369    #[gpui::test]
3370    fn test_backspace(cx: &mut gpui::MutableAppContext) {
3371        let buffer = cx.add_model(|cx| {
3372            Buffer::new(
3373                0,
3374                "one two three\nfour five six\nseven eight nine\nten\n",
3375                cx,
3376            )
3377        });
3378        let settings = EditorSettings::test(&cx);
3379        let (_, view) = cx.add_window(Default::default(), |cx| {
3380            build_editor(buffer.clone(), settings, cx)
3381        });
3382
3383        view.update(cx, |view, cx| {
3384            view.select_display_ranges(
3385                &[
3386                    // an empty selection - the preceding character is deleted
3387                    DisplayPoint::new(0, 2)..DisplayPoint::new(0, 2),
3388                    // one character selected - it is deleted
3389                    DisplayPoint::new(1, 4)..DisplayPoint::new(1, 3),
3390                    // a line suffix selected - it is deleted
3391                    DisplayPoint::new(2, 6)..DisplayPoint::new(3, 0),
3392                ],
3393                cx,
3394            )
3395            .unwrap();
3396            view.backspace(&Backspace, cx);
3397        });
3398
3399        assert_eq!(
3400            buffer.read(cx).text(),
3401            "oe two three\nfou five six\nseven ten\n"
3402        );
3403    }
3404
3405    #[gpui::test]
3406    fn test_delete(cx: &mut gpui::MutableAppContext) {
3407        let buffer = cx.add_model(|cx| {
3408            Buffer::new(
3409                0,
3410                "one two three\nfour five six\nseven eight nine\nten\n",
3411                cx,
3412            )
3413        });
3414        let settings = EditorSettings::test(&cx);
3415        let (_, view) = cx.add_window(Default::default(), |cx| {
3416            build_editor(buffer.clone(), settings, cx)
3417        });
3418
3419        view.update(cx, |view, cx| {
3420            view.select_display_ranges(
3421                &[
3422                    // an empty selection - the following character is deleted
3423                    DisplayPoint::new(0, 2)..DisplayPoint::new(0, 2),
3424                    // one character selected - it is deleted
3425                    DisplayPoint::new(1, 4)..DisplayPoint::new(1, 3),
3426                    // a line suffix selected - it is deleted
3427                    DisplayPoint::new(2, 6)..DisplayPoint::new(3, 0),
3428                ],
3429                cx,
3430            )
3431            .unwrap();
3432            view.delete(&Delete, cx);
3433        });
3434
3435        assert_eq!(
3436            buffer.read(cx).text(),
3437            "on two three\nfou five six\nseven ten\n"
3438        );
3439    }
3440
3441    #[gpui::test]
3442    fn test_delete_line(cx: &mut gpui::MutableAppContext) {
3443        let settings = EditorSettings::test(&cx);
3444        let buffer = cx.add_model(|cx| Buffer::new(0, "abc\ndef\nghi\n", cx));
3445        let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer, settings, cx));
3446        view.update(cx, |view, cx| {
3447            view.select_display_ranges(
3448                &[
3449                    DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1),
3450                    DisplayPoint::new(1, 0)..DisplayPoint::new(1, 1),
3451                    DisplayPoint::new(3, 0)..DisplayPoint::new(3, 0),
3452                ],
3453                cx,
3454            )
3455            .unwrap();
3456            view.delete_line(&DeleteLine, cx);
3457            assert_eq!(view.display_text(cx), "ghi");
3458            assert_eq!(
3459                view.selection_ranges(cx),
3460                vec![
3461                    DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0),
3462                    DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1)
3463                ]
3464            );
3465        });
3466
3467        let settings = EditorSettings::test(&cx);
3468        let buffer = cx.add_model(|cx| Buffer::new(0, "abc\ndef\nghi\n", cx));
3469        let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer, settings, cx));
3470        view.update(cx, |view, cx| {
3471            view.select_display_ranges(&[DisplayPoint::new(2, 0)..DisplayPoint::new(0, 1)], cx)
3472                .unwrap();
3473            view.delete_line(&DeleteLine, cx);
3474            assert_eq!(view.display_text(cx), "ghi\n");
3475            assert_eq!(
3476                view.selection_ranges(cx),
3477                vec![DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1)]
3478            );
3479        });
3480    }
3481
3482    #[gpui::test]
3483    fn test_duplicate_line(cx: &mut gpui::MutableAppContext) {
3484        let settings = EditorSettings::test(&cx);
3485        let buffer = cx.add_model(|cx| Buffer::new(0, "abc\ndef\nghi\n", cx));
3486        let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer, settings, cx));
3487        view.update(cx, |view, cx| {
3488            view.select_display_ranges(
3489                &[
3490                    DisplayPoint::new(0, 0)..DisplayPoint::new(0, 1),
3491                    DisplayPoint::new(0, 2)..DisplayPoint::new(0, 2),
3492                    DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0),
3493                    DisplayPoint::new(3, 0)..DisplayPoint::new(3, 0),
3494                ],
3495                cx,
3496            )
3497            .unwrap();
3498            view.duplicate_line(&DuplicateLine, cx);
3499            assert_eq!(view.display_text(cx), "abc\nabc\ndef\ndef\nghi\n\n");
3500            assert_eq!(
3501                view.selection_ranges(cx),
3502                vec![
3503                    DisplayPoint::new(1, 0)..DisplayPoint::new(1, 1),
3504                    DisplayPoint::new(1, 2)..DisplayPoint::new(1, 2),
3505                    DisplayPoint::new(3, 0)..DisplayPoint::new(3, 0),
3506                    DisplayPoint::new(6, 0)..DisplayPoint::new(6, 0),
3507                ]
3508            );
3509        });
3510
3511        let settings = EditorSettings::test(&cx);
3512        let buffer = cx.add_model(|cx| Buffer::new(0, "abc\ndef\nghi\n", cx));
3513        let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer, settings, cx));
3514        view.update(cx, |view, cx| {
3515            view.select_display_ranges(
3516                &[
3517                    DisplayPoint::new(0, 1)..DisplayPoint::new(1, 1),
3518                    DisplayPoint::new(1, 2)..DisplayPoint::new(2, 1),
3519                ],
3520                cx,
3521            )
3522            .unwrap();
3523            view.duplicate_line(&DuplicateLine, cx);
3524            assert_eq!(view.display_text(cx), "abc\ndef\nghi\nabc\ndef\nghi\n");
3525            assert_eq!(
3526                view.selection_ranges(cx),
3527                vec![
3528                    DisplayPoint::new(3, 1)..DisplayPoint::new(4, 1),
3529                    DisplayPoint::new(4, 2)..DisplayPoint::new(5, 1),
3530                ]
3531            );
3532        });
3533    }
3534
3535    #[gpui::test]
3536    fn test_move_line_up_down(cx: &mut gpui::MutableAppContext) {
3537        let settings = EditorSettings::test(&cx);
3538        let buffer = cx.add_model(|cx| Buffer::new(0, sample_text(10, 5), cx));
3539        let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer, settings, cx));
3540        view.update(cx, |view, cx| {
3541            view.fold_ranges(
3542                vec![
3543                    Point::new(0, 2)..Point::new(1, 2),
3544                    Point::new(2, 3)..Point::new(4, 1),
3545                    Point::new(7, 0)..Point::new(8, 4),
3546                ],
3547                cx,
3548            );
3549            view.select_display_ranges(
3550                &[
3551                    DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1),
3552                    DisplayPoint::new(3, 1)..DisplayPoint::new(3, 1),
3553                    DisplayPoint::new(3, 2)..DisplayPoint::new(4, 3),
3554                    DisplayPoint::new(5, 0)..DisplayPoint::new(5, 2),
3555                ],
3556                cx,
3557            )
3558            .unwrap();
3559            assert_eq!(
3560                view.display_text(cx),
3561                "aa…bbb\nccc…eeee\nfffff\nggggg\n…i\njjjjj"
3562            );
3563
3564            view.move_line_up(&MoveLineUp, cx);
3565            assert_eq!(
3566                view.display_text(cx),
3567                "aa…bbb\nccc…eeee\nggggg\n…i\njjjjj\nfffff"
3568            );
3569            assert_eq!(
3570                view.selection_ranges(cx),
3571                vec![
3572                    DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1),
3573                    DisplayPoint::new(2, 1)..DisplayPoint::new(2, 1),
3574                    DisplayPoint::new(2, 2)..DisplayPoint::new(3, 3),
3575                    DisplayPoint::new(4, 0)..DisplayPoint::new(4, 2)
3576                ]
3577            );
3578        });
3579
3580        view.update(cx, |view, cx| {
3581            view.move_line_down(&MoveLineDown, cx);
3582            assert_eq!(
3583                view.display_text(cx),
3584                "ccc…eeee\naa…bbb\nfffff\nggggg\n…i\njjjjj"
3585            );
3586            assert_eq!(
3587                view.selection_ranges(cx),
3588                vec![
3589                    DisplayPoint::new(1, 1)..DisplayPoint::new(1, 1),
3590                    DisplayPoint::new(3, 1)..DisplayPoint::new(3, 1),
3591                    DisplayPoint::new(3, 2)..DisplayPoint::new(4, 3),
3592                    DisplayPoint::new(5, 0)..DisplayPoint::new(5, 2)
3593                ]
3594            );
3595        });
3596
3597        view.update(cx, |view, cx| {
3598            view.move_line_down(&MoveLineDown, cx);
3599            assert_eq!(
3600                view.display_text(cx),
3601                "ccc…eeee\nfffff\naa…bbb\nggggg\n…i\njjjjj"
3602            );
3603            assert_eq!(
3604                view.selection_ranges(cx),
3605                vec![
3606                    DisplayPoint::new(2, 1)..DisplayPoint::new(2, 1),
3607                    DisplayPoint::new(3, 1)..DisplayPoint::new(3, 1),
3608                    DisplayPoint::new(3, 2)..DisplayPoint::new(4, 3),
3609                    DisplayPoint::new(5, 0)..DisplayPoint::new(5, 2)
3610                ]
3611            );
3612        });
3613
3614        view.update(cx, |view, cx| {
3615            view.move_line_up(&MoveLineUp, cx);
3616            assert_eq!(
3617                view.display_text(cx),
3618                "ccc…eeee\naa…bbb\nggggg\n…i\njjjjj\nfffff"
3619            );
3620            assert_eq!(
3621                view.selection_ranges(cx),
3622                vec![
3623                    DisplayPoint::new(1, 1)..DisplayPoint::new(1, 1),
3624                    DisplayPoint::new(2, 1)..DisplayPoint::new(2, 1),
3625                    DisplayPoint::new(2, 2)..DisplayPoint::new(3, 3),
3626                    DisplayPoint::new(4, 0)..DisplayPoint::new(4, 2)
3627                ]
3628            );
3629        });
3630    }
3631
3632    #[gpui::test]
3633    fn test_clipboard(cx: &mut gpui::MutableAppContext) {
3634        let buffer = cx.add_model(|cx| Buffer::new(0, "one✅ two three four five six ", cx));
3635        let settings = EditorSettings::test(&cx);
3636        let view = cx
3637            .add_window(Default::default(), |cx| {
3638                build_editor(buffer.clone(), settings, cx)
3639            })
3640            .1;
3641
3642        // Cut with three selections. Clipboard text is divided into three slices.
3643        view.update(cx, |view, cx| {
3644            view.select_ranges(vec![0..7, 11..17, 22..27], false, cx);
3645            view.cut(&Cut, cx);
3646            assert_eq!(view.display_text(cx), "two four six ");
3647        });
3648
3649        // Paste with three cursors. Each cursor pastes one slice of the clipboard text.
3650        view.update(cx, |view, cx| {
3651            view.select_ranges(vec![4..4, 9..9, 13..13], false, cx);
3652            view.paste(&Paste, cx);
3653            assert_eq!(view.display_text(cx), "two one✅ four three six five ");
3654            assert_eq!(
3655                view.selection_ranges(cx),
3656                &[
3657                    DisplayPoint::new(0, 11)..DisplayPoint::new(0, 11),
3658                    DisplayPoint::new(0, 22)..DisplayPoint::new(0, 22),
3659                    DisplayPoint::new(0, 31)..DisplayPoint::new(0, 31)
3660                ]
3661            );
3662        });
3663
3664        // Paste again but with only two cursors. Since the number of cursors doesn't
3665        // match the number of slices in the clipboard, the entire clipboard text
3666        // is pasted at each cursor.
3667        view.update(cx, |view, cx| {
3668            view.select_ranges(vec![0..0, 31..31], false, cx);
3669            view.insert(&Insert("( ".into()), cx);
3670            view.paste(&Paste, cx);
3671            view.insert(&Insert(") ".into()), cx);
3672            assert_eq!(
3673                view.display_text(cx),
3674                "( one✅ three five ) two one✅ four three six five ( one✅ three five ) "
3675            );
3676        });
3677
3678        view.update(cx, |view, cx| {
3679            view.select_ranges(vec![0..0], false, cx);
3680            view.insert(&Insert("123\n4567\n89\n".into()), cx);
3681            assert_eq!(
3682                view.display_text(cx),
3683                "123\n4567\n89\n( one✅ three five ) two one✅ four three six five ( one✅ three five ) "
3684            );
3685        });
3686
3687        // Cut with three selections, one of which is full-line.
3688        view.update(cx, |view, cx| {
3689            view.select_display_ranges(
3690                &[
3691                    DisplayPoint::new(0, 1)..DisplayPoint::new(0, 2),
3692                    DisplayPoint::new(1, 1)..DisplayPoint::new(1, 1),
3693                    DisplayPoint::new(2, 0)..DisplayPoint::new(2, 1),
3694                ],
3695                cx,
3696            )
3697            .unwrap();
3698            view.cut(&Cut, cx);
3699            assert_eq!(
3700                view.display_text(cx),
3701                "13\n9\n( one✅ three five ) two one✅ four three six five ( one✅ three five ) "
3702            );
3703        });
3704
3705        // Paste with three selections, noticing how the copied selection that was full-line
3706        // gets inserted before the second cursor.
3707        view.update(cx, |view, cx| {
3708            view.select_display_ranges(
3709                &[
3710                    DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1),
3711                    DisplayPoint::new(1, 1)..DisplayPoint::new(1, 1),
3712                    DisplayPoint::new(2, 2)..DisplayPoint::new(2, 3),
3713                ],
3714                cx,
3715            )
3716            .unwrap();
3717            view.paste(&Paste, cx);
3718            assert_eq!(
3719                view.display_text(cx),
3720                "123\n4567\n9\n( 8ne✅ three five ) two one✅ four three six five ( one✅ three five ) "
3721            );
3722            assert_eq!(
3723                view.selection_ranges(cx),
3724                &[
3725                    DisplayPoint::new(0, 2)..DisplayPoint::new(0, 2),
3726                    DisplayPoint::new(2, 1)..DisplayPoint::new(2, 1),
3727                    DisplayPoint::new(3, 3)..DisplayPoint::new(3, 3),
3728                ]
3729            );
3730        });
3731
3732        // Copy with a single cursor only, which writes the whole line into the clipboard.
3733        view.update(cx, |view, cx| {
3734            view.select_display_ranges(&[DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1)], cx)
3735                .unwrap();
3736            view.copy(&Copy, cx);
3737        });
3738
3739        // Paste with three selections, noticing how the copied full-line selection is inserted
3740        // before the empty selections but replaces the selection that is non-empty.
3741        view.update(cx, |view, cx| {
3742            view.select_display_ranges(
3743                &[
3744                    DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1),
3745                    DisplayPoint::new(1, 0)..DisplayPoint::new(1, 2),
3746                    DisplayPoint::new(2, 1)..DisplayPoint::new(2, 1),
3747                ],
3748                cx,
3749            )
3750            .unwrap();
3751            view.paste(&Paste, cx);
3752            assert_eq!(
3753                view.display_text(cx),
3754                "123\n123\n123\n67\n123\n9\n( 8ne✅ three five ) two one✅ four three six five ( one✅ three five ) "
3755            );
3756            assert_eq!(
3757                view.selection_ranges(cx),
3758                &[
3759                    DisplayPoint::new(1, 1)..DisplayPoint::new(1, 1),
3760                    DisplayPoint::new(3, 0)..DisplayPoint::new(3, 0),
3761                    DisplayPoint::new(5, 1)..DisplayPoint::new(5, 1),
3762                ]
3763            );
3764        });
3765    }
3766
3767    #[gpui::test]
3768    fn test_select_all(cx: &mut gpui::MutableAppContext) {
3769        let buffer = cx.add_model(|cx| Buffer::new(0, "abc\nde\nfgh", cx));
3770        let settings = EditorSettings::test(&cx);
3771        let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer, settings, cx));
3772        view.update(cx, |view, cx| {
3773            view.select_all(&SelectAll, cx);
3774            assert_eq!(
3775                view.selection_ranges(cx),
3776                &[DisplayPoint::new(0, 0)..DisplayPoint::new(2, 3)]
3777            );
3778        });
3779    }
3780
3781    #[gpui::test]
3782    fn test_select_line(cx: &mut gpui::MutableAppContext) {
3783        let settings = EditorSettings::test(&cx);
3784        let buffer = cx.add_model(|cx| Buffer::new(0, sample_text(6, 5), cx));
3785        let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer, settings, cx));
3786        view.update(cx, |view, cx| {
3787            view.select_display_ranges(
3788                &[
3789                    DisplayPoint::new(0, 0)..DisplayPoint::new(0, 1),
3790                    DisplayPoint::new(0, 2)..DisplayPoint::new(0, 2),
3791                    DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0),
3792                    DisplayPoint::new(4, 2)..DisplayPoint::new(4, 2),
3793                ],
3794                cx,
3795            )
3796            .unwrap();
3797            view.select_line(&SelectLine, cx);
3798            assert_eq!(
3799                view.selection_ranges(cx),
3800                vec![
3801                    DisplayPoint::new(0, 0)..DisplayPoint::new(2, 0),
3802                    DisplayPoint::new(4, 0)..DisplayPoint::new(5, 0),
3803                ]
3804            );
3805        });
3806
3807        view.update(cx, |view, cx| {
3808            view.select_line(&SelectLine, cx);
3809            assert_eq!(
3810                view.selection_ranges(cx),
3811                vec![
3812                    DisplayPoint::new(0, 0)..DisplayPoint::new(3, 0),
3813                    DisplayPoint::new(4, 0)..DisplayPoint::new(5, 5),
3814                ]
3815            );
3816        });
3817
3818        view.update(cx, |view, cx| {
3819            view.select_line(&SelectLine, cx);
3820            assert_eq!(
3821                view.selection_ranges(cx),
3822                vec![DisplayPoint::new(0, 0)..DisplayPoint::new(5, 5)]
3823            );
3824        });
3825    }
3826
3827    #[gpui::test]
3828    fn test_split_selection_into_lines(cx: &mut gpui::MutableAppContext) {
3829        let settings = EditorSettings::test(&cx);
3830        let buffer = cx.add_model(|cx| Buffer::new(0, sample_text(9, 5), cx));
3831        let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer, settings, cx));
3832        view.update(cx, |view, cx| {
3833            view.fold_ranges(
3834                vec![
3835                    Point::new(0, 2)..Point::new(1, 2),
3836                    Point::new(2, 3)..Point::new(4, 1),
3837                    Point::new(7, 0)..Point::new(8, 4),
3838                ],
3839                cx,
3840            );
3841            view.select_display_ranges(
3842                &[
3843                    DisplayPoint::new(0, 0)..DisplayPoint::new(0, 1),
3844                    DisplayPoint::new(0, 2)..DisplayPoint::new(0, 2),
3845                    DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0),
3846                    DisplayPoint::new(4, 4)..DisplayPoint::new(4, 4),
3847                ],
3848                cx,
3849            )
3850            .unwrap();
3851            assert_eq!(view.display_text(cx), "aa…bbb\nccc…eeee\nfffff\nggggg\n…i");
3852        });
3853
3854        view.update(cx, |view, cx| {
3855            view.split_selection_into_lines(&SplitSelectionIntoLines, cx);
3856            assert_eq!(
3857                view.display_text(cx),
3858                "aaaaa\nbbbbb\nccc…eeee\nfffff\nggggg\n…i"
3859            );
3860            assert_eq!(
3861                view.selection_ranges(cx),
3862                [
3863                    DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1),
3864                    DisplayPoint::new(0, 2)..DisplayPoint::new(0, 2),
3865                    DisplayPoint::new(2, 0)..DisplayPoint::new(2, 0),
3866                    DisplayPoint::new(5, 4)..DisplayPoint::new(5, 4)
3867                ]
3868            );
3869        });
3870
3871        view.update(cx, |view, cx| {
3872            view.select_display_ranges(&[DisplayPoint::new(5, 0)..DisplayPoint::new(0, 1)], cx)
3873                .unwrap();
3874            view.split_selection_into_lines(&SplitSelectionIntoLines, cx);
3875            assert_eq!(
3876                view.display_text(cx),
3877                "aaaaa\nbbbbb\nccccc\nddddd\neeeee\nfffff\nggggg\nhhhhh\niiiii"
3878            );
3879            assert_eq!(
3880                view.selection_ranges(cx),
3881                [
3882                    DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1),
3883                    DisplayPoint::new(1, 5)..DisplayPoint::new(1, 5),
3884                    DisplayPoint::new(2, 5)..DisplayPoint::new(2, 5),
3885                    DisplayPoint::new(3, 5)..DisplayPoint::new(3, 5),
3886                    DisplayPoint::new(4, 5)..DisplayPoint::new(4, 5),
3887                    DisplayPoint::new(5, 5)..DisplayPoint::new(5, 5),
3888                    DisplayPoint::new(6, 5)..DisplayPoint::new(6, 5),
3889                    DisplayPoint::new(7, 0)..DisplayPoint::new(7, 0)
3890                ]
3891            );
3892        });
3893    }
3894
3895    #[gpui::test]
3896    fn test_add_selection_above_below(cx: &mut gpui::MutableAppContext) {
3897        let settings = EditorSettings::test(&cx);
3898        let buffer = cx.add_model(|cx| Buffer::new(0, "abc\ndefghi\n\njk\nlmno\n", cx));
3899        let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer, settings, cx));
3900
3901        view.update(cx, |view, cx| {
3902            view.select_display_ranges(&[DisplayPoint::new(1, 3)..DisplayPoint::new(1, 3)], cx)
3903                .unwrap();
3904        });
3905        view.update(cx, |view, cx| {
3906            view.add_selection_above(&AddSelectionAbove, cx);
3907            assert_eq!(
3908                view.selection_ranges(cx),
3909                vec![
3910                    DisplayPoint::new(0, 3)..DisplayPoint::new(0, 3),
3911                    DisplayPoint::new(1, 3)..DisplayPoint::new(1, 3)
3912                ]
3913            );
3914        });
3915
3916        view.update(cx, |view, cx| {
3917            view.add_selection_above(&AddSelectionAbove, cx);
3918            assert_eq!(
3919                view.selection_ranges(cx),
3920                vec![
3921                    DisplayPoint::new(0, 3)..DisplayPoint::new(0, 3),
3922                    DisplayPoint::new(1, 3)..DisplayPoint::new(1, 3)
3923                ]
3924            );
3925        });
3926
3927        view.update(cx, |view, cx| {
3928            view.add_selection_below(&AddSelectionBelow, cx);
3929            assert_eq!(
3930                view.selection_ranges(cx),
3931                vec![DisplayPoint::new(1, 3)..DisplayPoint::new(1, 3)]
3932            );
3933        });
3934
3935        view.update(cx, |view, cx| {
3936            view.add_selection_below(&AddSelectionBelow, cx);
3937            assert_eq!(
3938                view.selection_ranges(cx),
3939                vec![
3940                    DisplayPoint::new(1, 3)..DisplayPoint::new(1, 3),
3941                    DisplayPoint::new(4, 3)..DisplayPoint::new(4, 3)
3942                ]
3943            );
3944        });
3945
3946        view.update(cx, |view, cx| {
3947            view.add_selection_below(&AddSelectionBelow, cx);
3948            assert_eq!(
3949                view.selection_ranges(cx),
3950                vec![
3951                    DisplayPoint::new(1, 3)..DisplayPoint::new(1, 3),
3952                    DisplayPoint::new(4, 3)..DisplayPoint::new(4, 3)
3953                ]
3954            );
3955        });
3956
3957        view.update(cx, |view, cx| {
3958            view.select_display_ranges(&[DisplayPoint::new(1, 4)..DisplayPoint::new(1, 3)], cx)
3959                .unwrap();
3960        });
3961        view.update(cx, |view, cx| {
3962            view.add_selection_below(&AddSelectionBelow, cx);
3963            assert_eq!(
3964                view.selection_ranges(cx),
3965                vec![
3966                    DisplayPoint::new(1, 4)..DisplayPoint::new(1, 3),
3967                    DisplayPoint::new(4, 4)..DisplayPoint::new(4, 3)
3968                ]
3969            );
3970        });
3971
3972        view.update(cx, |view, cx| {
3973            view.add_selection_below(&AddSelectionBelow, cx);
3974            assert_eq!(
3975                view.selection_ranges(cx),
3976                vec![
3977                    DisplayPoint::new(1, 4)..DisplayPoint::new(1, 3),
3978                    DisplayPoint::new(4, 4)..DisplayPoint::new(4, 3)
3979                ]
3980            );
3981        });
3982
3983        view.update(cx, |view, cx| {
3984            view.add_selection_above(&AddSelectionAbove, cx);
3985            assert_eq!(
3986                view.selection_ranges(cx),
3987                vec![DisplayPoint::new(1, 4)..DisplayPoint::new(1, 3)]
3988            );
3989        });
3990
3991        view.update(cx, |view, cx| {
3992            view.add_selection_above(&AddSelectionAbove, cx);
3993            assert_eq!(
3994                view.selection_ranges(cx),
3995                vec![DisplayPoint::new(1, 4)..DisplayPoint::new(1, 3)]
3996            );
3997        });
3998
3999        view.update(cx, |view, cx| {
4000            view.select_display_ranges(&[DisplayPoint::new(0, 1)..DisplayPoint::new(1, 4)], cx)
4001                .unwrap();
4002            view.add_selection_below(&AddSelectionBelow, cx);
4003            assert_eq!(
4004                view.selection_ranges(cx),
4005                vec![
4006                    DisplayPoint::new(0, 1)..DisplayPoint::new(0, 3),
4007                    DisplayPoint::new(1, 1)..DisplayPoint::new(1, 4),
4008                    DisplayPoint::new(3, 1)..DisplayPoint::new(3, 2),
4009                ]
4010            );
4011        });
4012
4013        view.update(cx, |view, cx| {
4014            view.add_selection_below(&AddSelectionBelow, cx);
4015            assert_eq!(
4016                view.selection_ranges(cx),
4017                vec![
4018                    DisplayPoint::new(0, 1)..DisplayPoint::new(0, 3),
4019                    DisplayPoint::new(1, 1)..DisplayPoint::new(1, 4),
4020                    DisplayPoint::new(3, 1)..DisplayPoint::new(3, 2),
4021                    DisplayPoint::new(4, 1)..DisplayPoint::new(4, 4),
4022                ]
4023            );
4024        });
4025
4026        view.update(cx, |view, cx| {
4027            view.add_selection_above(&AddSelectionAbove, cx);
4028            assert_eq!(
4029                view.selection_ranges(cx),
4030                vec![
4031                    DisplayPoint::new(0, 1)..DisplayPoint::new(0, 3),
4032                    DisplayPoint::new(1, 1)..DisplayPoint::new(1, 4),
4033                    DisplayPoint::new(3, 1)..DisplayPoint::new(3, 2),
4034                ]
4035            );
4036        });
4037
4038        view.update(cx, |view, cx| {
4039            view.select_display_ranges(&[DisplayPoint::new(4, 3)..DisplayPoint::new(1, 1)], cx)
4040                .unwrap();
4041        });
4042        view.update(cx, |view, cx| {
4043            view.add_selection_above(&AddSelectionAbove, cx);
4044            assert_eq!(
4045                view.selection_ranges(cx),
4046                vec![
4047                    DisplayPoint::new(0, 3)..DisplayPoint::new(0, 1),
4048                    DisplayPoint::new(1, 3)..DisplayPoint::new(1, 1),
4049                    DisplayPoint::new(3, 2)..DisplayPoint::new(3, 1),
4050                    DisplayPoint::new(4, 3)..DisplayPoint::new(4, 1),
4051                ]
4052            );
4053        });
4054
4055        view.update(cx, |view, cx| {
4056            view.add_selection_below(&AddSelectionBelow, cx);
4057            assert_eq!(
4058                view.selection_ranges(cx),
4059                vec![
4060                    DisplayPoint::new(1, 3)..DisplayPoint::new(1, 1),
4061                    DisplayPoint::new(3, 2)..DisplayPoint::new(3, 1),
4062                    DisplayPoint::new(4, 3)..DisplayPoint::new(4, 1),
4063                ]
4064            );
4065        });
4066    }
4067
4068    #[gpui::test]
4069    async fn test_select_larger_smaller_syntax_node(mut cx: gpui::TestAppContext) {
4070        let settings = cx.read(EditorSettings::test);
4071
4072        let grammar = tree_sitter_rust::language();
4073        let language = Arc::new(Language {
4074            config: LanguageConfig::default(),
4075            brackets_query: tree_sitter::Query::new(grammar, "").unwrap(),
4076            highlight_query: tree_sitter::Query::new(grammar, "").unwrap(),
4077            highlight_map: Default::default(),
4078            grammar,
4079        });
4080
4081        let text = r#"
4082            use mod1::mod2::{mod3, mod4};
4083
4084            fn fn_1(param1: bool, param2: &str) {
4085                let var1 = "text";
4086            }
4087        "#
4088        .unindent();
4089        let buffer = cx.add_model(|cx| {
4090            let history = History::new(text.into());
4091            Buffer::from_history(0, history, None, Some(language), cx)
4092        });
4093        let (_, view) = cx.add_window(|cx| build_editor(buffer, settings, cx));
4094        view.condition(&cx, |view, cx| !view.buffer.read(cx).is_parsing())
4095            .await;
4096
4097        view.update(&mut cx, |view, cx| {
4098            view.select_display_ranges(
4099                &[
4100                    DisplayPoint::new(0, 25)..DisplayPoint::new(0, 25),
4101                    DisplayPoint::new(2, 24)..DisplayPoint::new(2, 12),
4102                    DisplayPoint::new(3, 18)..DisplayPoint::new(3, 18),
4103                ],
4104                cx,
4105            )
4106            .unwrap();
4107            view.select_larger_syntax_node(&SelectLargerSyntaxNode, cx);
4108        });
4109        assert_eq!(
4110            view.update(&mut cx, |view, cx| view.selection_ranges(cx)),
4111            &[
4112                DisplayPoint::new(0, 23)..DisplayPoint::new(0, 27),
4113                DisplayPoint::new(2, 35)..DisplayPoint::new(2, 7),
4114                DisplayPoint::new(3, 15)..DisplayPoint::new(3, 21),
4115            ]
4116        );
4117
4118        view.update(&mut cx, |view, cx| {
4119            view.select_larger_syntax_node(&SelectLargerSyntaxNode, cx);
4120        });
4121        assert_eq!(
4122            view.update(&mut cx, |view, cx| view.selection_ranges(cx)),
4123            &[
4124                DisplayPoint::new(0, 16)..DisplayPoint::new(0, 28),
4125                DisplayPoint::new(4, 1)..DisplayPoint::new(2, 0),
4126            ]
4127        );
4128
4129        view.update(&mut cx, |view, cx| {
4130            view.select_larger_syntax_node(&SelectLargerSyntaxNode, cx);
4131        });
4132        assert_eq!(
4133            view.update(&mut cx, |view, cx| view.selection_ranges(cx)),
4134            &[DisplayPoint::new(5, 0)..DisplayPoint::new(0, 0)]
4135        );
4136
4137        // Trying to expand the selected syntax node one more time has no effect.
4138        view.update(&mut cx, |view, cx| {
4139            view.select_larger_syntax_node(&SelectLargerSyntaxNode, cx);
4140        });
4141        assert_eq!(
4142            view.update(&mut cx, |view, cx| view.selection_ranges(cx)),
4143            &[DisplayPoint::new(5, 0)..DisplayPoint::new(0, 0)]
4144        );
4145
4146        view.update(&mut cx, |view, cx| {
4147            view.select_smaller_syntax_node(&SelectSmallerSyntaxNode, cx);
4148        });
4149        assert_eq!(
4150            view.update(&mut cx, |view, cx| view.selection_ranges(cx)),
4151            &[
4152                DisplayPoint::new(0, 16)..DisplayPoint::new(0, 28),
4153                DisplayPoint::new(4, 1)..DisplayPoint::new(2, 0),
4154            ]
4155        );
4156
4157        view.update(&mut cx, |view, cx| {
4158            view.select_smaller_syntax_node(&SelectSmallerSyntaxNode, cx);
4159        });
4160        assert_eq!(
4161            view.update(&mut cx, |view, cx| view.selection_ranges(cx)),
4162            &[
4163                DisplayPoint::new(0, 23)..DisplayPoint::new(0, 27),
4164                DisplayPoint::new(2, 35)..DisplayPoint::new(2, 7),
4165                DisplayPoint::new(3, 15)..DisplayPoint::new(3, 21),
4166            ]
4167        );
4168
4169        view.update(&mut cx, |view, cx| {
4170            view.select_smaller_syntax_node(&SelectSmallerSyntaxNode, cx);
4171        });
4172        assert_eq!(
4173            view.update(&mut cx, |view, cx| view.selection_ranges(cx)),
4174            &[
4175                DisplayPoint::new(0, 25)..DisplayPoint::new(0, 25),
4176                DisplayPoint::new(2, 24)..DisplayPoint::new(2, 12),
4177                DisplayPoint::new(3, 18)..DisplayPoint::new(3, 18),
4178            ]
4179        );
4180
4181        // Trying to shrink the selected syntax node one more time has no effect.
4182        view.update(&mut cx, |view, cx| {
4183            view.select_smaller_syntax_node(&SelectSmallerSyntaxNode, cx);
4184        });
4185        assert_eq!(
4186            view.update(&mut cx, |view, cx| view.selection_ranges(cx)),
4187            &[
4188                DisplayPoint::new(0, 25)..DisplayPoint::new(0, 25),
4189                DisplayPoint::new(2, 24)..DisplayPoint::new(2, 12),
4190                DisplayPoint::new(3, 18)..DisplayPoint::new(3, 18),
4191            ]
4192        );
4193
4194        // Ensure that we keep expanding the selection if the larger selection starts or ends within
4195        // a fold.
4196        view.update(&mut cx, |view, cx| {
4197            view.fold_ranges(
4198                vec![
4199                    Point::new(0, 21)..Point::new(0, 24),
4200                    Point::new(3, 20)..Point::new(3, 22),
4201                ],
4202                cx,
4203            );
4204            view.select_larger_syntax_node(&SelectLargerSyntaxNode, cx);
4205        });
4206        assert_eq!(
4207            view.update(&mut cx, |view, cx| view.selection_ranges(cx)),
4208            &[
4209                DisplayPoint::new(0, 16)..DisplayPoint::new(0, 28),
4210                DisplayPoint::new(2, 35)..DisplayPoint::new(2, 7),
4211                DisplayPoint::new(3, 4)..DisplayPoint::new(3, 23),
4212            ]
4213        );
4214    }
4215
4216    impl Editor {
4217        fn selection_ranges(&self, cx: &mut MutableAppContext) -> Vec<Range<DisplayPoint>> {
4218            self.selections_in_range(
4219                self.selection_set_id,
4220                DisplayPoint::zero()..self.max_point(cx),
4221                cx,
4222            )
4223            .collect::<Vec<_>>()
4224        }
4225    }
4226
4227    fn empty_range(row: usize, column: usize) -> Range<DisplayPoint> {
4228        let point = DisplayPoint::new(row as u32, column as u32);
4229        point..point
4230    }
4231
4232    fn build_editor(
4233        buffer: ModelHandle<Buffer>,
4234        settings: EditorSettings,
4235        cx: &mut ViewContext<Editor>,
4236    ) -> Editor {
4237        Editor::for_buffer(buffer, move |_| settings.clone(), cx)
4238    }
4239}
4240
4241trait RangeExt<T> {
4242    fn sorted(&self) -> Range<T>;
4243    fn to_inclusive(&self) -> RangeInclusive<T>;
4244}
4245
4246impl<T: Ord + Clone> RangeExt<T> for Range<T> {
4247    fn sorted(&self) -> Self {
4248        cmp::min(&self.start, &self.end).clone()..cmp::max(&self.start, &self.end).clone()
4249    }
4250
4251    fn to_inclusive(&self) -> RangeInclusive<T> {
4252        self.start.clone()..=self.end.clone()
4253    }
4254}