lib.rs

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