editor.rs

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