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