editor.rs

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