buffer_view.rs

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