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