editor.rs

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