editor.rs

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