editor.rs

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