lib.rs

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