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);
 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);
 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);
 946            while let Some(next_selection) = selections_iter.peek() {
 947                let (next_rows, _) = next_selection.spanned_rows(false, &display_map);
 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 (mut buffer_rows, mut display_rows) = selection.spanned_rows(false, &display_map);
1001            while let Some(next_selection) = selections.peek() {
1002                let (next_buffer_rows, next_display_rows) =
1003                    next_selection.spanned_rows(false, &display_map);
1004                if next_buffer_rows.start <= buffer_rows.end {
1005                    buffer_rows.end = next_buffer_rows.end;
1006                    display_rows.end = next_display_rows.end;
1007                    contiguous_selections.push(next_selection.point_range(buffer));
1008                    selections.next().unwrap();
1009                } else {
1010                    break;
1011                }
1012            }
1013
1014            // Cut the text from the selected rows and paste it at the start of the previous line.
1015            if display_rows.start != 0 {
1016                let start = Point::new(buffer_rows.start, 0).to_offset(buffer);
1017                let end = Point::new(buffer_rows.end - 1, buffer.line_len(buffer_rows.end - 1))
1018                    .to_offset(buffer);
1019
1020                let prev_row_display_start = DisplayPoint::new(display_rows.start - 1, 0);
1021                let prev_row_buffer_start = display_map.prev_row_boundary(prev_row_display_start).1;
1022                let prev_row_buffer_start_offset = prev_row_buffer_start.to_offset(buffer);
1023
1024                let mut text = String::new();
1025                text.extend(buffer.text_for_range(start..end));
1026                text.push('\n');
1027                edits.push((
1028                    prev_row_buffer_start_offset..prev_row_buffer_start_offset,
1029                    text,
1030                ));
1031                edits.push((start - 1..end, String::new()));
1032
1033                let row_delta = buffer_rows.start - prev_row_buffer_start.row;
1034
1035                // Move selections up.
1036                for range in &mut contiguous_selections {
1037                    range.start.row -= row_delta;
1038                    range.end.row -= row_delta;
1039                }
1040
1041                // Move folds up.
1042                old_folds.push(start..end);
1043                for fold in display_map.folds_in_range(start..end) {
1044                    let mut start = fold.start.to_point(buffer);
1045                    let mut end = fold.end.to_point(buffer);
1046                    start.row -= row_delta;
1047                    end.row -= row_delta;
1048                    new_folds.push(start..end);
1049                }
1050            }
1051
1052            new_selection_ranges.extend(contiguous_selections.drain(..));
1053        }
1054
1055        self.unfold_ranges(old_folds, cx);
1056        self.buffer.update(cx, |buffer, cx| {
1057            for (range, text) in edits.into_iter().rev() {
1058                buffer.edit(Some(range), text, cx);
1059            }
1060        });
1061        self.fold_ranges(new_folds, cx);
1062        self.select_ranges(new_selection_ranges, true, cx);
1063
1064        self.end_transaction(cx);
1065    }
1066
1067    pub fn move_line_down(&mut self, _: &(), cx: &mut ViewContext<Self>) {
1068        self.start_transaction(cx);
1069
1070        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
1071        let app = cx.as_ref();
1072        let buffer = self.buffer.read(cx);
1073
1074        let mut edits = Vec::new();
1075        let mut new_selection_ranges = Vec::new();
1076        let mut old_folds = Vec::new();
1077        let mut new_folds = Vec::new();
1078
1079        let mut selections = self.selections(app).iter().peekable();
1080        let mut contiguous_selections = Vec::new();
1081        while let Some(selection) = selections.next() {
1082            // Accumulate contiguous regions of rows that we want to move.
1083            contiguous_selections.push(selection.point_range(buffer));
1084            let (mut buffer_rows, mut display_rows) = selection.spanned_rows(false, &display_map);
1085            while let Some(next_selection) = selections.peek() {
1086                let (next_buffer_rows, next_display_rows) =
1087                    next_selection.spanned_rows(false, &display_map);
1088                if next_buffer_rows.start <= buffer_rows.end {
1089                    buffer_rows.end = next_buffer_rows.end;
1090                    display_rows.end = next_display_rows.end;
1091                    contiguous_selections.push(next_selection.point_range(buffer));
1092                    selections.next().unwrap();
1093                } else {
1094                    break;
1095                }
1096            }
1097
1098            // Cut the text from the selected rows and paste it at the end of the next line.
1099            if display_rows.end <= display_map.max_point().row() {
1100                let start = Point::new(buffer_rows.start, 0).to_offset(buffer);
1101                let end = Point::new(buffer_rows.end - 1, buffer.line_len(buffer_rows.end - 1))
1102                    .to_offset(buffer);
1103
1104                let next_row_display_end =
1105                    DisplayPoint::new(display_rows.end, display_map.line_len(display_rows.end));
1106                let next_row_buffer_end = display_map.next_row_boundary(next_row_display_end).1;
1107                let next_row_buffer_end_offset = next_row_buffer_end.to_offset(buffer);
1108
1109                let mut text = String::new();
1110                text.push('\n');
1111                text.extend(buffer.text_for_range(start..end));
1112                edits.push((start..end + 1, String::new()));
1113                edits.push((next_row_buffer_end_offset..next_row_buffer_end_offset, text));
1114
1115                let row_delta = next_row_buffer_end.row - buffer_rows.end + 1;
1116
1117                // Move selections down.
1118                for range in &mut contiguous_selections {
1119                    range.start.row += row_delta;
1120                    range.end.row += row_delta;
1121                }
1122
1123                // Move folds down.
1124                old_folds.push(start..end);
1125                for fold in display_map.folds_in_range(start..end) {
1126                    let mut start = fold.start.to_point(buffer);
1127                    let mut end = fold.end.to_point(buffer);
1128                    start.row += row_delta;
1129                    end.row += row_delta;
1130                    new_folds.push(start..end);
1131                }
1132            }
1133
1134            new_selection_ranges.extend(contiguous_selections.drain(..));
1135        }
1136
1137        self.unfold_ranges(old_folds, cx);
1138        self.buffer.update(cx, |buffer, cx| {
1139            for (range, text) in edits.into_iter().rev() {
1140                buffer.edit(Some(range), text, cx);
1141            }
1142        });
1143        self.fold_ranges(new_folds, cx);
1144        self.select_ranges(new_selection_ranges, true, cx);
1145
1146        self.end_transaction(cx);
1147    }
1148
1149    pub fn cut(&mut self, _: &(), cx: &mut ViewContext<Self>) {
1150        self.start_transaction(cx);
1151        let mut text = String::new();
1152        let mut selections = self.selections(cx.as_ref()).to_vec();
1153        let mut clipboard_selections = Vec::with_capacity(selections.len());
1154        {
1155            let buffer = self.buffer.read(cx);
1156            let max_point = buffer.max_point();
1157            for selection in &mut selections {
1158                let mut start = selection.start.to_point(buffer);
1159                let mut end = selection.end.to_point(buffer);
1160                let is_entire_line = start == end;
1161                if is_entire_line {
1162                    start = Point::new(start.row, 0);
1163                    end = cmp::min(max_point, Point::new(start.row + 1, 0));
1164                    selection.start = buffer.anchor_before(start);
1165                    selection.end = buffer.anchor_before(end);
1166                }
1167                let mut len = 0;
1168                for chunk in buffer.text_for_range(start..end) {
1169                    text.push_str(chunk);
1170                    len += chunk.len();
1171                }
1172                clipboard_selections.push(ClipboardSelection {
1173                    len,
1174                    is_entire_line,
1175                });
1176            }
1177        }
1178        self.update_selections(selections, true, cx);
1179        self.insert(&String::new(), cx);
1180        self.end_transaction(cx);
1181
1182        cx.as_mut()
1183            .write_to_clipboard(ClipboardItem::new(text).with_metadata(clipboard_selections));
1184    }
1185
1186    pub fn copy(&mut self, _: &(), cx: &mut ViewContext<Self>) {
1187        let buffer = self.buffer.read(cx);
1188        let max_point = buffer.max_point();
1189        let mut text = String::new();
1190        let selections = self.selections(cx.as_ref());
1191        let mut clipboard_selections = Vec::with_capacity(selections.len());
1192        for selection in selections {
1193            let mut start = selection.start.to_point(buffer);
1194            let mut end = selection.end.to_point(buffer);
1195            let is_entire_line = start == end;
1196            if is_entire_line {
1197                start = Point::new(start.row, 0);
1198                end = cmp::min(max_point, Point::new(start.row + 1, 0));
1199            }
1200            let mut len = 0;
1201            for chunk in buffer.text_for_range(start..end) {
1202                text.push_str(chunk);
1203                len += chunk.len();
1204            }
1205            clipboard_selections.push(ClipboardSelection {
1206                len,
1207                is_entire_line,
1208            });
1209        }
1210
1211        cx.as_mut()
1212            .write_to_clipboard(ClipboardItem::new(text).with_metadata(clipboard_selections));
1213    }
1214
1215    pub fn paste(&mut self, _: &(), cx: &mut ViewContext<Self>) {
1216        if let Some(item) = cx.as_mut().read_from_clipboard() {
1217            let clipboard_text = item.text();
1218            if let Some(mut clipboard_selections) = item.metadata::<Vec<ClipboardSelection>>() {
1219                let selections = self.selections(cx.as_ref()).to_vec();
1220                if clipboard_selections.len() != selections.len() {
1221                    let merged_selection = ClipboardSelection {
1222                        len: clipboard_selections.iter().map(|s| s.len).sum(),
1223                        is_entire_line: clipboard_selections.iter().all(|s| s.is_entire_line),
1224                    };
1225                    clipboard_selections.clear();
1226                    clipboard_selections.push(merged_selection);
1227                }
1228
1229                self.start_transaction(cx);
1230                let mut new_selections = Vec::with_capacity(selections.len());
1231                let mut clipboard_chars = clipboard_text.chars().cycle();
1232                for (selection, clipboard_selection) in
1233                    selections.iter().zip(clipboard_selections.iter().cycle())
1234                {
1235                    let to_insert =
1236                        String::from_iter(clipboard_chars.by_ref().take(clipboard_selection.len));
1237
1238                    self.buffer.update(cx, |buffer, cx| {
1239                        let selection_start = selection.start.to_point(&*buffer);
1240                        let selection_end = selection.end.to_point(&*buffer);
1241
1242                        // If the corresponding selection was empty when this slice of the
1243                        // clipboard text was written, then the entire line containing the
1244                        // selection was copied. If this selection is also currently empty,
1245                        // then paste the line before the current line of the buffer.
1246                        let new_selection_start = selection.end.bias_right(buffer);
1247                        if selection_start == selection_end && clipboard_selection.is_entire_line {
1248                            let line_start = Point::new(selection_start.row, 0);
1249                            buffer.edit(Some(line_start..line_start), to_insert, cx);
1250                        } else {
1251                            buffer.edit(Some(&selection.start..&selection.end), to_insert, cx);
1252                        };
1253
1254                        let new_selection_start = new_selection_start.bias_left(buffer);
1255                        new_selections.push(Selection {
1256                            id: selection.id,
1257                            start: new_selection_start.clone(),
1258                            end: new_selection_start,
1259                            reversed: false,
1260                            goal: SelectionGoal::None,
1261                        });
1262                    });
1263                }
1264                self.update_selections(new_selections, true, cx);
1265                self.end_transaction(cx);
1266            } else {
1267                self.insert(clipboard_text, cx);
1268            }
1269        }
1270    }
1271
1272    pub fn undo(&mut self, _: &(), cx: &mut ViewContext<Self>) {
1273        self.buffer.update(cx, |buffer, cx| buffer.undo(cx));
1274    }
1275
1276    pub fn redo(&mut self, _: &(), cx: &mut ViewContext<Self>) {
1277        self.buffer.update(cx, |buffer, cx| buffer.redo(cx));
1278    }
1279
1280    pub fn move_left(&mut self, _: &(), cx: &mut ViewContext<Self>) {
1281        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
1282        let app = cx.as_ref();
1283        let mut selections = self.selections(app).to_vec();
1284        {
1285            for selection in &mut selections {
1286                let start = selection.start.to_display_point(&display_map, Bias::Left);
1287                let end = selection.end.to_display_point(&display_map, Bias::Left);
1288
1289                if start != end {
1290                    selection.end = selection.start.clone();
1291                } else {
1292                    let cursor = display_map
1293                        .anchor_before(movement::left(&display_map, start).unwrap(), Bias::Left);
1294                    selection.start = cursor.clone();
1295                    selection.end = cursor;
1296                }
1297                selection.reversed = false;
1298                selection.goal = SelectionGoal::None;
1299            }
1300        }
1301        self.update_selections(selections, true, cx);
1302    }
1303
1304    pub fn select_left(&mut self, _: &(), cx: &mut ViewContext<Self>) {
1305        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
1306        let mut selections = self.selections(cx.as_ref()).to_vec();
1307        {
1308            let buffer = self.buffer.read(cx);
1309            for selection in &mut selections {
1310                let head = selection.head().to_display_point(&display_map, Bias::Left);
1311                let cursor = display_map
1312                    .anchor_before(movement::left(&display_map, head).unwrap(), Bias::Left);
1313                selection.set_head(&buffer, cursor);
1314                selection.goal = SelectionGoal::None;
1315            }
1316        }
1317        self.update_selections(selections, true, cx);
1318    }
1319
1320    pub fn move_right(&mut self, _: &(), cx: &mut ViewContext<Self>) {
1321        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
1322        let mut selections = self.selections(cx.as_ref()).to_vec();
1323        {
1324            for selection in &mut selections {
1325                let start = selection.start.to_display_point(&display_map, Bias::Left);
1326                let end = selection.end.to_display_point(&display_map, Bias::Left);
1327
1328                if start != end {
1329                    selection.start = selection.end.clone();
1330                } else {
1331                    let cursor = display_map
1332                        .anchor_before(movement::right(&display_map, end).unwrap(), Bias::Right);
1333                    selection.start = cursor.clone();
1334                    selection.end = cursor;
1335                }
1336                selection.reversed = false;
1337                selection.goal = SelectionGoal::None;
1338            }
1339        }
1340        self.update_selections(selections, true, cx);
1341    }
1342
1343    pub fn select_right(&mut self, _: &(), cx: &mut ViewContext<Self>) {
1344        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
1345        let mut selections = self.selections(cx.as_ref()).to_vec();
1346        {
1347            let app = cx.as_ref();
1348            let buffer = self.buffer.read(app);
1349            for selection in &mut selections {
1350                let head = selection.head().to_display_point(&display_map, Bias::Left);
1351                let cursor = display_map
1352                    .anchor_before(movement::right(&display_map, head).unwrap(), Bias::Right);
1353                selection.set_head(&buffer, cursor);
1354                selection.goal = SelectionGoal::None;
1355            }
1356        }
1357        self.update_selections(selections, true, cx);
1358    }
1359
1360    pub fn move_up(&mut self, _: &(), cx: &mut ViewContext<Self>) {
1361        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
1362        if self.single_line {
1363            cx.propagate_action();
1364        } else {
1365            let mut selections = self.selections(cx.as_ref()).to_vec();
1366            {
1367                for selection in &mut selections {
1368                    let start = selection.start.to_display_point(&display_map, Bias::Left);
1369                    let end = selection.end.to_display_point(&display_map, Bias::Left);
1370                    if start != end {
1371                        selection.goal = SelectionGoal::None;
1372                    }
1373
1374                    let (start, goal) = movement::up(&display_map, start, selection.goal).unwrap();
1375                    let cursor = display_map.anchor_before(start, Bias::Left);
1376                    selection.start = cursor.clone();
1377                    selection.end = cursor;
1378                    selection.goal = goal;
1379                    selection.reversed = false;
1380                }
1381            }
1382            self.update_selections(selections, true, cx);
1383        }
1384    }
1385
1386    pub fn select_up(&mut self, _: &(), cx: &mut ViewContext<Self>) {
1387        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
1388        let mut selections = self.selections(cx.as_ref()).to_vec();
1389        {
1390            let app = cx.as_ref();
1391            let buffer = self.buffer.read(app);
1392            for selection in &mut selections {
1393                let head = selection.head().to_display_point(&display_map, Bias::Left);
1394                let (head, goal) = movement::up(&display_map, head, selection.goal).unwrap();
1395                selection.set_head(&buffer, display_map.anchor_before(head, Bias::Left));
1396                selection.goal = goal;
1397            }
1398        }
1399        self.update_selections(selections, true, cx);
1400    }
1401
1402    pub fn move_down(&mut self, _: &(), cx: &mut ViewContext<Self>) {
1403        if self.single_line {
1404            cx.propagate_action();
1405        } else {
1406            let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
1407            let mut selections = self.selections(cx.as_ref()).to_vec();
1408            {
1409                for selection in &mut selections {
1410                    let start = selection.start.to_display_point(&display_map, Bias::Left);
1411                    let end = selection.end.to_display_point(&display_map, Bias::Left);
1412                    if start != end {
1413                        selection.goal = SelectionGoal::None;
1414                    }
1415
1416                    let (start, goal) = movement::down(&display_map, end, selection.goal).unwrap();
1417                    let cursor = display_map.anchor_before(start, Bias::Right);
1418                    selection.start = cursor.clone();
1419                    selection.end = cursor;
1420                    selection.goal = goal;
1421                    selection.reversed = false;
1422                }
1423            }
1424            self.update_selections(selections, true, cx);
1425        }
1426    }
1427
1428    pub fn select_down(&mut self, _: &(), cx: &mut ViewContext<Self>) {
1429        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
1430        let mut selections = self.selections(cx).to_vec();
1431        {
1432            let app = cx.as_ref();
1433            let buffer = self.buffer.read(app);
1434            for selection in &mut selections {
1435                let head = selection.head().to_display_point(&display_map, Bias::Left);
1436                let (head, goal) = movement::down(&display_map, head, selection.goal).unwrap();
1437                selection.set_head(&buffer, display_map.anchor_before(head, Bias::Right));
1438                selection.goal = goal;
1439            }
1440        }
1441        self.update_selections(selections, true, cx);
1442    }
1443
1444    pub fn move_to_previous_word_boundary(&mut self, _: &(), cx: &mut ViewContext<Self>) {
1445        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
1446        let mut selections = self.selections(cx).to_vec();
1447        {
1448            for selection in &mut selections {
1449                let head = selection.head().to_display_point(&display_map, Bias::Left);
1450                let new_head = movement::prev_word_boundary(&display_map, head).unwrap();
1451                let anchor = display_map.anchor_before(new_head, Bias::Left);
1452                selection.start = anchor.clone();
1453                selection.end = anchor;
1454                selection.reversed = false;
1455                selection.goal = SelectionGoal::None;
1456            }
1457        }
1458        self.update_selections(selections, true, cx);
1459    }
1460
1461    pub fn select_to_previous_word_boundary(&mut self, _: &(), cx: &mut ViewContext<Self>) {
1462        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
1463        let mut selections = self.selections(cx).to_vec();
1464        {
1465            let buffer = self.buffer.read(cx);
1466            for selection in &mut selections {
1467                let head = selection.head().to_display_point(&display_map, Bias::Left);
1468                let new_head = movement::prev_word_boundary(&display_map, head).unwrap();
1469                let anchor = display_map.anchor_before(new_head, Bias::Left);
1470                selection.set_head(buffer, anchor);
1471                selection.goal = SelectionGoal::None;
1472            }
1473        }
1474        self.update_selections(selections, true, cx);
1475    }
1476
1477    pub fn delete_to_previous_word_boundary(&mut self, _: &(), cx: &mut ViewContext<Self>) {
1478        self.start_transaction(cx);
1479        self.select_to_previous_word_boundary(&(), cx);
1480        self.backspace(&(), cx);
1481        self.end_transaction(cx);
1482    }
1483
1484    pub fn move_to_next_word_boundary(&mut self, _: &(), cx: &mut ViewContext<Self>) {
1485        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
1486        let mut selections = self.selections(cx).to_vec();
1487        {
1488            for selection in &mut selections {
1489                let head = selection.head().to_display_point(&display_map, Bias::Left);
1490                let new_head = movement::next_word_boundary(&display_map, head).unwrap();
1491                let anchor = display_map.anchor_before(new_head, Bias::Left);
1492                selection.start = anchor.clone();
1493                selection.end = anchor;
1494                selection.reversed = false;
1495                selection.goal = SelectionGoal::None;
1496            }
1497        }
1498        self.update_selections(selections, true, cx);
1499    }
1500
1501    pub fn select_to_next_word_boundary(&mut self, _: &(), cx: &mut ViewContext<Self>) {
1502        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
1503        let mut selections = self.selections(cx).to_vec();
1504        {
1505            let buffer = self.buffer.read(cx);
1506            for selection in &mut selections {
1507                let head = selection.head().to_display_point(&display_map, Bias::Left);
1508                let new_head = movement::next_word_boundary(&display_map, head).unwrap();
1509                let anchor = display_map.anchor_before(new_head, Bias::Left);
1510                selection.set_head(buffer, anchor);
1511                selection.goal = SelectionGoal::None;
1512            }
1513        }
1514        self.update_selections(selections, true, cx);
1515    }
1516
1517    pub fn delete_to_next_word_boundary(&mut self, _: &(), cx: &mut ViewContext<Self>) {
1518        self.start_transaction(cx);
1519        self.select_to_next_word_boundary(&(), cx);
1520        self.delete(&(), cx);
1521        self.end_transaction(cx);
1522    }
1523
1524    pub fn move_to_beginning_of_line(&mut self, _: &(), cx: &mut ViewContext<Self>) {
1525        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
1526        let mut selections = self.selections(cx).to_vec();
1527        {
1528            for selection in &mut selections {
1529                let head = selection.head().to_display_point(&display_map, Bias::Left);
1530                let new_head = movement::line_beginning(&display_map, head, true).unwrap();
1531                let anchor = display_map.anchor_before(new_head, Bias::Left);
1532                selection.start = anchor.clone();
1533                selection.end = anchor;
1534                selection.reversed = false;
1535                selection.goal = SelectionGoal::None;
1536            }
1537        }
1538        self.update_selections(selections, true, cx);
1539    }
1540
1541    pub fn select_to_beginning_of_line(
1542        &mut self,
1543        toggle_indent: &bool,
1544        cx: &mut ViewContext<Self>,
1545    ) {
1546        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
1547        let mut selections = self.selections(cx).to_vec();
1548        {
1549            let buffer = self.buffer.read(cx);
1550            for selection in &mut selections {
1551                let head = selection.head().to_display_point(&display_map, Bias::Left);
1552                let new_head =
1553                    movement::line_beginning(&display_map, head, *toggle_indent).unwrap();
1554                let anchor = display_map.anchor_before(new_head, Bias::Left);
1555                selection.set_head(buffer, anchor);
1556                selection.goal = SelectionGoal::None;
1557            }
1558        }
1559        self.update_selections(selections, true, cx);
1560    }
1561
1562    pub fn delete_to_beginning_of_line(&mut self, _: &(), cx: &mut ViewContext<Self>) {
1563        self.start_transaction(cx);
1564        self.select_to_beginning_of_line(&false, cx);
1565        self.backspace(&(), cx);
1566        self.end_transaction(cx);
1567    }
1568
1569    pub fn move_to_end_of_line(&mut self, _: &(), cx: &mut ViewContext<Self>) {
1570        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
1571        let mut selections = self.selections(cx).to_vec();
1572        {
1573            for selection in &mut selections {
1574                let head = selection.head().to_display_point(&display_map, Bias::Left);
1575                let new_head = movement::line_end(&display_map, head).unwrap();
1576                let anchor = display_map.anchor_before(new_head, Bias::Left);
1577                selection.start = anchor.clone();
1578                selection.end = anchor;
1579                selection.reversed = false;
1580                selection.goal = SelectionGoal::None;
1581            }
1582        }
1583        self.update_selections(selections, true, cx);
1584    }
1585
1586    pub fn select_to_end_of_line(&mut self, _: &(), cx: &mut ViewContext<Self>) {
1587        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
1588        let mut selections = self.selections(cx).to_vec();
1589        {
1590            let buffer = self.buffer.read(cx);
1591            for selection in &mut selections {
1592                let head = selection.head().to_display_point(&display_map, Bias::Left);
1593                let new_head = movement::line_end(&display_map, head).unwrap();
1594                let anchor = display_map.anchor_before(new_head, Bias::Left);
1595                selection.set_head(buffer, anchor);
1596                selection.goal = SelectionGoal::None;
1597            }
1598        }
1599        self.update_selections(selections, true, cx);
1600    }
1601
1602    pub fn delete_to_end_of_line(&mut self, _: &(), cx: &mut ViewContext<Self>) {
1603        self.start_transaction(cx);
1604        self.select_to_end_of_line(&(), cx);
1605        self.delete(&(), cx);
1606        self.end_transaction(cx);
1607    }
1608
1609    pub fn cut_to_end_of_line(&mut self, _: &(), cx: &mut ViewContext<Self>) {
1610        self.start_transaction(cx);
1611        self.select_to_end_of_line(&(), cx);
1612        self.cut(&(), cx);
1613        self.end_transaction(cx);
1614    }
1615
1616    pub fn move_to_beginning(&mut self, _: &(), cx: &mut ViewContext<Self>) {
1617        let buffer = self.buffer.read(cx);
1618        let cursor = buffer.anchor_before(Point::new(0, 0));
1619        let selection = Selection {
1620            id: post_inc(&mut self.next_selection_id),
1621            start: cursor.clone(),
1622            end: cursor,
1623            reversed: false,
1624            goal: SelectionGoal::None,
1625        };
1626        self.update_selections(vec![selection], true, cx);
1627    }
1628
1629    pub fn select_to_beginning(&mut self, _: &(), cx: &mut ViewContext<Self>) {
1630        let mut selection = self.selections(cx.as_ref()).last().unwrap().clone();
1631        selection.set_head(self.buffer.read(cx), Anchor::min());
1632        self.update_selections(vec![selection], true, cx);
1633    }
1634
1635    pub fn move_to_end(&mut self, _: &(), cx: &mut ViewContext<Self>) {
1636        let buffer = self.buffer.read(cx);
1637        let cursor = buffer.anchor_before(buffer.max_point());
1638        let selection = Selection {
1639            id: post_inc(&mut self.next_selection_id),
1640            start: cursor.clone(),
1641            end: cursor,
1642            reversed: false,
1643            goal: SelectionGoal::None,
1644        };
1645        self.update_selections(vec![selection], true, cx);
1646    }
1647
1648    pub fn select_to_end(&mut self, _: &(), cx: &mut ViewContext<Self>) {
1649        let mut selection = self.selections(cx.as_ref()).last().unwrap().clone();
1650        selection.set_head(self.buffer.read(cx), Anchor::max());
1651        self.update_selections(vec![selection], true, cx);
1652    }
1653
1654    pub fn select_all(&mut self, _: &(), cx: &mut ViewContext<Self>) {
1655        let selection = Selection {
1656            id: post_inc(&mut self.next_selection_id),
1657            start: Anchor::min(),
1658            end: Anchor::max(),
1659            reversed: false,
1660            goal: SelectionGoal::None,
1661        };
1662        self.update_selections(vec![selection], false, cx);
1663    }
1664
1665    pub fn select_line(&mut self, _: &(), cx: &mut ViewContext<Self>) {
1666        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
1667        let buffer = self.buffer.read(cx);
1668        let mut selections = self.selections(cx).to_vec();
1669        let max_point = buffer.max_point();
1670        for selection in &mut selections {
1671            let (rows, _) = selection.spanned_rows(true, &display_map);
1672            selection.start = buffer.anchor_before(Point::new(rows.start, 0));
1673            selection.end = buffer.anchor_before(cmp::min(max_point, Point::new(rows.end, 0)));
1674            selection.reversed = false;
1675        }
1676        self.update_selections(selections, true, cx);
1677    }
1678
1679    pub fn split_selection_into_lines(&mut self, _: &(), cx: &mut ViewContext<Self>) {
1680        let app = cx.as_ref();
1681        let buffer = self.buffer.read(app);
1682
1683        let mut to_unfold = Vec::new();
1684        let mut new_selections = Vec::new();
1685        for selection in self.selections(app) {
1686            let range = selection.point_range(buffer).sorted();
1687            if range.start.row != range.end.row {
1688                new_selections.push(Selection {
1689                    id: post_inc(&mut self.next_selection_id),
1690                    start: selection.start.clone(),
1691                    end: selection.start.clone(),
1692                    reversed: false,
1693                    goal: SelectionGoal::None,
1694                });
1695            }
1696            for row in range.start.row + 1..range.end.row {
1697                let cursor = buffer.anchor_before(Point::new(row, buffer.line_len(row)));
1698                new_selections.push(Selection {
1699                    id: post_inc(&mut self.next_selection_id),
1700                    start: cursor.clone(),
1701                    end: cursor,
1702                    reversed: false,
1703                    goal: SelectionGoal::None,
1704                });
1705            }
1706            new_selections.push(Selection {
1707                id: selection.id,
1708                start: selection.end.clone(),
1709                end: selection.end.clone(),
1710                reversed: false,
1711                goal: SelectionGoal::None,
1712            });
1713            to_unfold.push(range);
1714        }
1715        self.unfold_ranges(to_unfold, cx);
1716        self.update_selections(new_selections, true, cx);
1717    }
1718
1719    pub fn add_selection_above(&mut self, _: &(), cx: &mut ViewContext<Self>) {
1720        self.add_selection(true, cx);
1721    }
1722
1723    pub fn add_selection_below(&mut self, _: &(), cx: &mut ViewContext<Self>) {
1724        self.add_selection(false, cx);
1725    }
1726
1727    fn add_selection(&mut self, above: bool, cx: &mut ViewContext<Self>) {
1728        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
1729        let mut selections = self.selections(cx).to_vec();
1730        let mut state = self.add_selections_state.take().unwrap_or_else(|| {
1731            let oldest_selection = selections.iter().min_by_key(|s| s.id).unwrap().clone();
1732            let range = oldest_selection.display_range(&display_map).sorted();
1733            let columns = cmp::min(range.start.column(), range.end.column())
1734                ..cmp::max(range.start.column(), range.end.column());
1735
1736            selections.clear();
1737            let mut stack = Vec::new();
1738            for row in range.start.row()..=range.end.row() {
1739                if let Some(selection) = self.build_columnar_selection(
1740                    &display_map,
1741                    row,
1742                    &columns,
1743                    oldest_selection.reversed,
1744                ) {
1745                    stack.push(selection.id);
1746                    selections.push(selection);
1747                }
1748            }
1749
1750            if above {
1751                stack.reverse();
1752            }
1753
1754            AddSelectionsState { above, stack }
1755        });
1756
1757        let last_added_selection = *state.stack.last().unwrap();
1758        let mut new_selections = Vec::new();
1759        if above == state.above {
1760            let end_row = if above {
1761                0
1762            } else {
1763                display_map.max_point().row()
1764            };
1765
1766            'outer: for selection in selections {
1767                if selection.id == last_added_selection {
1768                    let range = selection.display_range(&display_map).sorted();
1769                    debug_assert_eq!(range.start.row(), range.end.row());
1770                    let mut row = range.start.row();
1771                    let columns = if let SelectionGoal::ColumnRange { start, end } = selection.goal
1772                    {
1773                        start..end
1774                    } else {
1775                        cmp::min(range.start.column(), range.end.column())
1776                            ..cmp::max(range.start.column(), range.end.column())
1777                    };
1778
1779                    while row != end_row {
1780                        if above {
1781                            row -= 1;
1782                        } else {
1783                            row += 1;
1784                        }
1785
1786                        if let Some(new_selection) = self.build_columnar_selection(
1787                            &display_map,
1788                            row,
1789                            &columns,
1790                            selection.reversed,
1791                        ) {
1792                            state.stack.push(new_selection.id);
1793                            if above {
1794                                new_selections.push(new_selection);
1795                                new_selections.push(selection);
1796                            } else {
1797                                new_selections.push(selection);
1798                                new_selections.push(new_selection);
1799                            }
1800
1801                            continue 'outer;
1802                        }
1803                    }
1804                }
1805
1806                new_selections.push(selection);
1807            }
1808        } else {
1809            new_selections = selections;
1810            new_selections.retain(|s| s.id != last_added_selection);
1811            state.stack.pop();
1812        }
1813
1814        self.update_selections(new_selections, true, cx);
1815        if state.stack.len() > 1 {
1816            self.add_selections_state = Some(state);
1817        }
1818    }
1819
1820    pub fn select_larger_syntax_node(&mut self, _: &(), cx: &mut ViewContext<Self>) {
1821        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
1822        let buffer = self.buffer.read(cx);
1823
1824        let mut stack = mem::take(&mut self.select_larger_syntax_node_stack);
1825        let mut selected_larger_node = false;
1826        let old_selections = self.selections(cx).to_vec();
1827        let mut new_selection_ranges = Vec::new();
1828        for selection in &old_selections {
1829            let old_range = selection.start.to_offset(buffer)..selection.end.to_offset(buffer);
1830            let mut new_range = old_range.clone();
1831            while let Some(containing_range) = buffer.range_for_syntax_ancestor(new_range.clone()) {
1832                new_range = containing_range;
1833                if !display_map.intersects_fold(new_range.start)
1834                    && !display_map.intersects_fold(new_range.end)
1835                {
1836                    break;
1837                }
1838            }
1839
1840            selected_larger_node |= new_range != old_range;
1841            new_selection_ranges.push((selection.id, new_range, selection.reversed));
1842        }
1843
1844        if selected_larger_node {
1845            stack.push(old_selections);
1846            new_selection_ranges.sort_unstable_by_key(|(_, range, _)| range.start.clone());
1847            let new_selections = new_selection_ranges
1848                .into_iter()
1849                .map(|(id, range, reversed)| Selection {
1850                    id,
1851                    start: buffer.anchor_before(range.start),
1852                    end: buffer.anchor_before(range.end),
1853                    reversed,
1854                    goal: SelectionGoal::None,
1855                })
1856                .collect();
1857            self.update_selections(new_selections, true, cx);
1858        }
1859        self.select_larger_syntax_node_stack = stack;
1860    }
1861
1862    pub fn select_smaller_syntax_node(&mut self, _: &(), cx: &mut ViewContext<Self>) {
1863        let mut stack = mem::take(&mut self.select_larger_syntax_node_stack);
1864        if let Some(selections) = stack.pop() {
1865            self.update_selections(selections, true, cx);
1866        }
1867        self.select_larger_syntax_node_stack = stack;
1868    }
1869
1870    pub fn move_to_enclosing_bracket(&mut self, _: &(), cx: &mut ViewContext<Self>) {
1871        let buffer = self.buffer.read(cx.as_ref());
1872        let mut selections = self.selections(cx.as_ref()).to_vec();
1873        for selection in &mut selections {
1874            let selection_range = selection.offset_range(buffer);
1875            if let Some((open_range, close_range)) =
1876                buffer.enclosing_bracket_ranges(selection_range.clone())
1877            {
1878                let close_range = close_range.to_inclusive();
1879                let destination = if close_range.contains(&selection_range.start)
1880                    && close_range.contains(&selection_range.end)
1881                {
1882                    open_range.end
1883                } else {
1884                    *close_range.start()
1885                };
1886                selection.start = buffer.anchor_before(destination);
1887                selection.end = selection.start.clone();
1888            }
1889        }
1890
1891        self.update_selections(selections, true, cx);
1892    }
1893
1894    fn build_columnar_selection(
1895        &mut self,
1896        display_map: &DisplayMapSnapshot,
1897        row: u32,
1898        columns: &Range<u32>,
1899        reversed: bool,
1900    ) -> Option<Selection> {
1901        let is_empty = columns.start == columns.end;
1902        let line_len = display_map.line_len(row);
1903        if columns.start < line_len || (is_empty && columns.start == line_len) {
1904            let start = DisplayPoint::new(row, columns.start);
1905            let end = DisplayPoint::new(row, cmp::min(columns.end, line_len));
1906            Some(Selection {
1907                id: post_inc(&mut self.next_selection_id),
1908                start: display_map.anchor_before(start, Bias::Left),
1909                end: display_map.anchor_before(end, Bias::Left),
1910                reversed,
1911                goal: SelectionGoal::ColumnRange {
1912                    start: columns.start,
1913                    end: columns.end,
1914                },
1915            })
1916        } else {
1917            None
1918        }
1919    }
1920
1921    pub fn active_selection_sets<'a>(
1922        &'a self,
1923        cx: &'a AppContext,
1924    ) -> impl 'a + Iterator<Item = SelectionSetId> {
1925        self.buffer
1926            .read(cx)
1927            .selection_sets()
1928            .filter(|(_, set)| set.active)
1929            .map(|(set_id, _)| *set_id)
1930    }
1931
1932    pub fn selections_in_range<'a>(
1933        &'a self,
1934        set_id: SelectionSetId,
1935        range: Range<DisplayPoint>,
1936        cx: &'a mut MutableAppContext,
1937    ) -> impl 'a + Iterator<Item = Range<DisplayPoint>> {
1938        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
1939        let buffer = self.buffer.read(cx);
1940        let selections = &buffer.selection_set(set_id).unwrap().selections;
1941        let start = display_map.anchor_before(range.start, Bias::Left);
1942        let start_index = self.selection_insertion_index(selections, &start, cx);
1943        let pending_selection = if set_id.replica_id == self.buffer.read(cx).replica_id() {
1944            self.pending_selection.as_ref().and_then(|s| {
1945                let selection_range = s.display_range(&display_map);
1946                if selection_range.start <= range.end || selection_range.end <= range.end {
1947                    Some(selection_range)
1948                } else {
1949                    None
1950                }
1951            })
1952        } else {
1953            None
1954        };
1955        selections[start_index..]
1956            .iter()
1957            .map(move |s| s.display_range(&display_map))
1958            .take_while(move |r| r.start <= range.end || r.end <= range.end)
1959            .chain(pending_selection)
1960    }
1961
1962    fn selection_insertion_index(
1963        &self,
1964        selections: &[Selection],
1965        start: &Anchor,
1966        cx: &AppContext,
1967    ) -> usize {
1968        let buffer = self.buffer.read(cx);
1969        match selections.binary_search_by(|probe| probe.start.cmp(&start, buffer).unwrap()) {
1970            Ok(index) => index,
1971            Err(index) => {
1972                if index > 0
1973                    && selections[index - 1].end.cmp(&start, buffer).unwrap() == Ordering::Greater
1974                {
1975                    index - 1
1976                } else {
1977                    index
1978                }
1979            }
1980        }
1981    }
1982
1983    fn selections<'a>(&self, cx: &'a AppContext) -> &'a [Selection] {
1984        let buffer = self.buffer.read(cx);
1985        &buffer
1986            .selection_set(self.selection_set_id)
1987            .unwrap()
1988            .selections
1989    }
1990
1991    fn update_selections(
1992        &mut self,
1993        mut selections: Vec<Selection>,
1994        autoscroll: bool,
1995        cx: &mut ViewContext<Self>,
1996    ) {
1997        // Merge overlapping selections.
1998        let buffer = self.buffer.read(cx);
1999        let mut i = 1;
2000        while i < selections.len() {
2001            if selections[i - 1]
2002                .end
2003                .cmp(&selections[i].start, buffer)
2004                .unwrap()
2005                >= Ordering::Equal
2006            {
2007                let removed = selections.remove(i);
2008                if removed.start.cmp(&selections[i - 1].start, buffer).unwrap() < Ordering::Equal {
2009                    selections[i - 1].start = removed.start;
2010                }
2011                if removed.end.cmp(&selections[i - 1].end, buffer).unwrap() > Ordering::Equal {
2012                    selections[i - 1].end = removed.end;
2013                }
2014            } else {
2015                i += 1;
2016            }
2017        }
2018
2019        self.buffer.update(cx, |buffer, cx| {
2020            buffer
2021                .update_selection_set(self.selection_set_id, selections, cx)
2022                .unwrap();
2023        });
2024        self.pause_cursor_blinking(cx);
2025
2026        if autoscroll {
2027            self.autoscroll_requested = true;
2028            cx.notify();
2029        }
2030
2031        self.add_selections_state = None;
2032        self.select_larger_syntax_node_stack.clear();
2033    }
2034
2035    fn start_transaction(&self, cx: &mut ViewContext<Self>) {
2036        self.buffer.update(cx, |buffer, _| {
2037            buffer
2038                .start_transaction(Some(self.selection_set_id))
2039                .unwrap()
2040        });
2041    }
2042
2043    fn end_transaction(&self, cx: &mut ViewContext<Self>) {
2044        self.buffer.update(cx, |buffer, cx| {
2045            buffer
2046                .end_transaction(Some(self.selection_set_id), cx)
2047                .unwrap()
2048        });
2049    }
2050
2051    pub fn page_up(&mut self, _: &(), _: &mut ViewContext<Self>) {
2052        log::info!("BufferView::page_up");
2053    }
2054
2055    pub fn page_down(&mut self, _: &(), _: &mut ViewContext<Self>) {
2056        log::info!("BufferView::page_down");
2057    }
2058
2059    pub fn fold(&mut self, _: &(), cx: &mut ViewContext<Self>) {
2060        let mut fold_ranges = Vec::new();
2061
2062        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
2063        for selection in self.selections(cx) {
2064            let range = selection.display_range(&display_map).sorted();
2065            let buffer_start_row = range.start.to_buffer_point(&display_map, Bias::Left).row;
2066
2067            for row in (0..=range.end.row()).rev() {
2068                if self.is_line_foldable(&display_map, row) && !display_map.is_line_folded(row) {
2069                    let fold_range = self.foldable_range_for_line(&display_map, row);
2070                    if fold_range.end.row >= buffer_start_row {
2071                        fold_ranges.push(fold_range);
2072                        if row <= range.start.row() {
2073                            break;
2074                        }
2075                    }
2076                }
2077            }
2078        }
2079
2080        self.fold_ranges(fold_ranges, cx);
2081    }
2082
2083    pub fn unfold(&mut self, _: &(), cx: &mut ViewContext<Self>) {
2084        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
2085        let buffer = self.buffer.read(cx);
2086        let ranges = self
2087            .selections(cx)
2088            .iter()
2089            .map(|s| {
2090                let range = s.display_range(&display_map).sorted();
2091                let mut start = range.start.to_buffer_point(&display_map, Bias::Left);
2092                let mut end = range.end.to_buffer_point(&display_map, Bias::Left);
2093                start.column = 0;
2094                end.column = buffer.line_len(end.row);
2095                start..end
2096            })
2097            .collect::<Vec<_>>();
2098        self.unfold_ranges(ranges, cx);
2099    }
2100
2101    fn is_line_foldable(&self, display_map: &DisplayMapSnapshot, display_row: u32) -> bool {
2102        let max_point = display_map.max_point();
2103        if display_row >= max_point.row() {
2104            false
2105        } else {
2106            let (start_indent, is_blank) = display_map.line_indent(display_row);
2107            if is_blank {
2108                false
2109            } else {
2110                for display_row in display_row + 1..=max_point.row() {
2111                    let (indent, is_blank) = display_map.line_indent(display_row);
2112                    if !is_blank {
2113                        return indent > start_indent;
2114                    }
2115                }
2116                false
2117            }
2118        }
2119    }
2120
2121    fn foldable_range_for_line(
2122        &self,
2123        display_map: &DisplayMapSnapshot,
2124        start_row: u32,
2125    ) -> Range<Point> {
2126        let max_point = display_map.max_point();
2127
2128        let (start_indent, _) = display_map.line_indent(start_row);
2129        let start = DisplayPoint::new(start_row, display_map.line_len(start_row));
2130        let mut end = None;
2131        for row in start_row + 1..=max_point.row() {
2132            let (indent, is_blank) = display_map.line_indent(row);
2133            if !is_blank && indent <= start_indent {
2134                end = Some(DisplayPoint::new(row - 1, display_map.line_len(row - 1)));
2135                break;
2136            }
2137        }
2138
2139        let end = end.unwrap_or(max_point);
2140        return start.to_buffer_point(display_map, Bias::Left)
2141            ..end.to_buffer_point(display_map, Bias::Left);
2142    }
2143
2144    pub fn fold_selected_ranges(&mut self, _: &(), cx: &mut ViewContext<Self>) {
2145        let buffer = self.buffer.read(cx);
2146        let ranges = self
2147            .selections(cx.as_ref())
2148            .iter()
2149            .map(|s| s.point_range(buffer).sorted())
2150            .collect();
2151        self.fold_ranges(ranges, cx);
2152    }
2153
2154    fn fold_ranges<T: ToOffset>(&mut self, ranges: Vec<Range<T>>, cx: &mut ViewContext<Self>) {
2155        if !ranges.is_empty() {
2156            self.display_map.update(cx, |map, cx| map.fold(ranges, cx));
2157            self.autoscroll_requested = true;
2158            cx.notify();
2159        }
2160    }
2161
2162    fn unfold_ranges<T: ToOffset>(&mut self, ranges: Vec<Range<T>>, cx: &mut ViewContext<Self>) {
2163        if !ranges.is_empty() {
2164            self.display_map
2165                .update(cx, |map, cx| map.unfold(ranges, cx));
2166            self.autoscroll_requested = true;
2167            cx.notify();
2168        }
2169    }
2170
2171    pub fn longest_row(&self, cx: &mut MutableAppContext) -> u32 {
2172        self.display_map
2173            .update(cx, |map, cx| map.snapshot(cx))
2174            .longest_row()
2175    }
2176
2177    pub fn max_point(&self, cx: &mut MutableAppContext) -> DisplayPoint {
2178        self.display_map
2179            .update(cx, |map, cx| map.snapshot(cx))
2180            .max_point()
2181    }
2182
2183    pub fn text(&self, cx: &mut MutableAppContext) -> String {
2184        self.display_map
2185            .update(cx, |map, cx| map.snapshot(cx))
2186            .text()
2187    }
2188
2189    pub fn font_size(&self) -> f32 {
2190        self.settings.borrow().buffer_font_size
2191    }
2192
2193    pub fn set_wrap_width(&self, width: f32, cx: &mut MutableAppContext) -> bool {
2194        self.display_map
2195            .update(cx, |map, cx| map.set_wrap_width(Some(width), cx))
2196    }
2197
2198    fn next_blink_epoch(&mut self) -> usize {
2199        self.blink_epoch += 1;
2200        self.blink_epoch
2201    }
2202
2203    fn pause_cursor_blinking(&mut self, cx: &mut ViewContext<Self>) {
2204        self.cursors_visible = true;
2205        cx.notify();
2206
2207        let epoch = self.next_blink_epoch();
2208        cx.spawn(|this, mut cx| {
2209            let this = this.downgrade();
2210            async move {
2211                Timer::after(CURSOR_BLINK_INTERVAL).await;
2212                if let Some(this) = cx.read(|cx| this.upgrade(cx)) {
2213                    this.update(&mut cx, |this, cx| this.resume_cursor_blinking(epoch, cx))
2214                }
2215            }
2216        })
2217        .detach();
2218    }
2219
2220    fn resume_cursor_blinking(&mut self, epoch: usize, cx: &mut ViewContext<Self>) {
2221        if epoch == self.blink_epoch {
2222            self.blinking_paused = false;
2223            self.blink_cursors(epoch, cx);
2224        }
2225    }
2226
2227    fn blink_cursors(&mut self, epoch: usize, cx: &mut ViewContext<Self>) {
2228        if epoch == self.blink_epoch && self.focused && !self.blinking_paused {
2229            self.cursors_visible = !self.cursors_visible;
2230            cx.notify();
2231
2232            let epoch = self.next_blink_epoch();
2233            cx.spawn(|this, mut cx| {
2234                let this = this.downgrade();
2235                async move {
2236                    Timer::after(CURSOR_BLINK_INTERVAL).await;
2237                    if let Some(this) = cx.read(|cx| this.upgrade(cx)) {
2238                        this.update(&mut cx, |this, cx| this.blink_cursors(epoch, cx));
2239                    }
2240                }
2241            })
2242            .detach();
2243        }
2244    }
2245
2246    pub fn cursors_visible(&self) -> bool {
2247        self.cursors_visible
2248    }
2249
2250    fn on_buffer_changed(&mut self, _: ModelHandle<Buffer>, cx: &mut ViewContext<Self>) {
2251        cx.notify();
2252    }
2253
2254    fn on_buffer_event(
2255        &mut self,
2256        _: ModelHandle<Buffer>,
2257        event: &buffer::Event,
2258        cx: &mut ViewContext<Self>,
2259    ) {
2260        match event {
2261            buffer::Event::Edited => cx.emit(Event::Edited),
2262            buffer::Event::Dirtied => cx.emit(Event::Dirtied),
2263            buffer::Event::Saved => cx.emit(Event::Saved),
2264            buffer::Event::FileHandleChanged => cx.emit(Event::FileHandleChanged),
2265            buffer::Event::Reloaded => cx.emit(Event::FileHandleChanged),
2266            buffer::Event::Reparsed => {}
2267        }
2268    }
2269
2270    fn on_display_map_changed(&mut self, _: ModelHandle<DisplayMap>, cx: &mut ViewContext<Self>) {
2271        cx.notify();
2272    }
2273}
2274
2275impl Snapshot {
2276    pub fn scroll_position(&self) -> Vector2F {
2277        compute_scroll_position(
2278            &self.display_snapshot,
2279            self.scroll_position,
2280            &self.scroll_top_anchor,
2281        )
2282    }
2283
2284    pub fn max_point(&self) -> DisplayPoint {
2285        self.display_snapshot.max_point()
2286    }
2287
2288    pub fn longest_row(&self) -> u32 {
2289        self.display_snapshot.longest_row()
2290    }
2291
2292    pub fn line_len(&self, display_row: u32) -> u32 {
2293        self.display_snapshot.line_len(display_row)
2294    }
2295
2296    pub fn font_ascent(&self, font_cache: &FontCache) -> f32 {
2297        let font_id = font_cache.default_font(self.font_family);
2298        let ascent = font_cache.metric(font_id, |m| m.ascent);
2299        font_cache.scale_metric(ascent, font_id, self.font_size)
2300    }
2301
2302    pub fn font_descent(&self, font_cache: &FontCache) -> f32 {
2303        let font_id = font_cache.default_font(self.font_family);
2304        let descent = font_cache.metric(font_id, |m| m.descent);
2305        font_cache.scale_metric(descent, font_id, self.font_size)
2306    }
2307
2308    pub fn line_height(&self, font_cache: &FontCache) -> f32 {
2309        let font_id = font_cache.default_font(self.font_family);
2310        font_cache.line_height(font_id, self.font_size)
2311    }
2312
2313    pub fn em_width(&self, font_cache: &FontCache) -> f32 {
2314        let font_id = font_cache.default_font(self.font_family);
2315        font_cache.em_width(font_id, self.font_size)
2316    }
2317
2318    // TODO: Can we make this not return a result?
2319    pub fn max_line_number_width(
2320        &self,
2321        font_cache: &FontCache,
2322        layout_cache: &TextLayoutCache,
2323    ) -> Result<f32> {
2324        let font_size = self.font_size;
2325        let font_id = font_cache.select_font(self.font_family, &FontProperties::new())?;
2326        let digit_count = (self.display_snapshot.buffer_row_count() as f32)
2327            .log10()
2328            .floor() as usize
2329            + 1;
2330
2331        Ok(layout_cache
2332            .layout_str(
2333                "1".repeat(digit_count).as_str(),
2334                font_size,
2335                &[(digit_count, font_id, ColorU::black())],
2336            )
2337            .width())
2338    }
2339
2340    pub fn layout_line_numbers(
2341        &self,
2342        viewport_height: f32,
2343        font_cache: &FontCache,
2344        layout_cache: &TextLayoutCache,
2345    ) -> Result<Vec<Option<text_layout::Line>>> {
2346        let font_id = font_cache.select_font(self.font_family, &FontProperties::new())?;
2347
2348        let start_row = self.scroll_position().y() as usize;
2349        let end_row = cmp::min(
2350            self.display_snapshot.max_point().row() as usize,
2351            start_row + (viewport_height / self.line_height(font_cache)).ceil() as usize,
2352        );
2353        let line_count = end_row - start_row + 1;
2354
2355        let mut layouts = Vec::with_capacity(line_count);
2356        let mut line_number = String::new();
2357        for (buffer_row, soft_wrapped) in self
2358            .display_snapshot
2359            .buffer_rows(start_row as u32)
2360            .take(line_count)
2361        {
2362            if soft_wrapped {
2363                layouts.push(None);
2364            } else {
2365                line_number.clear();
2366                write!(&mut line_number, "{}", buffer_row + 1).unwrap();
2367                layouts.push(Some(layout_cache.layout_str(
2368                    &line_number,
2369                    self.font_size,
2370                    &[(line_number.len(), font_id, ColorU::black())],
2371                )));
2372            }
2373        }
2374
2375        Ok(layouts)
2376    }
2377
2378    pub fn layout_lines(
2379        &mut self,
2380        mut rows: Range<u32>,
2381        font_cache: &FontCache,
2382        layout_cache: &TextLayoutCache,
2383    ) -> Result<Vec<text_layout::Line>> {
2384        rows.end = cmp::min(rows.end, self.display_snapshot.max_point().row() + 1);
2385        if rows.start >= rows.end {
2386            return Ok(Vec::new());
2387        }
2388
2389        let mut prev_font_properties = FontProperties::new();
2390        let mut prev_font_id = font_cache
2391            .select_font(self.font_family, &prev_font_properties)
2392            .unwrap();
2393
2394        let mut layouts = Vec::with_capacity(rows.len());
2395        let mut line = String::new();
2396        let mut styles = Vec::new();
2397        let mut row = rows.start;
2398        let mut line_exceeded_max_len = false;
2399        let chunks = self
2400            .display_snapshot
2401            .highlighted_chunks_for_rows(rows.clone());
2402
2403        'outer: for (chunk, style_ix) in chunks.chain(Some(("\n", StyleId::default()))) {
2404            for (ix, mut line_chunk) in chunk.split('\n').enumerate() {
2405                if ix > 0 {
2406                    layouts.push(layout_cache.layout_str(&line, self.font_size, &styles));
2407                    line.clear();
2408                    styles.clear();
2409                    row += 1;
2410                    line_exceeded_max_len = false;
2411                    if row == rows.end {
2412                        break 'outer;
2413                    }
2414                }
2415
2416                if !line_chunk.is_empty() && !line_exceeded_max_len {
2417                    let (color, font_properties) = self.theme.syntax_style(style_ix);
2418                    // Avoid a lookup if the font properties match the previous ones.
2419                    let font_id = if font_properties == prev_font_properties {
2420                        prev_font_id
2421                    } else {
2422                        font_cache.select_font(self.font_family, &font_properties)?
2423                    };
2424
2425                    if line.len() + line_chunk.len() > MAX_LINE_LEN {
2426                        let mut chunk_len = MAX_LINE_LEN - line.len();
2427                        while !line_chunk.is_char_boundary(chunk_len) {
2428                            chunk_len -= 1;
2429                        }
2430                        line_chunk = &line_chunk[..chunk_len];
2431                        line_exceeded_max_len = true;
2432                    }
2433
2434                    line.push_str(line_chunk);
2435                    styles.push((line_chunk.len(), font_id, color));
2436                    prev_font_id = font_id;
2437                    prev_font_properties = font_properties;
2438                }
2439            }
2440        }
2441
2442        Ok(layouts)
2443    }
2444
2445    pub fn layout_line(
2446        &self,
2447        row: u32,
2448        font_cache: &FontCache,
2449        layout_cache: &TextLayoutCache,
2450    ) -> Result<text_layout::Line> {
2451        let font_id = font_cache.select_font(self.font_family, &FontProperties::new())?;
2452
2453        let mut line = self.display_snapshot.line(row);
2454
2455        if line.len() > MAX_LINE_LEN {
2456            let mut len = MAX_LINE_LEN;
2457            while !line.is_char_boundary(len) {
2458                len -= 1;
2459            }
2460            line.truncate(len);
2461        }
2462
2463        Ok(layout_cache.layout_str(
2464            &line,
2465            self.font_size,
2466            &[(
2467                self.display_snapshot.line_len(row) as usize,
2468                font_id,
2469                ColorU::black(),
2470            )],
2471        ))
2472    }
2473}
2474
2475fn compute_scroll_position(
2476    snapshot: &DisplayMapSnapshot,
2477    mut scroll_position: Vector2F,
2478    scroll_top_anchor: &Anchor,
2479) -> Vector2F {
2480    let scroll_top = scroll_top_anchor
2481        .to_display_point(snapshot, Bias::Left)
2482        .row() as f32;
2483    scroll_position.set_y(scroll_top + scroll_position.y());
2484    scroll_position
2485}
2486
2487pub enum Event {
2488    Activate,
2489    Edited,
2490    Blurred,
2491    Dirtied,
2492    Saved,
2493    FileHandleChanged,
2494}
2495
2496impl Entity for Editor {
2497    type Event = Event;
2498
2499    fn release(&mut self, cx: &mut MutableAppContext) {
2500        self.buffer.update(cx, |buffer, cx| {
2501            buffer
2502                .remove_selection_set(self.selection_set_id, cx)
2503                .unwrap();
2504        });
2505    }
2506}
2507
2508impl View for Editor {
2509    fn render<'a>(&self, _: &AppContext) -> ElementBox {
2510        EditorElement::new(self.handle.clone()).boxed()
2511    }
2512
2513    fn ui_name() -> &'static str {
2514        "BufferView"
2515    }
2516
2517    fn on_focus(&mut self, cx: &mut ViewContext<Self>) {
2518        self.focused = true;
2519        self.blink_cursors(self.blink_epoch, cx);
2520        self.buffer.update(cx, |buffer, cx| {
2521            buffer
2522                .set_active_selection_set(Some(self.selection_set_id), cx)
2523                .unwrap();
2524        });
2525    }
2526
2527    fn on_blur(&mut self, cx: &mut ViewContext<Self>) {
2528        self.focused = false;
2529        self.cursors_visible = false;
2530        self.buffer.update(cx, |buffer, cx| {
2531            buffer.set_active_selection_set(None, cx).unwrap();
2532        });
2533        cx.emit(Event::Blurred);
2534        cx.notify();
2535    }
2536}
2537
2538impl workspace::Item for Buffer {
2539    type View = Editor;
2540
2541    fn file(&self) -> Option<&File> {
2542        self.file()
2543    }
2544
2545    fn build_view(
2546        handle: ModelHandle<Self>,
2547        settings: watch::Receiver<Settings>,
2548        cx: &mut ViewContext<Self::View>,
2549    ) -> Self::View {
2550        Editor::for_buffer(handle, settings, cx)
2551    }
2552}
2553
2554impl workspace::ItemView for Editor {
2555    fn should_activate_item_on_event(event: &Self::Event) -> bool {
2556        matches!(event, Event::Activate)
2557    }
2558
2559    fn should_update_tab_on_event(event: &Self::Event) -> bool {
2560        matches!(
2561            event,
2562            Event::Saved | Event::Dirtied | Event::FileHandleChanged
2563        )
2564    }
2565
2566    fn title(&self, cx: &AppContext) -> std::string::String {
2567        let filename = self
2568            .buffer
2569            .read(cx)
2570            .file()
2571            .and_then(|file| file.file_name(cx));
2572        if let Some(name) = filename {
2573            name.to_string_lossy().into()
2574        } else {
2575            "untitled".into()
2576        }
2577    }
2578
2579    fn entry_id(&self, cx: &AppContext) -> Option<(usize, Arc<Path>)> {
2580        self.buffer.read(cx).file().map(|file| file.entry_id())
2581    }
2582
2583    fn clone_on_split(&self, cx: &mut ViewContext<Self>) -> Option<Self>
2584    where
2585        Self: Sized,
2586    {
2587        let mut clone = Editor::for_buffer(self.buffer.clone(), self.settings.clone(), cx);
2588        clone.scroll_position = self.scroll_position;
2589        clone.scroll_top_anchor = self.scroll_top_anchor.clone();
2590        Some(clone)
2591    }
2592
2593    fn save(&mut self, cx: &mut ViewContext<Self>) -> Result<Task<Result<()>>> {
2594        let save = self.buffer.update(cx, |b, cx| b.save(cx))?;
2595        Ok(cx.spawn(|_, _| async move {
2596            save.await?;
2597            Ok(())
2598        }))
2599    }
2600
2601    fn save_as(
2602        &mut self,
2603        worktree: &ModelHandle<Worktree>,
2604        path: &Path,
2605        cx: &mut ViewContext<Self>,
2606    ) -> Task<Result<()>> {
2607        self.buffer
2608            .update(cx, |b, cx| b.save_as(worktree, path, cx))
2609    }
2610
2611    fn is_dirty(&self, cx: &AppContext) -> bool {
2612        self.buffer.read(cx).is_dirty()
2613    }
2614
2615    fn has_conflict(&self, cx: &AppContext) -> bool {
2616        self.buffer.read(cx).has_conflict()
2617    }
2618}
2619
2620#[cfg(test)]
2621mod tests {
2622    use super::*;
2623    use crate::{
2624        editor::Point,
2625        settings,
2626        test::{build_app_state, sample_text},
2627    };
2628    use buffer::History;
2629    use unindent::Unindent;
2630
2631    #[gpui::test]
2632    fn test_selection_with_mouse(cx: &mut gpui::MutableAppContext) {
2633        let buffer = cx.add_model(|cx| Buffer::new(0, "aaaaaa\nbbbbbb\ncccccc\ndddddd\n", cx));
2634        let settings = settings::channel(&cx.font_cache()).unwrap().1;
2635        let (_, editor) = cx.add_window(|cx| Editor::for_buffer(buffer, settings, cx));
2636
2637        editor.update(cx, |view, cx| {
2638            view.begin_selection(DisplayPoint::new(2, 2), false, cx);
2639        });
2640
2641        assert_eq!(
2642            editor.update(cx, |view, cx| view.selection_ranges(cx)),
2643            [DisplayPoint::new(2, 2)..DisplayPoint::new(2, 2)]
2644        );
2645
2646        editor.update(cx, |view, cx| {
2647            view.update_selection(DisplayPoint::new(3, 3), Vector2F::zero(), cx);
2648        });
2649
2650        assert_eq!(
2651            editor.update(cx, |view, cx| view.selection_ranges(cx)),
2652            [DisplayPoint::new(2, 2)..DisplayPoint::new(3, 3)]
2653        );
2654
2655        editor.update(cx, |view, cx| {
2656            view.update_selection(DisplayPoint::new(1, 1), Vector2F::zero(), cx);
2657        });
2658
2659        assert_eq!(
2660            editor.update(cx, |view, cx| view.selection_ranges(cx)),
2661            [DisplayPoint::new(2, 2)..DisplayPoint::new(1, 1)]
2662        );
2663
2664        editor.update(cx, |view, cx| {
2665            view.end_selection(cx);
2666            view.update_selection(DisplayPoint::new(3, 3), Vector2F::zero(), cx);
2667        });
2668
2669        assert_eq!(
2670            editor.update(cx, |view, cx| view.selection_ranges(cx)),
2671            [DisplayPoint::new(2, 2)..DisplayPoint::new(1, 1)]
2672        );
2673
2674        editor.update(cx, |view, cx| {
2675            view.begin_selection(DisplayPoint::new(3, 3), true, cx);
2676            view.update_selection(DisplayPoint::new(0, 0), Vector2F::zero(), cx);
2677        });
2678
2679        assert_eq!(
2680            editor.update(cx, |view, cx| view.selection_ranges(cx)),
2681            [
2682                DisplayPoint::new(2, 2)..DisplayPoint::new(1, 1),
2683                DisplayPoint::new(3, 3)..DisplayPoint::new(0, 0)
2684            ]
2685        );
2686
2687        editor.update(cx, |view, cx| {
2688            view.end_selection(cx);
2689        });
2690
2691        assert_eq!(
2692            editor.update(cx, |view, cx| view.selection_ranges(cx)),
2693            [DisplayPoint::new(3, 3)..DisplayPoint::new(0, 0)]
2694        );
2695    }
2696
2697    #[gpui::test]
2698    fn test_canceling_pending_selection(cx: &mut gpui::MutableAppContext) {
2699        let buffer = cx.add_model(|cx| Buffer::new(0, "aaaaaa\nbbbbbb\ncccccc\ndddddd\n", cx));
2700        let settings = settings::channel(&cx.font_cache()).unwrap().1;
2701        let (_, view) = cx.add_window(|cx| Editor::for_buffer(buffer, settings, cx));
2702
2703        view.update(cx, |view, cx| {
2704            view.begin_selection(DisplayPoint::new(2, 2), false, cx);
2705            assert_eq!(
2706                view.selection_ranges(cx),
2707                [DisplayPoint::new(2, 2)..DisplayPoint::new(2, 2)]
2708            );
2709        });
2710
2711        view.update(cx, |view, cx| {
2712            view.update_selection(DisplayPoint::new(3, 3), Vector2F::zero(), cx);
2713            assert_eq!(
2714                view.selection_ranges(cx),
2715                [DisplayPoint::new(2, 2)..DisplayPoint::new(3, 3)]
2716            );
2717        });
2718
2719        view.update(cx, |view, cx| {
2720            view.cancel(&(), cx);
2721            view.update_selection(DisplayPoint::new(1, 1), Vector2F::zero(), cx);
2722            assert_eq!(
2723                view.selection_ranges(cx),
2724                [DisplayPoint::new(2, 2)..DisplayPoint::new(3, 3)]
2725            );
2726        });
2727    }
2728
2729    #[gpui::test]
2730    fn test_cancel(cx: &mut gpui::MutableAppContext) {
2731        let buffer = cx.add_model(|cx| Buffer::new(0, "aaaaaa\nbbbbbb\ncccccc\ndddddd\n", cx));
2732        let settings = settings::channel(&cx.font_cache()).unwrap().1;
2733        let (_, view) = cx.add_window(|cx| Editor::for_buffer(buffer, settings, cx));
2734
2735        view.update(cx, |view, cx| {
2736            view.begin_selection(DisplayPoint::new(3, 4), false, cx);
2737            view.update_selection(DisplayPoint::new(1, 1), Vector2F::zero(), cx);
2738            view.end_selection(cx);
2739
2740            view.begin_selection(DisplayPoint::new(0, 1), true, cx);
2741            view.update_selection(DisplayPoint::new(0, 3), Vector2F::zero(), cx);
2742            view.end_selection(cx);
2743            assert_eq!(
2744                view.selection_ranges(cx),
2745                [
2746                    DisplayPoint::new(0, 1)..DisplayPoint::new(0, 3),
2747                    DisplayPoint::new(3, 4)..DisplayPoint::new(1, 1),
2748                ]
2749            );
2750        });
2751
2752        view.update(cx, |view, cx| {
2753            view.cancel(&(), cx);
2754            assert_eq!(
2755                view.selection_ranges(cx),
2756                [DisplayPoint::new(3, 4)..DisplayPoint::new(1, 1)]
2757            );
2758        });
2759
2760        view.update(cx, |view, cx| {
2761            view.cancel(&(), cx);
2762            assert_eq!(
2763                view.selection_ranges(cx),
2764                [DisplayPoint::new(1, 1)..DisplayPoint::new(1, 1)]
2765            );
2766        });
2767    }
2768
2769    #[gpui::test]
2770    fn test_layout_line_numbers(cx: &mut gpui::MutableAppContext) {
2771        let layout_cache = TextLayoutCache::new(cx.platform().fonts());
2772        let font_cache = cx.font_cache().clone();
2773
2774        let buffer = cx.add_model(|cx| Buffer::new(0, sample_text(6, 6), cx));
2775
2776        let settings = settings::channel(&font_cache).unwrap().1;
2777        let (_, editor) = cx.add_window(|cx| Editor::for_buffer(buffer.clone(), settings, cx));
2778
2779        let layouts = editor.update(cx, |editor, cx| {
2780            editor
2781                .snapshot(cx)
2782                .layout_line_numbers(1000.0, &font_cache, &layout_cache)
2783                .unwrap()
2784        });
2785        assert_eq!(layouts.len(), 6);
2786    }
2787
2788    #[gpui::test]
2789    fn test_fold(cx: &mut gpui::MutableAppContext) {
2790        let buffer = cx.add_model(|cx| {
2791            Buffer::new(
2792                0,
2793                "
2794                    impl Foo {
2795                        // Hello!
2796
2797                        fn a() {
2798                            1
2799                        }
2800
2801                        fn b() {
2802                            2
2803                        }
2804
2805                        fn c() {
2806                            3
2807                        }
2808                    }
2809                "
2810                .unindent(),
2811                cx,
2812            )
2813        });
2814        let settings = settings::channel(&cx.font_cache()).unwrap().1;
2815        let (_, view) = cx.add_window(|cx| Editor::for_buffer(buffer.clone(), settings, cx));
2816
2817        view.update(cx, |view, cx| {
2818            view.select_display_ranges(&[DisplayPoint::new(8, 0)..DisplayPoint::new(12, 0)], cx)
2819                .unwrap();
2820            view.fold(&(), cx);
2821            assert_eq!(
2822                view.text(cx),
2823                "
2824                    impl Foo {
2825                        // Hello!
2826
2827                        fn a() {
2828                            1
2829                        }
2830
2831                        fn b() {…
2832                        }
2833
2834                        fn c() {…
2835                        }
2836                    }
2837                "
2838                .unindent(),
2839            );
2840
2841            view.fold(&(), cx);
2842            assert_eq!(
2843                view.text(cx),
2844                "
2845                    impl Foo {…
2846                    }
2847                "
2848                .unindent(),
2849            );
2850
2851            view.unfold(&(), cx);
2852            assert_eq!(
2853                view.text(cx),
2854                "
2855                    impl Foo {
2856                        // Hello!
2857
2858                        fn a() {
2859                            1
2860                        }
2861
2862                        fn b() {…
2863                        }
2864
2865                        fn c() {…
2866                        }
2867                    }
2868                "
2869                .unindent(),
2870            );
2871
2872            view.unfold(&(), cx);
2873            assert_eq!(view.text(cx), buffer.read(cx).text());
2874        });
2875    }
2876
2877    #[gpui::test]
2878    fn test_move_cursor(cx: &mut gpui::MutableAppContext) {
2879        let buffer = cx.add_model(|cx| Buffer::new(0, sample_text(6, 6), cx));
2880        let settings = settings::channel(&cx.font_cache()).unwrap().1;
2881        let (_, view) = cx.add_window(|cx| Editor::for_buffer(buffer.clone(), settings, cx));
2882
2883        buffer.update(cx, |buffer, cx| {
2884            buffer.edit(
2885                vec![
2886                    Point::new(1, 0)..Point::new(1, 0),
2887                    Point::new(1, 1)..Point::new(1, 1),
2888                ],
2889                "\t",
2890                cx,
2891            );
2892        });
2893
2894        view.update(cx, |view, cx| {
2895            assert_eq!(
2896                view.selection_ranges(cx),
2897                &[DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0)]
2898            );
2899
2900            view.move_down(&(), cx);
2901            assert_eq!(
2902                view.selection_ranges(cx),
2903                &[DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0)]
2904            );
2905
2906            view.move_right(&(), cx);
2907            assert_eq!(
2908                view.selection_ranges(cx),
2909                &[DisplayPoint::new(1, 4)..DisplayPoint::new(1, 4)]
2910            );
2911
2912            view.move_left(&(), cx);
2913            assert_eq!(
2914                view.selection_ranges(cx),
2915                &[DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0)]
2916            );
2917
2918            view.move_up(&(), cx);
2919            assert_eq!(
2920                view.selection_ranges(cx),
2921                &[DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0)]
2922            );
2923
2924            view.move_to_end(&(), cx);
2925            assert_eq!(
2926                view.selection_ranges(cx),
2927                &[DisplayPoint::new(5, 6)..DisplayPoint::new(5, 6)]
2928            );
2929
2930            view.move_to_beginning(&(), cx);
2931            assert_eq!(
2932                view.selection_ranges(cx),
2933                &[DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0)]
2934            );
2935
2936            view.select_display_ranges(&[DisplayPoint::new(0, 1)..DisplayPoint::new(0, 2)], cx)
2937                .unwrap();
2938            view.select_to_beginning(&(), cx);
2939            assert_eq!(
2940                view.selection_ranges(cx),
2941                &[DisplayPoint::new(0, 1)..DisplayPoint::new(0, 0)]
2942            );
2943
2944            view.select_to_end(&(), cx);
2945            assert_eq!(
2946                view.selection_ranges(cx),
2947                &[DisplayPoint::new(0, 1)..DisplayPoint::new(5, 6)]
2948            );
2949        });
2950    }
2951
2952    #[gpui::test]
2953    fn test_move_cursor_multibyte(cx: &mut gpui::MutableAppContext) {
2954        let buffer = cx.add_model(|cx| Buffer::new(0, "ⓐⓑⓒⓓⓔ\nabcde\nαβγδε\n", cx));
2955        let settings = settings::channel(&cx.font_cache()).unwrap().1;
2956        let (_, view) = cx.add_window(|cx| Editor::for_buffer(buffer.clone(), settings, cx));
2957
2958        assert_eq!('ⓐ'.len_utf8(), 3);
2959        assert_eq!('α'.len_utf8(), 2);
2960
2961        view.update(cx, |view, cx| {
2962            view.fold_ranges(
2963                vec![
2964                    Point::new(0, 6)..Point::new(0, 12),
2965                    Point::new(1, 2)..Point::new(1, 4),
2966                    Point::new(2, 4)..Point::new(2, 8),
2967                ],
2968                cx,
2969            );
2970            assert_eq!(view.text(cx), "ⓐⓑ…ⓔ\nab…e\nαβ…ε\n");
2971
2972            view.move_right(&(), cx);
2973            assert_eq!(view.selection_ranges(cx), &[empty_range(0, "".len())]);
2974            view.move_right(&(), cx);
2975            assert_eq!(view.selection_ranges(cx), &[empty_range(0, "ⓐⓑ".len())]);
2976            view.move_right(&(), cx);
2977            assert_eq!(view.selection_ranges(cx), &[empty_range(0, "ⓐⓑ…".len())]);
2978
2979            view.move_down(&(), cx);
2980            assert_eq!(view.selection_ranges(cx), &[empty_range(1, "ab…".len())]);
2981            view.move_left(&(), cx);
2982            assert_eq!(view.selection_ranges(cx), &[empty_range(1, "ab".len())]);
2983            view.move_left(&(), cx);
2984            assert_eq!(view.selection_ranges(cx), &[empty_range(1, "a".len())]);
2985
2986            view.move_down(&(), cx);
2987            assert_eq!(view.selection_ranges(cx), &[empty_range(2, "α".len())]);
2988            view.move_right(&(), cx);
2989            assert_eq!(view.selection_ranges(cx), &[empty_range(2, "αβ".len())]);
2990            view.move_right(&(), cx);
2991            assert_eq!(view.selection_ranges(cx), &[empty_range(2, "αβ…".len())]);
2992            view.move_right(&(), cx);
2993            assert_eq!(view.selection_ranges(cx), &[empty_range(2, "αβ…ε".len())]);
2994
2995            view.move_up(&(), cx);
2996            assert_eq!(view.selection_ranges(cx), &[empty_range(1, "ab…e".len())]);
2997            view.move_up(&(), cx);
2998            assert_eq!(view.selection_ranges(cx), &[empty_range(0, "ⓐⓑ…ⓔ".len())]);
2999            view.move_left(&(), cx);
3000            assert_eq!(view.selection_ranges(cx), &[empty_range(0, "ⓐⓑ…".len())]);
3001            view.move_left(&(), cx);
3002            assert_eq!(view.selection_ranges(cx), &[empty_range(0, "ⓐⓑ".len())]);
3003            view.move_left(&(), cx);
3004            assert_eq!(view.selection_ranges(cx), &[empty_range(0, "".len())]);
3005        });
3006    }
3007
3008    #[gpui::test]
3009    fn test_move_cursor_different_line_lengths(cx: &mut gpui::MutableAppContext) {
3010        let buffer = cx.add_model(|cx| Buffer::new(0, "ⓐⓑⓒⓓⓔ\nabcd\nαβγ\nabcd\nⓐⓑⓒⓓⓔ\n", cx));
3011        let settings = settings::channel(&cx.font_cache()).unwrap().1;
3012        let (_, view) = cx.add_window(|cx| Editor::for_buffer(buffer.clone(), settings, cx));
3013        view.update(cx, |view, cx| {
3014            view.select_display_ranges(&[empty_range(0, "ⓐⓑⓒⓓⓔ".len())], cx)
3015                .unwrap();
3016
3017            view.move_down(&(), cx);
3018            assert_eq!(view.selection_ranges(cx), &[empty_range(1, "abcd".len())]);
3019
3020            view.move_down(&(), cx);
3021            assert_eq!(view.selection_ranges(cx), &[empty_range(2, "αβγ".len())]);
3022
3023            view.move_down(&(), cx);
3024            assert_eq!(view.selection_ranges(cx), &[empty_range(3, "abcd".len())]);
3025
3026            view.move_down(&(), cx);
3027            assert_eq!(view.selection_ranges(cx), &[empty_range(4, "ⓐⓑⓒⓓⓔ".len())]);
3028
3029            view.move_up(&(), cx);
3030            assert_eq!(view.selection_ranges(cx), &[empty_range(3, "abcd".len())]);
3031
3032            view.move_up(&(), cx);
3033            assert_eq!(view.selection_ranges(cx), &[empty_range(2, "αβγ".len())]);
3034        });
3035    }
3036
3037    #[gpui::test]
3038    fn test_beginning_end_of_line(cx: &mut gpui::MutableAppContext) {
3039        let buffer = cx.add_model(|cx| Buffer::new(0, "abc\n  def", cx));
3040        let settings = settings::channel(&cx.font_cache()).unwrap().1;
3041        let (_, view) = cx.add_window(|cx| Editor::for_buffer(buffer, settings, cx));
3042        view.update(cx, |view, cx| {
3043            view.select_display_ranges(
3044                &[
3045                    DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1),
3046                    DisplayPoint::new(1, 4)..DisplayPoint::new(1, 4),
3047                ],
3048                cx,
3049            )
3050            .unwrap();
3051        });
3052
3053        view.update(cx, |view, cx| {
3054            view.move_to_beginning_of_line(&(), cx);
3055            assert_eq!(
3056                view.selection_ranges(cx),
3057                &[
3058                    DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0),
3059                    DisplayPoint::new(1, 2)..DisplayPoint::new(1, 2),
3060                ]
3061            );
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, 0)..DisplayPoint::new(1, 0),
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, 2)..DisplayPoint::new(1, 2),
3082                ]
3083            );
3084        });
3085
3086        view.update(cx, |view, cx| {
3087            view.move_to_end_of_line(&(), cx);
3088            assert_eq!(
3089                view.selection_ranges(cx),
3090                &[
3091                    DisplayPoint::new(0, 3)..DisplayPoint::new(0, 3),
3092                    DisplayPoint::new(1, 5)..DisplayPoint::new(1, 5),
3093                ]
3094            );
3095        });
3096
3097        // Moving to the end of line again is a no-op.
3098        view.update(cx, |view, cx| {
3099            view.move_to_end_of_line(&(), cx);
3100            assert_eq!(
3101                view.selection_ranges(cx),
3102                &[
3103                    DisplayPoint::new(0, 3)..DisplayPoint::new(0, 3),
3104                    DisplayPoint::new(1, 5)..DisplayPoint::new(1, 5),
3105                ]
3106            );
3107        });
3108
3109        view.update(cx, |view, cx| {
3110            view.move_left(&(), cx);
3111            view.select_to_beginning_of_line(&true, cx);
3112            assert_eq!(
3113                view.selection_ranges(cx),
3114                &[
3115                    DisplayPoint::new(0, 2)..DisplayPoint::new(0, 0),
3116                    DisplayPoint::new(1, 4)..DisplayPoint::new(1, 2),
3117                ]
3118            );
3119        });
3120
3121        view.update(cx, |view, 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, 0),
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, 2),
3139                ]
3140            );
3141        });
3142
3143        view.update(cx, |view, cx| {
3144            view.select_to_end_of_line(&(), cx);
3145            assert_eq!(
3146                view.selection_ranges(cx),
3147                &[
3148                    DisplayPoint::new(0, 2)..DisplayPoint::new(0, 3),
3149                    DisplayPoint::new(1, 4)..DisplayPoint::new(1, 5),
3150                ]
3151            );
3152        });
3153
3154        view.update(cx, |view, cx| {
3155            view.delete_to_end_of_line(&(), cx);
3156            assert_eq!(view.text(cx), "ab\n  de");
3157            assert_eq!(
3158                view.selection_ranges(cx),
3159                &[
3160                    DisplayPoint::new(0, 2)..DisplayPoint::new(0, 2),
3161                    DisplayPoint::new(1, 4)..DisplayPoint::new(1, 4),
3162                ]
3163            );
3164        });
3165
3166        view.update(cx, |view, cx| {
3167            view.delete_to_beginning_of_line(&(), cx);
3168            assert_eq!(view.text(cx), "\n");
3169            assert_eq!(
3170                view.selection_ranges(cx),
3171                &[
3172                    DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0),
3173                    DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0),
3174                ]
3175            );
3176        });
3177    }
3178
3179    #[gpui::test]
3180    fn test_prev_next_word_boundary(cx: &mut gpui::MutableAppContext) {
3181        let buffer =
3182            cx.add_model(|cx| Buffer::new(0, "use std::str::{foo, bar}\n\n  {baz.qux()}", cx));
3183        let settings = settings::channel(&cx.font_cache()).unwrap().1;
3184        let (_, view) = cx.add_window(|cx| Editor::for_buffer(buffer, settings, cx));
3185        view.update(cx, |view, cx| {
3186            view.select_display_ranges(
3187                &[
3188                    DisplayPoint::new(0, 11)..DisplayPoint::new(0, 11),
3189                    DisplayPoint::new(2, 4)..DisplayPoint::new(2, 4),
3190                ],
3191                cx,
3192            )
3193            .unwrap();
3194        });
3195
3196        view.update(cx, |view, cx| {
3197            view.move_to_previous_word_boundary(&(), cx);
3198            assert_eq!(
3199                view.selection_ranges(cx),
3200                &[
3201                    DisplayPoint::new(0, 9)..DisplayPoint::new(0, 9),
3202                    DisplayPoint::new(2, 3)..DisplayPoint::new(2, 3),
3203                ]
3204            );
3205        });
3206
3207        view.update(cx, |view, cx| {
3208            view.move_to_previous_word_boundary(&(), cx);
3209            assert_eq!(
3210                view.selection_ranges(cx),
3211                &[
3212                    DisplayPoint::new(0, 7)..DisplayPoint::new(0, 7),
3213                    DisplayPoint::new(2, 2)..DisplayPoint::new(2, 2),
3214                ]
3215            );
3216        });
3217
3218        view.update(cx, |view, cx| {
3219            view.move_to_previous_word_boundary(&(), cx);
3220            assert_eq!(
3221                view.selection_ranges(cx),
3222                &[
3223                    DisplayPoint::new(0, 4)..DisplayPoint::new(0, 4),
3224                    DisplayPoint::new(2, 0)..DisplayPoint::new(2, 0),
3225                ]
3226            );
3227        });
3228
3229        view.update(cx, |view, cx| {
3230            view.move_to_previous_word_boundary(&(), cx);
3231            assert_eq!(
3232                view.selection_ranges(cx),
3233                &[
3234                    DisplayPoint::new(0, 3)..DisplayPoint::new(0, 3),
3235                    DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0),
3236                ]
3237            );
3238        });
3239
3240        view.update(cx, |view, cx| {
3241            view.move_to_previous_word_boundary(&(), cx);
3242            assert_eq!(
3243                view.selection_ranges(cx),
3244                &[
3245                    DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0),
3246                    DisplayPoint::new(0, 24)..DisplayPoint::new(0, 24),
3247                ]
3248            );
3249        });
3250
3251        view.update(cx, |view, cx| {
3252            view.move_to_previous_word_boundary(&(), cx);
3253            assert_eq!(
3254                view.selection_ranges(cx),
3255                &[
3256                    DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0),
3257                    DisplayPoint::new(0, 23)..DisplayPoint::new(0, 23),
3258                ]
3259            );
3260        });
3261
3262        view.update(cx, |view, cx| {
3263            view.move_to_next_word_boundary(&(), cx);
3264            assert_eq!(
3265                view.selection_ranges(cx),
3266                &[
3267                    DisplayPoint::new(0, 3)..DisplayPoint::new(0, 3),
3268                    DisplayPoint::new(0, 24)..DisplayPoint::new(0, 24),
3269                ]
3270            );
3271        });
3272
3273        view.update(cx, |view, cx| {
3274            view.move_to_next_word_boundary(&(), cx);
3275            assert_eq!(
3276                view.selection_ranges(cx),
3277                &[
3278                    DisplayPoint::new(0, 4)..DisplayPoint::new(0, 4),
3279                    DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0),
3280                ]
3281            );
3282        });
3283
3284        view.update(cx, |view, cx| {
3285            view.move_to_next_word_boundary(&(), cx);
3286            assert_eq!(
3287                view.selection_ranges(cx),
3288                &[
3289                    DisplayPoint::new(0, 7)..DisplayPoint::new(0, 7),
3290                    DisplayPoint::new(2, 0)..DisplayPoint::new(2, 0),
3291                ]
3292            );
3293        });
3294
3295        view.update(cx, |view, cx| {
3296            view.move_to_next_word_boundary(&(), cx);
3297            assert_eq!(
3298                view.selection_ranges(cx),
3299                &[
3300                    DisplayPoint::new(0, 9)..DisplayPoint::new(0, 9),
3301                    DisplayPoint::new(2, 2)..DisplayPoint::new(2, 2),
3302                ]
3303            );
3304        });
3305
3306        view.update(cx, |view, cx| {
3307            view.move_right(&(), cx);
3308            view.select_to_previous_word_boundary(&(), cx);
3309            assert_eq!(
3310                view.selection_ranges(cx),
3311                &[
3312                    DisplayPoint::new(0, 10)..DisplayPoint::new(0, 9),
3313                    DisplayPoint::new(2, 3)..DisplayPoint::new(2, 2),
3314                ]
3315            );
3316        });
3317
3318        view.update(cx, |view, cx| {
3319            view.select_to_previous_word_boundary(&(), cx);
3320            assert_eq!(
3321                view.selection_ranges(cx),
3322                &[
3323                    DisplayPoint::new(0, 10)..DisplayPoint::new(0, 7),
3324                    DisplayPoint::new(2, 3)..DisplayPoint::new(2, 0),
3325                ]
3326            );
3327        });
3328
3329        view.update(cx, |view, cx| {
3330            view.select_to_next_word_boundary(&(), cx);
3331            assert_eq!(
3332                view.selection_ranges(cx),
3333                &[
3334                    DisplayPoint::new(0, 10)..DisplayPoint::new(0, 9),
3335                    DisplayPoint::new(2, 3)..DisplayPoint::new(2, 2),
3336                ]
3337            );
3338        });
3339
3340        view.update(cx, |view, cx| {
3341            view.delete_to_next_word_boundary(&(), cx);
3342            assert_eq!(view.text(cx), "use std::s::{foo, bar}\n\n  {az.qux()}");
3343            assert_eq!(
3344                view.selection_ranges(cx),
3345                &[
3346                    DisplayPoint::new(0, 10)..DisplayPoint::new(0, 10),
3347                    DisplayPoint::new(2, 3)..DisplayPoint::new(2, 3),
3348                ]
3349            );
3350        });
3351
3352        view.update(cx, |view, cx| {
3353            view.delete_to_previous_word_boundary(&(), cx);
3354            assert_eq!(view.text(cx), "use std::::{foo, bar}\n\n  az.qux()}");
3355            assert_eq!(
3356                view.selection_ranges(cx),
3357                &[
3358                    DisplayPoint::new(0, 9)..DisplayPoint::new(0, 9),
3359                    DisplayPoint::new(2, 2)..DisplayPoint::new(2, 2),
3360                ]
3361            );
3362        });
3363    }
3364
3365    #[gpui::test]
3366    fn test_backspace(cx: &mut gpui::MutableAppContext) {
3367        let buffer = cx.add_model(|cx| {
3368            Buffer::new(
3369                0,
3370                "one two three\nfour five six\nseven eight nine\nten\n",
3371                cx,
3372            )
3373        });
3374        let settings = settings::channel(&cx.font_cache()).unwrap().1;
3375        let (_, view) = cx.add_window(|cx| Editor::for_buffer(buffer.clone(), settings, cx));
3376
3377        view.update(cx, |view, cx| {
3378            view.select_display_ranges(
3379                &[
3380                    // an empty selection - the preceding character is deleted
3381                    DisplayPoint::new(0, 2)..DisplayPoint::new(0, 2),
3382                    // one character selected - it is deleted
3383                    DisplayPoint::new(1, 4)..DisplayPoint::new(1, 3),
3384                    // a line suffix selected - it is deleted
3385                    DisplayPoint::new(2, 6)..DisplayPoint::new(3, 0),
3386                ],
3387                cx,
3388            )
3389            .unwrap();
3390            view.backspace(&(), cx);
3391        });
3392
3393        assert_eq!(
3394            buffer.read(cx).text(),
3395            "oe two three\nfou five six\nseven ten\n"
3396        );
3397    }
3398
3399    #[gpui::test]
3400    fn test_delete(cx: &mut gpui::MutableAppContext) {
3401        let buffer = cx.add_model(|cx| {
3402            Buffer::new(
3403                0,
3404                "one two three\nfour five six\nseven eight nine\nten\n",
3405                cx,
3406            )
3407        });
3408        let settings = settings::channel(&cx.font_cache()).unwrap().1;
3409        let (_, view) = cx.add_window(|cx| Editor::for_buffer(buffer.clone(), settings, cx));
3410
3411        view.update(cx, |view, cx| {
3412            view.select_display_ranges(
3413                &[
3414                    // an empty selection - the following character is deleted
3415                    DisplayPoint::new(0, 2)..DisplayPoint::new(0, 2),
3416                    // one character selected - it is deleted
3417                    DisplayPoint::new(1, 4)..DisplayPoint::new(1, 3),
3418                    // a line suffix selected - it is deleted
3419                    DisplayPoint::new(2, 6)..DisplayPoint::new(3, 0),
3420                ],
3421                cx,
3422            )
3423            .unwrap();
3424            view.delete(&(), cx);
3425        });
3426
3427        assert_eq!(
3428            buffer.read(cx).text(),
3429            "on two three\nfou five six\nseven ten\n"
3430        );
3431    }
3432
3433    #[gpui::test]
3434    fn test_delete_line(cx: &mut gpui::MutableAppContext) {
3435        let settings = settings::channel(&cx.font_cache()).unwrap().1;
3436        let buffer = cx.add_model(|cx| Buffer::new(0, "abc\ndef\nghi\n", cx));
3437        let (_, view) = cx.add_window(|cx| Editor::for_buffer(buffer, settings, cx));
3438        view.update(cx, |view, cx| {
3439            view.select_display_ranges(
3440                &[
3441                    DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1),
3442                    DisplayPoint::new(1, 0)..DisplayPoint::new(1, 1),
3443                    DisplayPoint::new(3, 0)..DisplayPoint::new(3, 0),
3444                ],
3445                cx,
3446            )
3447            .unwrap();
3448            view.delete_line(&(), cx);
3449            assert_eq!(view.text(cx), "ghi");
3450            assert_eq!(
3451                view.selection_ranges(cx),
3452                vec![
3453                    DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0),
3454                    DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1)
3455                ]
3456            );
3457        });
3458
3459        let settings = settings::channel(&cx.font_cache()).unwrap().1;
3460        let buffer = cx.add_model(|cx| Buffer::new(0, "abc\ndef\nghi\n", cx));
3461        let (_, view) = cx.add_window(|cx| Editor::for_buffer(buffer, settings, cx));
3462        view.update(cx, |view, cx| {
3463            view.select_display_ranges(&[DisplayPoint::new(2, 0)..DisplayPoint::new(0, 1)], cx)
3464                .unwrap();
3465            view.delete_line(&(), cx);
3466            assert_eq!(view.text(cx), "ghi\n");
3467            assert_eq!(
3468                view.selection_ranges(cx),
3469                vec![DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1)]
3470            );
3471        });
3472    }
3473
3474    #[gpui::test]
3475    fn test_duplicate_line(cx: &mut gpui::MutableAppContext) {
3476        let settings = settings::channel(&cx.font_cache()).unwrap().1;
3477        let buffer = cx.add_model(|cx| Buffer::new(0, "abc\ndef\nghi\n", cx));
3478        let (_, view) = cx.add_window(|cx| Editor::for_buffer(buffer, settings, cx));
3479        view.update(cx, |view, cx| {
3480            view.select_display_ranges(
3481                &[
3482                    DisplayPoint::new(0, 0)..DisplayPoint::new(0, 1),
3483                    DisplayPoint::new(0, 2)..DisplayPoint::new(0, 2),
3484                    DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0),
3485                    DisplayPoint::new(3, 0)..DisplayPoint::new(3, 0),
3486                ],
3487                cx,
3488            )
3489            .unwrap();
3490            view.duplicate_line(&(), cx);
3491            assert_eq!(view.text(cx), "abc\nabc\ndef\ndef\nghi\n\n");
3492            assert_eq!(
3493                view.selection_ranges(cx),
3494                vec![
3495                    DisplayPoint::new(1, 0)..DisplayPoint::new(1, 1),
3496                    DisplayPoint::new(1, 2)..DisplayPoint::new(1, 2),
3497                    DisplayPoint::new(3, 0)..DisplayPoint::new(3, 0),
3498                    DisplayPoint::new(6, 0)..DisplayPoint::new(6, 0),
3499                ]
3500            );
3501        });
3502
3503        let settings = settings::channel(&cx.font_cache()).unwrap().1;
3504        let buffer = cx.add_model(|cx| Buffer::new(0, "abc\ndef\nghi\n", cx));
3505        let (_, view) = cx.add_window(|cx| Editor::for_buffer(buffer, settings, cx));
3506        view.update(cx, |view, cx| {
3507            view.select_display_ranges(
3508                &[
3509                    DisplayPoint::new(0, 1)..DisplayPoint::new(1, 1),
3510                    DisplayPoint::new(1, 2)..DisplayPoint::new(2, 1),
3511                ],
3512                cx,
3513            )
3514            .unwrap();
3515            view.duplicate_line(&(), cx);
3516            assert_eq!(view.text(cx), "abc\ndef\nghi\nabc\ndef\nghi\n");
3517            assert_eq!(
3518                view.selection_ranges(cx),
3519                vec![
3520                    DisplayPoint::new(3, 1)..DisplayPoint::new(4, 1),
3521                    DisplayPoint::new(4, 2)..DisplayPoint::new(5, 1),
3522                ]
3523            );
3524        });
3525    }
3526
3527    #[gpui::test]
3528    fn test_move_line_up_down(cx: &mut gpui::MutableAppContext) {
3529        let settings = settings::channel(&cx.font_cache()).unwrap().1;
3530        let buffer = cx.add_model(|cx| Buffer::new(0, sample_text(10, 5), cx));
3531        let (_, view) = cx.add_window(|cx| Editor::for_buffer(buffer, settings, cx));
3532        view.update(cx, |view, cx| {
3533            view.fold_ranges(
3534                vec![
3535                    Point::new(0, 2)..Point::new(1, 2),
3536                    Point::new(2, 3)..Point::new(4, 1),
3537                    Point::new(7, 0)..Point::new(8, 4),
3538                ],
3539                cx,
3540            );
3541            view.select_display_ranges(
3542                &[
3543                    DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1),
3544                    DisplayPoint::new(3, 1)..DisplayPoint::new(3, 1),
3545                    DisplayPoint::new(3, 2)..DisplayPoint::new(4, 3),
3546                    DisplayPoint::new(5, 0)..DisplayPoint::new(5, 2),
3547                ],
3548                cx,
3549            )
3550            .unwrap();
3551            assert_eq!(view.text(cx), "aa…bbb\nccc…eeee\nfffff\nggggg\n…i\njjjjj");
3552
3553            view.move_line_up(&(), cx);
3554            assert_eq!(view.text(cx), "aa…bbb\nccc…eeee\nggggg\n…i\njjjjj\nfffff");
3555            assert_eq!(
3556                view.selection_ranges(cx),
3557                vec![
3558                    DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1),
3559                    DisplayPoint::new(2, 1)..DisplayPoint::new(2, 1),
3560                    DisplayPoint::new(2, 2)..DisplayPoint::new(3, 3),
3561                    DisplayPoint::new(4, 0)..DisplayPoint::new(4, 2)
3562                ]
3563            );
3564        });
3565
3566        view.update(cx, |view, cx| {
3567            view.move_line_down(&(), cx);
3568            assert_eq!(view.text(cx), "ccc…eeee\naa…bbb\nfffff\nggggg\n…i\njjjjj");
3569            assert_eq!(
3570                view.selection_ranges(cx),
3571                vec![
3572                    DisplayPoint::new(1, 1)..DisplayPoint::new(1, 1),
3573                    DisplayPoint::new(3, 1)..DisplayPoint::new(3, 1),
3574                    DisplayPoint::new(3, 2)..DisplayPoint::new(4, 3),
3575                    DisplayPoint::new(5, 0)..DisplayPoint::new(5, 2)
3576                ]
3577            );
3578        });
3579
3580        view.update(cx, |view, cx| {
3581            view.move_line_down(&(), cx);
3582            assert_eq!(view.text(cx), "ccc…eeee\nfffff\naa…bbb\nggggg\n…i\njjjjj");
3583            assert_eq!(
3584                view.selection_ranges(cx),
3585                vec![
3586                    DisplayPoint::new(2, 1)..DisplayPoint::new(2, 1),
3587                    DisplayPoint::new(3, 1)..DisplayPoint::new(3, 1),
3588                    DisplayPoint::new(3, 2)..DisplayPoint::new(4, 3),
3589                    DisplayPoint::new(5, 0)..DisplayPoint::new(5, 2)
3590                ]
3591            );
3592        });
3593
3594        view.update(cx, |view, cx| {
3595            view.move_line_up(&(), cx);
3596            assert_eq!(view.text(cx), "ccc…eeee\naa…bbb\nggggg\n…i\njjjjj\nfffff");
3597            assert_eq!(
3598                view.selection_ranges(cx),
3599                vec![
3600                    DisplayPoint::new(1, 1)..DisplayPoint::new(1, 1),
3601                    DisplayPoint::new(2, 1)..DisplayPoint::new(2, 1),
3602                    DisplayPoint::new(2, 2)..DisplayPoint::new(3, 3),
3603                    DisplayPoint::new(4, 0)..DisplayPoint::new(4, 2)
3604                ]
3605            );
3606        });
3607    }
3608
3609    #[gpui::test]
3610    fn test_clipboard(cx: &mut gpui::MutableAppContext) {
3611        let buffer = cx.add_model(|cx| Buffer::new(0, "one two three four five six ", cx));
3612        let settings = settings::channel(&cx.font_cache()).unwrap().1;
3613        let view = cx
3614            .add_window(|cx| Editor::for_buffer(buffer.clone(), settings, cx))
3615            .1;
3616
3617        // Cut with three selections. Clipboard text is divided into three slices.
3618        view.update(cx, |view, cx| {
3619            view.select_ranges(vec![0..4, 8..14, 19..24], false, cx);
3620            view.cut(&(), cx);
3621            assert_eq!(view.text(cx), "two four six ");
3622        });
3623
3624        // Paste with three cursors. Each cursor pastes one slice of the clipboard text.
3625        view.update(cx, |view, cx| {
3626            view.select_ranges(vec![4..4, 9..9, 13..13], false, cx);
3627            view.paste(&(), cx);
3628            assert_eq!(view.text(cx), "two one four three six five ");
3629            assert_eq!(
3630                view.selection_ranges(cx),
3631                &[
3632                    DisplayPoint::new(0, 8)..DisplayPoint::new(0, 8),
3633                    DisplayPoint::new(0, 19)..DisplayPoint::new(0, 19),
3634                    DisplayPoint::new(0, 28)..DisplayPoint::new(0, 28)
3635                ]
3636            );
3637        });
3638
3639        // Paste again but with only two cursors. Since the number of cursors doesn't
3640        // match the number of slices in the clipboard, the entire clipboard text
3641        // is pasted at each cursor.
3642        view.update(cx, |view, cx| {
3643            view.select_ranges(vec![0..0, 28..28], false, cx);
3644            view.insert(&"( ".to_string(), cx);
3645            view.paste(&(), cx);
3646            view.insert(&") ".to_string(), cx);
3647            assert_eq!(
3648                view.text(cx),
3649                "( one three five ) two one four three six five ( one three five ) "
3650            );
3651        });
3652
3653        view.update(cx, |view, cx| {
3654            view.select_ranges(vec![0..0], false, cx);
3655            view.insert(&"123\n4567\n89\n".to_string(), cx);
3656            assert_eq!(
3657                view.text(cx),
3658                "123\n4567\n89\n( one three five ) two one four three six five ( one three five ) "
3659            );
3660        });
3661
3662        // Cut with three selections, one of which is full-line.
3663        view.update(cx, |view, cx| {
3664            view.select_display_ranges(
3665                &[
3666                    DisplayPoint::new(0, 1)..DisplayPoint::new(0, 2),
3667                    DisplayPoint::new(1, 1)..DisplayPoint::new(1, 1),
3668                    DisplayPoint::new(2, 0)..DisplayPoint::new(2, 1),
3669                ],
3670                cx,
3671            )
3672            .unwrap();
3673            view.cut(&(), cx);
3674            assert_eq!(
3675                view.text(cx),
3676                "13\n9\n( one three five ) two one four three six five ( one three five ) "
3677            );
3678        });
3679
3680        // Paste with three selections, noticing how the copied selection that was full-line
3681        // gets inserted before the second cursor.
3682        view.update(cx, |view, cx| {
3683            view.select_display_ranges(
3684                &[
3685                    DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1),
3686                    DisplayPoint::new(1, 1)..DisplayPoint::new(1, 1),
3687                    DisplayPoint::new(2, 2)..DisplayPoint::new(2, 3),
3688                ],
3689                cx,
3690            )
3691            .unwrap();
3692            view.paste(&(), cx);
3693            assert_eq!(
3694                view.text(cx),
3695                "123\n4567\n9\n( 8ne three five ) two one four three six five ( one three five ) "
3696            );
3697            assert_eq!(
3698                view.selection_ranges(cx),
3699                &[
3700                    DisplayPoint::new(0, 2)..DisplayPoint::new(0, 2),
3701                    DisplayPoint::new(2, 1)..DisplayPoint::new(2, 1),
3702                    DisplayPoint::new(3, 3)..DisplayPoint::new(3, 3),
3703                ]
3704            );
3705        });
3706
3707        // Copy with a single cursor only, which writes the whole line into the clipboard.
3708        view.update(cx, |view, cx| {
3709            view.select_display_ranges(&[DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1)], cx)
3710                .unwrap();
3711            view.copy(&(), cx);
3712        });
3713
3714        // Paste with three selections, noticing how the copied full-line selection is inserted
3715        // before the empty selections but replaces the selection that is non-empty.
3716        view.update(cx, |view, cx| {
3717            view.select_display_ranges(
3718                &[
3719                    DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1),
3720                    DisplayPoint::new(1, 0)..DisplayPoint::new(1, 2),
3721                    DisplayPoint::new(2, 1)..DisplayPoint::new(2, 1),
3722                ],
3723                cx,
3724            )
3725            .unwrap();
3726            view.paste(&(), cx);
3727            assert_eq!(
3728                view.text(cx),
3729                "123\n123\n123\n67\n123\n9\n( 8ne three five ) two one four three six five ( one three five ) "
3730            );
3731            assert_eq!(
3732                view.selection_ranges(cx),
3733                &[
3734                    DisplayPoint::new(1, 1)..DisplayPoint::new(1, 1),
3735                    DisplayPoint::new(3, 0)..DisplayPoint::new(3, 0),
3736                    DisplayPoint::new(5, 1)..DisplayPoint::new(5, 1),
3737                ]
3738            );
3739        });
3740    }
3741
3742    #[gpui::test]
3743    fn test_select_all(cx: &mut gpui::MutableAppContext) {
3744        let buffer = cx.add_model(|cx| Buffer::new(0, "abc\nde\nfgh", cx));
3745        let settings = settings::channel(&cx.font_cache()).unwrap().1;
3746        let (_, view) = cx.add_window(|cx| Editor::for_buffer(buffer, settings, cx));
3747        view.update(cx, |view, cx| {
3748            view.select_all(&(), cx);
3749            assert_eq!(
3750                view.selection_ranges(cx),
3751                &[DisplayPoint::new(0, 0)..DisplayPoint::new(2, 3)]
3752            );
3753        });
3754    }
3755
3756    #[gpui::test]
3757    fn test_select_line(cx: &mut gpui::MutableAppContext) {
3758        let settings = settings::channel(&cx.font_cache()).unwrap().1;
3759        let buffer = cx.add_model(|cx| Buffer::new(0, sample_text(6, 5), cx));
3760        let (_, view) = cx.add_window(|cx| Editor::for_buffer(buffer, settings, cx));
3761        view.update(cx, |view, cx| {
3762            view.select_display_ranges(
3763                &[
3764                    DisplayPoint::new(0, 0)..DisplayPoint::new(0, 1),
3765                    DisplayPoint::new(0, 2)..DisplayPoint::new(0, 2),
3766                    DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0),
3767                    DisplayPoint::new(4, 2)..DisplayPoint::new(4, 2),
3768                ],
3769                cx,
3770            )
3771            .unwrap();
3772            view.select_line(&(), cx);
3773            assert_eq!(
3774                view.selection_ranges(cx),
3775                vec![
3776                    DisplayPoint::new(0, 0)..DisplayPoint::new(2, 0),
3777                    DisplayPoint::new(4, 0)..DisplayPoint::new(5, 0),
3778                ]
3779            );
3780        });
3781
3782        view.update(cx, |view, cx| {
3783            view.select_line(&(), cx);
3784            assert_eq!(
3785                view.selection_ranges(cx),
3786                vec![
3787                    DisplayPoint::new(0, 0)..DisplayPoint::new(3, 0),
3788                    DisplayPoint::new(4, 0)..DisplayPoint::new(5, 5),
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![DisplayPoint::new(0, 0)..DisplayPoint::new(5, 5)]
3798            );
3799        });
3800    }
3801
3802    #[gpui::test]
3803    fn test_split_selection_into_lines(cx: &mut gpui::MutableAppContext) {
3804        let settings = settings::channel(&cx.font_cache()).unwrap().1;
3805        let buffer = cx.add_model(|cx| Buffer::new(0, sample_text(9, 5), cx));
3806        let (_, view) = cx.add_window(|cx| Editor::for_buffer(buffer, settings, cx));
3807        view.update(cx, |view, cx| {
3808            view.fold_ranges(
3809                vec![
3810                    Point::new(0, 2)..Point::new(1, 2),
3811                    Point::new(2, 3)..Point::new(4, 1),
3812                    Point::new(7, 0)..Point::new(8, 4),
3813                ],
3814                cx,
3815            );
3816            view.select_display_ranges(
3817                &[
3818                    DisplayPoint::new(0, 0)..DisplayPoint::new(0, 1),
3819                    DisplayPoint::new(0, 2)..DisplayPoint::new(0, 2),
3820                    DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0),
3821                    DisplayPoint::new(4, 4)..DisplayPoint::new(4, 4),
3822                ],
3823                cx,
3824            )
3825            .unwrap();
3826            assert_eq!(view.text(cx), "aa…bbb\nccc…eeee\nfffff\nggggg\n…i");
3827        });
3828
3829        view.update(cx, |view, cx| {
3830            view.split_selection_into_lines(&(), cx);
3831            assert_eq!(view.text(cx), "aa…bbb\nccc…eeee\nfffff\nggggg\n…i");
3832            assert_eq!(
3833                view.selection_ranges(cx),
3834                [
3835                    DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1),
3836                    DisplayPoint::new(0, 2)..DisplayPoint::new(0, 2),
3837                    DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0),
3838                    DisplayPoint::new(4, 4)..DisplayPoint::new(4, 4)
3839                ]
3840            );
3841        });
3842
3843        view.update(cx, |view, cx| {
3844            view.select_display_ranges(&[DisplayPoint::new(4, 0)..DisplayPoint::new(0, 1)], cx)
3845                .unwrap();
3846            view.split_selection_into_lines(&(), cx);
3847            assert_eq!(
3848                view.text(cx),
3849                "aaaaa\nbbbbb\nccccc\nddddd\neeeee\nfffff\nggggg\n…i"
3850            );
3851            assert_eq!(
3852                view.selection_ranges(cx),
3853                [
3854                    DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1),
3855                    DisplayPoint::new(1, 5)..DisplayPoint::new(1, 5),
3856                    DisplayPoint::new(2, 5)..DisplayPoint::new(2, 5),
3857                    DisplayPoint::new(3, 5)..DisplayPoint::new(3, 5),
3858                    DisplayPoint::new(4, 5)..DisplayPoint::new(4, 5),
3859                    DisplayPoint::new(5, 5)..DisplayPoint::new(5, 5),
3860                    DisplayPoint::new(6, 5)..DisplayPoint::new(6, 5),
3861                    DisplayPoint::new(7, 0)..DisplayPoint::new(7, 0)
3862                ]
3863            );
3864        });
3865    }
3866
3867    #[gpui::test]
3868    fn test_add_selection_above_below(cx: &mut gpui::MutableAppContext) {
3869        let settings = settings::channel(&cx.font_cache()).unwrap().1;
3870        let buffer = cx.add_model(|cx| Buffer::new(0, "abc\ndefghi\n\njk\nlmno\n", cx));
3871        let (_, view) = cx.add_window(|cx| Editor::for_buffer(buffer, settings, cx));
3872
3873        view.update(cx, |view, cx| {
3874            view.select_display_ranges(&[DisplayPoint::new(1, 3)..DisplayPoint::new(1, 3)], cx)
3875                .unwrap();
3876        });
3877        view.update(cx, |view, cx| {
3878            view.add_selection_above(&(), cx);
3879            assert_eq!(
3880                view.selection_ranges(cx),
3881                vec![
3882                    DisplayPoint::new(0, 3)..DisplayPoint::new(0, 3),
3883                    DisplayPoint::new(1, 3)..DisplayPoint::new(1, 3)
3884                ]
3885            );
3886        });
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_below(&(), cx);
3901            assert_eq!(
3902                view.selection_ranges(cx),
3903                vec![DisplayPoint::new(1, 3)..DisplayPoint::new(1, 3)]
3904            );
3905        });
3906
3907        view.update(cx, |view, cx| {
3908            view.add_selection_below(&(), cx);
3909            assert_eq!(
3910                view.selection_ranges(cx),
3911                vec![
3912                    DisplayPoint::new(1, 3)..DisplayPoint::new(1, 3),
3913                    DisplayPoint::new(4, 3)..DisplayPoint::new(4, 3)
3914                ]
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.select_display_ranges(&[DisplayPoint::new(1, 4)..DisplayPoint::new(1, 3)], cx)
3931                .unwrap();
3932        });
3933        view.update(cx, |view, cx| {
3934            view.add_selection_below(&(), cx);
3935            assert_eq!(
3936                view.selection_ranges(cx),
3937                vec![
3938                    DisplayPoint::new(1, 4)..DisplayPoint::new(1, 3),
3939                    DisplayPoint::new(4, 4)..DisplayPoint::new(4, 3)
3940                ]
3941            );
3942        });
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_above(&(), cx);
3957            assert_eq!(
3958                view.selection_ranges(cx),
3959                vec![DisplayPoint::new(1, 4)..DisplayPoint::new(1, 3)]
3960            );
3961        });
3962
3963        view.update(cx, |view, cx| {
3964            view.add_selection_above(&(), cx);
3965            assert_eq!(
3966                view.selection_ranges(cx),
3967                vec![DisplayPoint::new(1, 4)..DisplayPoint::new(1, 3)]
3968            );
3969        });
3970
3971        view.update(cx, |view, cx| {
3972            view.select_display_ranges(&[DisplayPoint::new(0, 1)..DisplayPoint::new(1, 4)], cx)
3973                .unwrap();
3974            view.add_selection_below(&(), cx);
3975            assert_eq!(
3976                view.selection_ranges(cx),
3977                vec![
3978                    DisplayPoint::new(0, 1)..DisplayPoint::new(0, 3),
3979                    DisplayPoint::new(1, 1)..DisplayPoint::new(1, 4),
3980                    DisplayPoint::new(3, 1)..DisplayPoint::new(3, 2),
3981                ]
3982            );
3983        });
3984
3985        view.update(cx, |view, cx| {
3986            view.add_selection_below(&(), cx);
3987            assert_eq!(
3988                view.selection_ranges(cx),
3989                vec![
3990                    DisplayPoint::new(0, 1)..DisplayPoint::new(0, 3),
3991                    DisplayPoint::new(1, 1)..DisplayPoint::new(1, 4),
3992                    DisplayPoint::new(3, 1)..DisplayPoint::new(3, 2),
3993                    DisplayPoint::new(4, 1)..DisplayPoint::new(4, 4),
3994                ]
3995            );
3996        });
3997
3998        view.update(cx, |view, cx| {
3999            view.add_selection_above(&(), cx);
4000            assert_eq!(
4001                view.selection_ranges(cx),
4002                vec![
4003                    DisplayPoint::new(0, 1)..DisplayPoint::new(0, 3),
4004                    DisplayPoint::new(1, 1)..DisplayPoint::new(1, 4),
4005                    DisplayPoint::new(3, 1)..DisplayPoint::new(3, 2),
4006                ]
4007            );
4008        });
4009
4010        view.update(cx, |view, cx| {
4011            view.select_display_ranges(&[DisplayPoint::new(4, 3)..DisplayPoint::new(1, 1)], cx)
4012                .unwrap();
4013        });
4014        view.update(cx, |view, cx| {
4015            view.add_selection_above(&(), cx);
4016            assert_eq!(
4017                view.selection_ranges(cx),
4018                vec![
4019                    DisplayPoint::new(0, 3)..DisplayPoint::new(0, 1),
4020                    DisplayPoint::new(1, 3)..DisplayPoint::new(1, 1),
4021                    DisplayPoint::new(3, 2)..DisplayPoint::new(3, 1),
4022                    DisplayPoint::new(4, 3)..DisplayPoint::new(4, 1),
4023                ]
4024            );
4025        });
4026
4027        view.update(cx, |view, cx| {
4028            view.add_selection_below(&(), cx);
4029            assert_eq!(
4030                view.selection_ranges(cx),
4031                vec![
4032                    DisplayPoint::new(1, 3)..DisplayPoint::new(1, 1),
4033                    DisplayPoint::new(3, 2)..DisplayPoint::new(3, 1),
4034                    DisplayPoint::new(4, 3)..DisplayPoint::new(4, 1),
4035                ]
4036            );
4037        });
4038    }
4039
4040    #[gpui::test]
4041    async fn test_select_larger_smaller_syntax_node(mut cx: gpui::TestAppContext) {
4042        let app_state = cx.read(build_app_state);
4043        let lang = app_state.languages.select_language("z.rs");
4044        let text = r#"
4045            use mod1::mod2::{mod3, mod4};
4046
4047            fn fn_1(param1: bool, param2: &str) {
4048                let var1 = "text";
4049            }
4050        "#
4051        .unindent();
4052        let buffer = cx.add_model(|cx| {
4053            let history = History::new(text.into());
4054            Buffer::from_history(0, history, None, lang.cloned(), cx)
4055        });
4056        let (_, view) =
4057            cx.add_window(|cx| Editor::for_buffer(buffer, app_state.settings.clone(), cx));
4058        view.condition(&cx, |view, cx| !view.buffer.read(cx).is_parsing())
4059            .await;
4060
4061        view.update(&mut cx, |view, cx| {
4062            view.select_display_ranges(
4063                &[
4064                    DisplayPoint::new(0, 25)..DisplayPoint::new(0, 25),
4065                    DisplayPoint::new(2, 24)..DisplayPoint::new(2, 12),
4066                    DisplayPoint::new(3, 18)..DisplayPoint::new(3, 18),
4067                ],
4068                cx,
4069            )
4070            .unwrap();
4071            view.select_larger_syntax_node(&(), cx);
4072        });
4073        assert_eq!(
4074            view.update(&mut cx, |view, cx| view.selection_ranges(cx)),
4075            &[
4076                DisplayPoint::new(0, 23)..DisplayPoint::new(0, 27),
4077                DisplayPoint::new(2, 35)..DisplayPoint::new(2, 7),
4078                DisplayPoint::new(3, 15)..DisplayPoint::new(3, 21),
4079            ]
4080        );
4081
4082        view.update(&mut cx, |view, cx| {
4083            view.select_larger_syntax_node(&(), cx);
4084        });
4085        assert_eq!(
4086            view.update(&mut cx, |view, cx| view.selection_ranges(cx)),
4087            &[
4088                DisplayPoint::new(0, 16)..DisplayPoint::new(0, 28),
4089                DisplayPoint::new(4, 1)..DisplayPoint::new(2, 0),
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            &[DisplayPoint::new(5, 0)..DisplayPoint::new(0, 0)]
4099        );
4100
4101        // Trying to expand the selected syntax node one more time has no effect.
4102        view.update(&mut cx, |view, cx| {
4103            view.select_larger_syntax_node(&(), cx);
4104        });
4105        assert_eq!(
4106            view.update(&mut cx, |view, cx| view.selection_ranges(cx)),
4107            &[DisplayPoint::new(5, 0)..DisplayPoint::new(0, 0)]
4108        );
4109
4110        view.update(&mut cx, |view, cx| {
4111            view.select_smaller_syntax_node(&(), cx);
4112        });
4113        assert_eq!(
4114            view.update(&mut cx, |view, cx| view.selection_ranges(cx)),
4115            &[
4116                DisplayPoint::new(0, 16)..DisplayPoint::new(0, 28),
4117                DisplayPoint::new(4, 1)..DisplayPoint::new(2, 0),
4118            ]
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, 23)..DisplayPoint::new(0, 27),
4128                DisplayPoint::new(2, 35)..DisplayPoint::new(2, 7),
4129                DisplayPoint::new(3, 15)..DisplayPoint::new(3, 21),
4130            ]
4131        );
4132
4133        view.update(&mut cx, |view, cx| {
4134            view.select_smaller_syntax_node(&(), cx);
4135        });
4136        assert_eq!(
4137            view.update(&mut cx, |view, cx| view.selection_ranges(cx)),
4138            &[
4139                DisplayPoint::new(0, 25)..DisplayPoint::new(0, 25),
4140                DisplayPoint::new(2, 24)..DisplayPoint::new(2, 12),
4141                DisplayPoint::new(3, 18)..DisplayPoint::new(3, 18),
4142            ]
4143        );
4144
4145        // Trying to shrink the selected syntax node one more time has no effect.
4146        view.update(&mut cx, |view, cx| {
4147            view.select_smaller_syntax_node(&(), cx);
4148        });
4149        assert_eq!(
4150            view.update(&mut cx, |view, cx| view.selection_ranges(cx)),
4151            &[
4152                DisplayPoint::new(0, 25)..DisplayPoint::new(0, 25),
4153                DisplayPoint::new(2, 24)..DisplayPoint::new(2, 12),
4154                DisplayPoint::new(3, 18)..DisplayPoint::new(3, 18),
4155            ]
4156        );
4157
4158        // Ensure that we keep expanding the selection if the larger selection starts or ends within
4159        // a fold.
4160        view.update(&mut cx, |view, cx| {
4161            view.fold_ranges(
4162                vec![
4163                    Point::new(0, 21)..Point::new(0, 24),
4164                    Point::new(3, 20)..Point::new(3, 22),
4165                ],
4166                cx,
4167            );
4168            view.select_larger_syntax_node(&(), cx);
4169        });
4170        assert_eq!(
4171            view.update(&mut cx, |view, cx| view.selection_ranges(cx)),
4172            &[
4173                DisplayPoint::new(0, 16)..DisplayPoint::new(0, 28),
4174                DisplayPoint::new(2, 35)..DisplayPoint::new(2, 7),
4175                DisplayPoint::new(3, 4)..DisplayPoint::new(3, 23),
4176            ]
4177        );
4178    }
4179
4180    impl Editor {
4181        fn selection_ranges(&self, cx: &mut MutableAppContext) -> Vec<Range<DisplayPoint>> {
4182            self.selections_in_range(
4183                self.selection_set_id,
4184                DisplayPoint::zero()..self.max_point(cx),
4185                cx,
4186            )
4187            .collect::<Vec<_>>()
4188        }
4189    }
4190
4191    fn empty_range(row: usize, column: usize) -> Range<DisplayPoint> {
4192        let point = DisplayPoint::new(row as u32, column as u32);
4193        point..point
4194    }
4195}
4196
4197trait RangeExt<T> {
4198    fn sorted(&self) -> Range<T>;
4199    fn to_inclusive(&self) -> RangeInclusive<T>;
4200}
4201
4202impl<T: Ord + Clone> RangeExt<T> for Range<T> {
4203    fn sorted(&self) -> Self {
4204        cmp::min(&self.start, &self.end).clone()..cmp::max(&self.start, &self.end).clone()
4205    }
4206
4207    fn to_inclusive(&self) -> RangeInclusive<T> {
4208        self.start.clone()..=self.end.clone()
4209    }
4210}