editor.rs

   1mod blink_manager;
   2pub mod display_map;
   3mod element;
   4mod highlight_matching_bracket;
   5mod hover_popover;
   6pub mod items;
   7mod link_go_to_definition;
   8mod mouse_context_menu;
   9pub mod movement;
  10mod multi_buffer;
  11pub mod selections_collection;
  12
  13#[cfg(test)]
  14mod editor_tests;
  15#[cfg(any(test, feature = "test-support"))]
  16pub mod test;
  17
  18use aho_corasick::AhoCorasick;
  19use anyhow::Result;
  20use blink_manager::BlinkManager;
  21use clock::ReplicaId;
  22use collections::{BTreeMap, Bound, HashMap, HashSet, VecDeque};
  23pub use display_map::DisplayPoint;
  24use display_map::*;
  25pub use element::*;
  26use futures::FutureExt;
  27use fuzzy::{StringMatch, StringMatchCandidate};
  28use gpui::{
  29    actions,
  30    color::Color,
  31    elements::*,
  32    executor,
  33    fonts::{self, HighlightStyle, TextStyle},
  34    geometry::vector::{vec2f, Vector2F},
  35    impl_actions, impl_internal_actions,
  36    platform::CursorStyle,
  37    serde_json::json,
  38    text_layout, AnyViewHandle, AppContext, AsyncAppContext, Axis, ClipboardItem, Element,
  39    ElementBox, Entity, ModelHandle, MouseButton, MutableAppContext, RenderContext, Subscription,
  40    Task, View, ViewContext, ViewHandle, WeakViewHandle,
  41};
  42use highlight_matching_bracket::refresh_matching_bracket_highlights;
  43use hover_popover::{hide_hover, HoverState};
  44pub use items::MAX_TAB_TITLE_LEN;
  45pub use language::{char_kind, CharKind};
  46use language::{
  47    AutoindentMode, BracketPair, Buffer, CodeAction, CodeLabel, Completion, CursorShape,
  48    Diagnostic, DiagnosticSeverity, IndentKind, IndentSize, Language, OffsetRangeExt, OffsetUtf16,
  49    Point, Selection, SelectionGoal, TransactionId,
  50};
  51use link_go_to_definition::{
  52    hide_link_definition, show_link_definition, LinkDefinitionKind, LinkGoToDefinitionState,
  53};
  54pub use multi_buffer::{
  55    Anchor, AnchorRangeExt, ExcerptId, ExcerptRange, MultiBuffer, MultiBufferSnapshot, ToOffset,
  56    ToPoint,
  57};
  58use multi_buffer::{MultiBufferChunks, ToOffsetUtf16};
  59use ordered_float::OrderedFloat;
  60use project::{FormatTrigger, LocationLink, Project, ProjectPath, ProjectTransaction};
  61use selections_collection::{resolve_multiple, MutableSelectionsCollection, SelectionsCollection};
  62use serde::{Deserialize, Serialize};
  63use settings::Settings;
  64use smallvec::SmallVec;
  65use smol::Timer;
  66use snippet::Snippet;
  67use std::{
  68    any::TypeId,
  69    borrow::Cow,
  70    cmp::{self, Ordering, Reverse},
  71    mem,
  72    num::NonZeroU32,
  73    ops::{Deref, DerefMut, Range, RangeInclusive},
  74    sync::Arc,
  75    time::{Duration, Instant},
  76};
  77pub use sum_tree::Bias;
  78use theme::{DiagnosticStyle, Theme};
  79use util::{post_inc, ResultExt, TryFutureExt};
  80use workspace::{ItemNavHistory, Workspace};
  81
  82const CURSOR_BLINK_INTERVAL: Duration = Duration::from_millis(500);
  83const SCROLLBAR_SHOW_INTERVAL: Duration = Duration::from_secs(1);
  84const MAX_LINE_LEN: usize = 1024;
  85const MIN_NAVIGATION_HISTORY_ROW_DELTA: i64 = 10;
  86const MAX_SELECTION_HISTORY_LEN: usize = 1024;
  87pub const SCROLL_EVENT_SEPARATION: Duration = Duration::from_millis(28);
  88
  89pub const FORMAT_TIMEOUT: Duration = Duration::from_secs(2);
  90
  91#[derive(Clone, Deserialize, PartialEq, Default)]
  92pub struct SelectNext {
  93    #[serde(default)]
  94    pub replace_newest: bool,
  95}
  96
  97#[derive(Clone, PartialEq)]
  98pub struct Scroll {
  99    pub scroll_position: Vector2F,
 100    pub axis: Option<Axis>,
 101}
 102
 103#[derive(Clone, PartialEq)]
 104pub struct Select(pub SelectPhase);
 105
 106#[derive(Clone, Debug, PartialEq)]
 107pub struct Jump {
 108    path: ProjectPath,
 109    position: Point,
 110    anchor: language::Anchor,
 111}
 112
 113#[derive(Clone, Deserialize, PartialEq)]
 114pub struct SelectToBeginningOfLine {
 115    #[serde(default)]
 116    stop_at_soft_wraps: bool,
 117}
 118
 119#[derive(Clone, Default, Deserialize, PartialEq)]
 120pub struct MovePageUp {
 121    #[serde(default)]
 122    center_cursor: bool,
 123}
 124
 125#[derive(Clone, Default, Deserialize, PartialEq)]
 126pub struct MovePageDown {
 127    #[serde(default)]
 128    center_cursor: bool,
 129}
 130
 131#[derive(Clone, Deserialize, PartialEq)]
 132pub struct SelectToEndOfLine {
 133    #[serde(default)]
 134    stop_at_soft_wraps: bool,
 135}
 136
 137#[derive(Clone, Deserialize, PartialEq)]
 138pub struct ToggleCodeActions {
 139    #[serde(default)]
 140    pub deployed_from_indicator: bool,
 141}
 142
 143#[derive(Clone, Default, Deserialize, PartialEq)]
 144pub struct ConfirmCompletion {
 145    #[serde(default)]
 146    pub item_ix: Option<usize>,
 147}
 148
 149#[derive(Clone, Default, Deserialize, PartialEq)]
 150pub struct ConfirmCodeAction {
 151    #[serde(default)]
 152    pub item_ix: Option<usize>,
 153}
 154
 155actions!(
 156    editor,
 157    [
 158        Cancel,
 159        Backspace,
 160        Delete,
 161        Newline,
 162        NewlineBelow,
 163        GoToDiagnostic,
 164        GoToPrevDiagnostic,
 165        Indent,
 166        Outdent,
 167        DeleteLine,
 168        DeleteToPreviousWordStart,
 169        DeleteToPreviousSubwordStart,
 170        DeleteToNextWordEnd,
 171        DeleteToNextSubwordEnd,
 172        DeleteToBeginningOfLine,
 173        DeleteToEndOfLine,
 174        CutToEndOfLine,
 175        DuplicateLine,
 176        MoveLineUp,
 177        MoveLineDown,
 178        Transpose,
 179        Cut,
 180        Copy,
 181        Paste,
 182        Undo,
 183        Redo,
 184        CenterScreen,
 185        MoveUp,
 186        PageUp,
 187        MoveDown,
 188        PageDown,
 189        MoveLeft,
 190        MoveRight,
 191        MoveToPreviousWordStart,
 192        MoveToPreviousSubwordStart,
 193        MoveToNextWordEnd,
 194        MoveToNextSubwordEnd,
 195        MoveToBeginningOfLine,
 196        MoveToEndOfLine,
 197        MoveToBeginning,
 198        MoveToEnd,
 199        SelectUp,
 200        SelectDown,
 201        SelectLeft,
 202        SelectRight,
 203        SelectToPreviousWordStart,
 204        SelectToPreviousSubwordStart,
 205        SelectToNextWordEnd,
 206        SelectToNextSubwordEnd,
 207        SelectToBeginning,
 208        SelectToEnd,
 209        SelectAll,
 210        SelectLine,
 211        SplitSelectionIntoLines,
 212        AddSelectionAbove,
 213        AddSelectionBelow,
 214        Tab,
 215        TabPrev,
 216        ToggleComments,
 217        ShowCharacterPalette,
 218        SelectLargerSyntaxNode,
 219        SelectSmallerSyntaxNode,
 220        GoToDefinition,
 221        GoToTypeDefinition,
 222        MoveToEnclosingBracket,
 223        UndoSelection,
 224        RedoSelection,
 225        FindAllReferences,
 226        Rename,
 227        ConfirmRename,
 228        Fold,
 229        UnfoldLines,
 230        FoldSelectedRanges,
 231        ShowCompletions,
 232        OpenExcerpts,
 233        RestartLanguageServer,
 234        Hover,
 235        Format,
 236    ]
 237);
 238
 239impl_actions!(
 240    editor,
 241    [
 242        SelectNext,
 243        SelectToBeginningOfLine,
 244        SelectToEndOfLine,
 245        ToggleCodeActions,
 246        MovePageUp,
 247        MovePageDown,
 248        ConfirmCompletion,
 249        ConfirmCodeAction,
 250    ]
 251);
 252
 253impl_internal_actions!(editor, [Scroll, Select, Jump]);
 254
 255enum DocumentHighlightRead {}
 256enum DocumentHighlightWrite {}
 257enum InputComposition {}
 258
 259#[derive(Copy, Clone, PartialEq, Eq)]
 260pub enum Direction {
 261    Prev,
 262    Next,
 263}
 264
 265#[derive(Default)]
 266struct ScrollbarAutoHide(bool);
 267
 268pub fn init(cx: &mut MutableAppContext) {
 269    cx.add_action(Editor::new_file);
 270    cx.add_action(Editor::scroll);
 271    cx.add_action(Editor::select);
 272    cx.add_action(Editor::cancel);
 273    cx.add_action(Editor::newline);
 274    cx.add_action(Editor::newline_below);
 275    cx.add_action(Editor::backspace);
 276    cx.add_action(Editor::delete);
 277    cx.add_action(Editor::tab);
 278    cx.add_action(Editor::tab_prev);
 279    cx.add_action(Editor::indent);
 280    cx.add_action(Editor::outdent);
 281    cx.add_action(Editor::delete_line);
 282    cx.add_action(Editor::delete_to_previous_word_start);
 283    cx.add_action(Editor::delete_to_previous_subword_start);
 284    cx.add_action(Editor::delete_to_next_word_end);
 285    cx.add_action(Editor::delete_to_next_subword_end);
 286    cx.add_action(Editor::delete_to_beginning_of_line);
 287    cx.add_action(Editor::delete_to_end_of_line);
 288    cx.add_action(Editor::cut_to_end_of_line);
 289    cx.add_action(Editor::duplicate_line);
 290    cx.add_action(Editor::move_line_up);
 291    cx.add_action(Editor::move_line_down);
 292    cx.add_action(Editor::transpose);
 293    cx.add_action(Editor::cut);
 294    cx.add_action(Editor::copy);
 295    cx.add_action(Editor::paste);
 296    cx.add_action(Editor::undo);
 297    cx.add_action(Editor::redo);
 298    cx.add_action(Editor::move_up);
 299    cx.add_action(Editor::move_page_up);
 300    cx.add_action(Editor::page_up);
 301    cx.add_action(Editor::move_down);
 302    cx.add_action(Editor::move_page_down);
 303    cx.add_action(Editor::page_down);
 304    cx.add_action(Editor::center_screen);
 305    cx.add_action(Editor::move_left);
 306    cx.add_action(Editor::move_right);
 307    cx.add_action(Editor::move_to_previous_word_start);
 308    cx.add_action(Editor::move_to_previous_subword_start);
 309    cx.add_action(Editor::move_to_next_word_end);
 310    cx.add_action(Editor::move_to_next_subword_end);
 311    cx.add_action(Editor::move_to_beginning_of_line);
 312    cx.add_action(Editor::move_to_end_of_line);
 313    cx.add_action(Editor::move_to_beginning);
 314    cx.add_action(Editor::move_to_end);
 315    cx.add_action(Editor::select_up);
 316    cx.add_action(Editor::select_down);
 317    cx.add_action(Editor::select_left);
 318    cx.add_action(Editor::select_right);
 319    cx.add_action(Editor::select_to_previous_word_start);
 320    cx.add_action(Editor::select_to_previous_subword_start);
 321    cx.add_action(Editor::select_to_next_word_end);
 322    cx.add_action(Editor::select_to_next_subword_end);
 323    cx.add_action(Editor::select_to_beginning_of_line);
 324    cx.add_action(Editor::select_to_end_of_line);
 325    cx.add_action(Editor::select_to_beginning);
 326    cx.add_action(Editor::select_to_end);
 327    cx.add_action(Editor::select_all);
 328    cx.add_action(Editor::select_line);
 329    cx.add_action(Editor::split_selection_into_lines);
 330    cx.add_action(Editor::add_selection_above);
 331    cx.add_action(Editor::add_selection_below);
 332    cx.add_action(Editor::select_next);
 333    cx.add_action(Editor::toggle_comments);
 334    cx.add_action(Editor::select_larger_syntax_node);
 335    cx.add_action(Editor::select_smaller_syntax_node);
 336    cx.add_action(Editor::move_to_enclosing_bracket);
 337    cx.add_action(Editor::undo_selection);
 338    cx.add_action(Editor::redo_selection);
 339    cx.add_action(Editor::go_to_diagnostic);
 340    cx.add_action(Editor::go_to_prev_diagnostic);
 341    cx.add_action(Editor::go_to_definition);
 342    cx.add_action(Editor::go_to_type_definition);
 343    cx.add_action(Editor::fold);
 344    cx.add_action(Editor::unfold_lines);
 345    cx.add_action(Editor::fold_selected_ranges);
 346    cx.add_action(Editor::show_completions);
 347    cx.add_action(Editor::toggle_code_actions);
 348    cx.add_action(Editor::open_excerpts);
 349    cx.add_action(Editor::jump);
 350    cx.add_async_action(Editor::format);
 351    cx.add_action(Editor::restart_language_server);
 352    cx.add_action(Editor::show_character_palette);
 353    cx.add_async_action(Editor::confirm_completion);
 354    cx.add_async_action(Editor::confirm_code_action);
 355    cx.add_async_action(Editor::rename);
 356    cx.add_async_action(Editor::confirm_rename);
 357    cx.add_async_action(Editor::find_all_references);
 358
 359    hover_popover::init(cx);
 360    link_go_to_definition::init(cx);
 361    mouse_context_menu::init(cx);
 362
 363    workspace::register_project_item::<Editor>(cx);
 364    workspace::register_followable_item::<Editor>(cx);
 365}
 366
 367trait InvalidationRegion {
 368    fn ranges(&self) -> &[Range<Anchor>];
 369}
 370
 371#[derive(Clone, Debug, PartialEq)]
 372pub enum SelectPhase {
 373    Begin {
 374        position: DisplayPoint,
 375        add: bool,
 376        click_count: usize,
 377    },
 378    BeginColumnar {
 379        position: DisplayPoint,
 380        goal_column: u32,
 381    },
 382    Extend {
 383        position: DisplayPoint,
 384        click_count: usize,
 385    },
 386    Update {
 387        position: DisplayPoint,
 388        goal_column: u32,
 389        scroll_position: Vector2F,
 390    },
 391    End,
 392}
 393
 394#[derive(Clone, Debug)]
 395pub enum SelectMode {
 396    Character,
 397    Word(Range<Anchor>),
 398    Line(Range<Anchor>),
 399    All,
 400}
 401
 402#[derive(PartialEq, Eq)]
 403pub enum Autoscroll {
 404    Fit,
 405    Center,
 406    Newest,
 407}
 408
 409#[derive(Copy, Clone, PartialEq, Eq)]
 410pub enum EditorMode {
 411    SingleLine,
 412    AutoHeight { max_lines: usize },
 413    Full,
 414}
 415
 416#[derive(Clone)]
 417pub enum SoftWrap {
 418    None,
 419    EditorWidth,
 420    Column(u32),
 421}
 422
 423#[derive(Clone)]
 424pub struct EditorStyle {
 425    pub text: TextStyle,
 426    pub placeholder_text: Option<TextStyle>,
 427    pub theme: theme::Editor,
 428}
 429
 430type CompletionId = usize;
 431
 432pub type GetFieldEditorTheme = fn(&theme::Theme) -> theme::FieldEditor;
 433
 434type OverrideTextStyle = dyn Fn(&EditorStyle) -> Option<HighlightStyle>;
 435
 436#[derive(Clone, Copy)]
 437pub struct OngoingScroll {
 438    last_timestamp: Instant,
 439    axis: Option<Axis>,
 440}
 441
 442impl OngoingScroll {
 443    fn initial() -> OngoingScroll {
 444        OngoingScroll {
 445            last_timestamp: Instant::now() - SCROLL_EVENT_SEPARATION,
 446            axis: None,
 447        }
 448    }
 449
 450    fn update(&mut self, axis: Option<Axis>) {
 451        self.last_timestamp = Instant::now();
 452        self.axis = axis;
 453    }
 454
 455    pub fn filter(&self, delta: &mut Vector2F) -> Option<Axis> {
 456        const UNLOCK_PERCENT: f32 = 1.9;
 457        const UNLOCK_LOWER_BOUND: f32 = 6.;
 458        let mut axis = self.axis;
 459
 460        let x = delta.x().abs();
 461        let y = delta.y().abs();
 462        let duration = Instant::now().duration_since(self.last_timestamp);
 463        if duration > SCROLL_EVENT_SEPARATION {
 464            //New ongoing scroll will start, determine axis
 465            axis = if x <= y {
 466                Some(Axis::Vertical)
 467            } else {
 468                Some(Axis::Horizontal)
 469            };
 470        } else if x.max(y) >= UNLOCK_LOWER_BOUND {
 471            //Check if the current ongoing will need to unlock
 472            match axis {
 473                Some(Axis::Vertical) => {
 474                    if x > y && x >= y * UNLOCK_PERCENT {
 475                        axis = None;
 476                    }
 477                }
 478
 479                Some(Axis::Horizontal) => {
 480                    if y > x && y >= x * UNLOCK_PERCENT {
 481                        axis = None;
 482                    }
 483                }
 484
 485                None => {}
 486            }
 487        }
 488
 489        match axis {
 490            Some(Axis::Vertical) => *delta = vec2f(0., delta.y()),
 491            Some(Axis::Horizontal) => *delta = vec2f(delta.x(), 0.),
 492            None => {}
 493        }
 494
 495        axis
 496    }
 497}
 498
 499pub struct Editor {
 500    handle: WeakViewHandle<Self>,
 501    buffer: ModelHandle<MultiBuffer>,
 502    display_map: ModelHandle<DisplayMap>,
 503    pub selections: SelectionsCollection,
 504    columnar_selection_tail: Option<Anchor>,
 505    add_selections_state: Option<AddSelectionsState>,
 506    select_next_state: Option<SelectNextState>,
 507    selection_history: SelectionHistory,
 508    autoclose_regions: Vec<AutocloseRegion>,
 509    snippet_stack: InvalidationStack<SnippetState>,
 510    select_larger_syntax_node_stack: Vec<Box<[Selection<usize>]>>,
 511    ime_transaction: Option<TransactionId>,
 512    active_diagnostics: Option<ActiveDiagnosticGroup>,
 513    ongoing_scroll: OngoingScroll,
 514    scroll_position: Vector2F,
 515    scroll_top_anchor: Anchor,
 516    autoscroll_request: Option<(Autoscroll, bool)>,
 517    soft_wrap_mode_override: Option<settings::SoftWrap>,
 518    get_field_editor_theme: Option<GetFieldEditorTheme>,
 519    override_text_style: Option<Box<OverrideTextStyle>>,
 520    project: Option<ModelHandle<Project>>,
 521    focused: bool,
 522    blink_manager: ModelHandle<BlinkManager>,
 523    show_local_selections: bool,
 524    show_scrollbars: bool,
 525    hide_scrollbar_task: Option<Task<()>>,
 526    mode: EditorMode,
 527    vertical_scroll_margin: f32,
 528    placeholder_text: Option<Arc<str>>,
 529    highlighted_rows: Option<Range<u32>>,
 530    #[allow(clippy::type_complexity)]
 531    background_highlights: BTreeMap<TypeId, (fn(&Theme) -> Color, Vec<Range<Anchor>>)>,
 532    nav_history: Option<ItemNavHistory>,
 533    context_menu: Option<ContextMenu>,
 534    mouse_context_menu: ViewHandle<context_menu::ContextMenu>,
 535    completion_tasks: Vec<(CompletionId, Task<Option<()>>)>,
 536    next_completion_id: CompletionId,
 537    available_code_actions: Option<(ModelHandle<Buffer>, Arc<[CodeAction]>)>,
 538    code_actions_task: Option<Task<()>>,
 539    document_highlights_task: Option<Task<()>>,
 540    pending_rename: Option<RenameState>,
 541    searchable: bool,
 542    cursor_shape: CursorShape,
 543    keymap_context_layers: BTreeMap<TypeId, gpui::keymap::Context>,
 544    input_enabled: bool,
 545    leader_replica_id: Option<u16>,
 546    hover_state: HoverState,
 547    link_go_to_definition_state: LinkGoToDefinitionState,
 548    visible_line_count: Option<f32>,
 549    _subscriptions: Vec<Subscription>,
 550}
 551
 552pub struct EditorSnapshot {
 553    pub mode: EditorMode,
 554    pub display_snapshot: DisplaySnapshot,
 555    pub placeholder_text: Option<Arc<str>>,
 556    is_focused: bool,
 557    ongoing_scroll: OngoingScroll,
 558    scroll_position: Vector2F,
 559    scroll_top_anchor: Anchor,
 560}
 561
 562#[derive(Clone, Debug)]
 563struct SelectionHistoryEntry {
 564    selections: Arc<[Selection<Anchor>]>,
 565    select_next_state: Option<SelectNextState>,
 566    add_selections_state: Option<AddSelectionsState>,
 567}
 568
 569enum SelectionHistoryMode {
 570    Normal,
 571    Undoing,
 572    Redoing,
 573}
 574
 575impl Default for SelectionHistoryMode {
 576    fn default() -> Self {
 577        Self::Normal
 578    }
 579}
 580
 581#[derive(Default)]
 582struct SelectionHistory {
 583    #[allow(clippy::type_complexity)]
 584    selections_by_transaction:
 585        HashMap<TransactionId, (Arc<[Selection<Anchor>]>, Option<Arc<[Selection<Anchor>]>>)>,
 586    mode: SelectionHistoryMode,
 587    undo_stack: VecDeque<SelectionHistoryEntry>,
 588    redo_stack: VecDeque<SelectionHistoryEntry>,
 589}
 590
 591impl SelectionHistory {
 592    fn insert_transaction(
 593        &mut self,
 594        transaction_id: TransactionId,
 595        selections: Arc<[Selection<Anchor>]>,
 596    ) {
 597        self.selections_by_transaction
 598            .insert(transaction_id, (selections, None));
 599    }
 600
 601    #[allow(clippy::type_complexity)]
 602    fn transaction(
 603        &self,
 604        transaction_id: TransactionId,
 605    ) -> Option<&(Arc<[Selection<Anchor>]>, Option<Arc<[Selection<Anchor>]>>)> {
 606        self.selections_by_transaction.get(&transaction_id)
 607    }
 608
 609    #[allow(clippy::type_complexity)]
 610    fn transaction_mut(
 611        &mut self,
 612        transaction_id: TransactionId,
 613    ) -> Option<&mut (Arc<[Selection<Anchor>]>, Option<Arc<[Selection<Anchor>]>>)> {
 614        self.selections_by_transaction.get_mut(&transaction_id)
 615    }
 616
 617    fn push(&mut self, entry: SelectionHistoryEntry) {
 618        if !entry.selections.is_empty() {
 619            match self.mode {
 620                SelectionHistoryMode::Normal => {
 621                    self.push_undo(entry);
 622                    self.redo_stack.clear();
 623                }
 624                SelectionHistoryMode::Undoing => self.push_redo(entry),
 625                SelectionHistoryMode::Redoing => self.push_undo(entry),
 626            }
 627        }
 628    }
 629
 630    fn push_undo(&mut self, entry: SelectionHistoryEntry) {
 631        if self
 632            .undo_stack
 633            .back()
 634            .map_or(true, |e| e.selections != entry.selections)
 635        {
 636            self.undo_stack.push_back(entry);
 637            if self.undo_stack.len() > MAX_SELECTION_HISTORY_LEN {
 638                self.undo_stack.pop_front();
 639            }
 640        }
 641    }
 642
 643    fn push_redo(&mut self, entry: SelectionHistoryEntry) {
 644        if self
 645            .redo_stack
 646            .back()
 647            .map_or(true, |e| e.selections != entry.selections)
 648        {
 649            self.redo_stack.push_back(entry);
 650            if self.redo_stack.len() > MAX_SELECTION_HISTORY_LEN {
 651                self.redo_stack.pop_front();
 652            }
 653        }
 654    }
 655}
 656
 657#[derive(Clone, Debug)]
 658struct AddSelectionsState {
 659    above: bool,
 660    stack: Vec<usize>,
 661}
 662
 663#[derive(Clone, Debug)]
 664struct SelectNextState {
 665    query: AhoCorasick,
 666    wordwise: bool,
 667    done: bool,
 668}
 669
 670#[derive(Debug)]
 671struct AutocloseRegion {
 672    selection_id: usize,
 673    range: Range<Anchor>,
 674    pair: BracketPair,
 675}
 676
 677#[derive(Debug)]
 678struct SnippetState {
 679    ranges: Vec<Vec<Range<Anchor>>>,
 680    active_index: usize,
 681}
 682
 683pub struct RenameState {
 684    pub range: Range<Anchor>,
 685    pub old_name: Arc<str>,
 686    pub editor: ViewHandle<Editor>,
 687    block_id: BlockId,
 688}
 689
 690struct InvalidationStack<T>(Vec<T>);
 691
 692enum ContextMenu {
 693    Completions(CompletionsMenu),
 694    CodeActions(CodeActionsMenu),
 695}
 696
 697impl ContextMenu {
 698    fn select_first(&mut self, cx: &mut ViewContext<Editor>) -> bool {
 699        if self.visible() {
 700            match self {
 701                ContextMenu::Completions(menu) => menu.select_first(cx),
 702                ContextMenu::CodeActions(menu) => menu.select_first(cx),
 703            }
 704            true
 705        } else {
 706            false
 707        }
 708    }
 709
 710    fn select_prev(&mut self, cx: &mut ViewContext<Editor>) -> bool {
 711        if self.visible() {
 712            match self {
 713                ContextMenu::Completions(menu) => menu.select_prev(cx),
 714                ContextMenu::CodeActions(menu) => menu.select_prev(cx),
 715            }
 716            true
 717        } else {
 718            false
 719        }
 720    }
 721
 722    fn select_next(&mut self, cx: &mut ViewContext<Editor>) -> bool {
 723        if self.visible() {
 724            match self {
 725                ContextMenu::Completions(menu) => menu.select_next(cx),
 726                ContextMenu::CodeActions(menu) => menu.select_next(cx),
 727            }
 728            true
 729        } else {
 730            false
 731        }
 732    }
 733
 734    fn select_last(&mut self, cx: &mut ViewContext<Editor>) -> bool {
 735        if self.visible() {
 736            match self {
 737                ContextMenu::Completions(menu) => menu.select_last(cx),
 738                ContextMenu::CodeActions(menu) => menu.select_last(cx),
 739            }
 740            true
 741        } else {
 742            false
 743        }
 744    }
 745
 746    fn visible(&self) -> bool {
 747        match self {
 748            ContextMenu::Completions(menu) => menu.visible(),
 749            ContextMenu::CodeActions(menu) => menu.visible(),
 750        }
 751    }
 752
 753    fn render(
 754        &self,
 755        cursor_position: DisplayPoint,
 756        style: EditorStyle,
 757        cx: &mut RenderContext<Editor>,
 758    ) -> (DisplayPoint, ElementBox) {
 759        match self {
 760            ContextMenu::Completions(menu) => (cursor_position, menu.render(style, cx)),
 761            ContextMenu::CodeActions(menu) => menu.render(cursor_position, style, cx),
 762        }
 763    }
 764}
 765
 766struct CompletionsMenu {
 767    id: CompletionId,
 768    initial_position: Anchor,
 769    buffer: ModelHandle<Buffer>,
 770    completions: Arc<[Completion]>,
 771    match_candidates: Vec<StringMatchCandidate>,
 772    matches: Arc<[StringMatch]>,
 773    selected_item: usize,
 774    list: UniformListState,
 775}
 776
 777impl CompletionsMenu {
 778    fn select_first(&mut self, cx: &mut ViewContext<Editor>) {
 779        self.selected_item = 0;
 780        self.list.scroll_to(ScrollTarget::Show(self.selected_item));
 781        cx.notify();
 782    }
 783
 784    fn select_prev(&mut self, cx: &mut ViewContext<Editor>) {
 785        if self.selected_item > 0 {
 786            self.selected_item -= 1;
 787            self.list.scroll_to(ScrollTarget::Show(self.selected_item));
 788        }
 789        cx.notify();
 790    }
 791
 792    fn select_next(&mut self, cx: &mut ViewContext<Editor>) {
 793        if self.selected_item + 1 < self.matches.len() {
 794            self.selected_item += 1;
 795            self.list.scroll_to(ScrollTarget::Show(self.selected_item));
 796        }
 797        cx.notify();
 798    }
 799
 800    fn select_last(&mut self, cx: &mut ViewContext<Editor>) {
 801        self.selected_item = self.matches.len() - 1;
 802        self.list.scroll_to(ScrollTarget::Show(self.selected_item));
 803        cx.notify();
 804    }
 805
 806    fn visible(&self) -> bool {
 807        !self.matches.is_empty()
 808    }
 809
 810    fn render(&self, style: EditorStyle, cx: &mut RenderContext<Editor>) -> ElementBox {
 811        enum CompletionTag {}
 812
 813        let completions = self.completions.clone();
 814        let matches = self.matches.clone();
 815        let selected_item = self.selected_item;
 816        let container_style = style.autocomplete.container;
 817        UniformList::new(
 818            self.list.clone(),
 819            matches.len(),
 820            cx,
 821            move |_, range, items, cx| {
 822                let start_ix = range.start;
 823                for (ix, mat) in matches[range].iter().enumerate() {
 824                    let completion = &completions[mat.candidate_id];
 825                    let item_ix = start_ix + ix;
 826                    items.push(
 827                        MouseEventHandler::<CompletionTag>::new(
 828                            mat.candidate_id,
 829                            cx,
 830                            |state, _| {
 831                                let item_style = if item_ix == selected_item {
 832                                    style.autocomplete.selected_item
 833                                } else if state.hovered() {
 834                                    style.autocomplete.hovered_item
 835                                } else {
 836                                    style.autocomplete.item
 837                                };
 838
 839                                Text::new(completion.label.text.clone(), style.text.clone())
 840                                    .with_soft_wrap(false)
 841                                    .with_highlights(combine_syntax_and_fuzzy_match_highlights(
 842                                        &completion.label.text,
 843                                        style.text.color.into(),
 844                                        styled_runs_for_code_label(
 845                                            &completion.label,
 846                                            &style.syntax,
 847                                        ),
 848                                        &mat.positions,
 849                                    ))
 850                                    .contained()
 851                                    .with_style(item_style)
 852                                    .boxed()
 853                            },
 854                        )
 855                        .with_cursor_style(CursorStyle::PointingHand)
 856                        .on_down(MouseButton::Left, move |_, cx| {
 857                            cx.dispatch_action(ConfirmCompletion {
 858                                item_ix: Some(item_ix),
 859                            });
 860                        })
 861                        .boxed(),
 862                    );
 863                }
 864            },
 865        )
 866        .with_width_from_item(
 867            self.matches
 868                .iter()
 869                .enumerate()
 870                .max_by_key(|(_, mat)| {
 871                    self.completions[mat.candidate_id]
 872                        .label
 873                        .text
 874                        .chars()
 875                        .count()
 876                })
 877                .map(|(ix, _)| ix),
 878        )
 879        .contained()
 880        .with_style(container_style)
 881        .boxed()
 882    }
 883
 884    pub async fn filter(&mut self, query: Option<&str>, executor: Arc<executor::Background>) {
 885        let mut matches = if let Some(query) = query {
 886            fuzzy::match_strings(
 887                &self.match_candidates,
 888                query,
 889                false,
 890                100,
 891                &Default::default(),
 892                executor,
 893            )
 894            .await
 895        } else {
 896            self.match_candidates
 897                .iter()
 898                .enumerate()
 899                .map(|(candidate_id, candidate)| StringMatch {
 900                    candidate_id,
 901                    score: Default::default(),
 902                    positions: Default::default(),
 903                    string: candidate.string.clone(),
 904                })
 905                .collect()
 906        };
 907        matches.sort_unstable_by_key(|mat| {
 908            let completion = &self.completions[mat.candidate_id];
 909            (
 910                completion.lsp_completion.sort_text.as_ref(),
 911                Reverse(OrderedFloat(mat.score)),
 912                completion.sort_key(),
 913            )
 914        });
 915
 916        for mat in &mut matches {
 917            let filter_start = self.completions[mat.candidate_id].label.filter_range.start;
 918            for position in &mut mat.positions {
 919                *position += filter_start;
 920            }
 921        }
 922
 923        self.matches = matches.into();
 924    }
 925}
 926
 927#[derive(Clone)]
 928struct CodeActionsMenu {
 929    actions: Arc<[CodeAction]>,
 930    buffer: ModelHandle<Buffer>,
 931    selected_item: usize,
 932    list: UniformListState,
 933    deployed_from_indicator: bool,
 934}
 935
 936impl CodeActionsMenu {
 937    fn select_first(&mut self, cx: &mut ViewContext<Editor>) {
 938        self.selected_item = 0;
 939        cx.notify()
 940    }
 941
 942    fn select_prev(&mut self, cx: &mut ViewContext<Editor>) {
 943        if self.selected_item > 0 {
 944            self.selected_item -= 1;
 945            cx.notify()
 946        }
 947    }
 948
 949    fn select_next(&mut self, cx: &mut ViewContext<Editor>) {
 950        if self.selected_item + 1 < self.actions.len() {
 951            self.selected_item += 1;
 952            cx.notify()
 953        }
 954    }
 955
 956    fn select_last(&mut self, cx: &mut ViewContext<Editor>) {
 957        self.selected_item = self.actions.len() - 1;
 958        cx.notify()
 959    }
 960
 961    fn visible(&self) -> bool {
 962        !self.actions.is_empty()
 963    }
 964
 965    fn render(
 966        &self,
 967        mut cursor_position: DisplayPoint,
 968        style: EditorStyle,
 969        cx: &mut RenderContext<Editor>,
 970    ) -> (DisplayPoint, ElementBox) {
 971        enum ActionTag {}
 972
 973        let container_style = style.autocomplete.container;
 974        let actions = self.actions.clone();
 975        let selected_item = self.selected_item;
 976        let element = UniformList::new(
 977            self.list.clone(),
 978            actions.len(),
 979            cx,
 980            move |_, range, items, cx| {
 981                let start_ix = range.start;
 982                for (ix, action) in actions[range].iter().enumerate() {
 983                    let item_ix = start_ix + ix;
 984                    items.push(
 985                        MouseEventHandler::<ActionTag>::new(item_ix, cx, |state, _| {
 986                            let item_style = if item_ix == selected_item {
 987                                style.autocomplete.selected_item
 988                            } else if state.hovered() {
 989                                style.autocomplete.hovered_item
 990                            } else {
 991                                style.autocomplete.item
 992                            };
 993
 994                            Text::new(action.lsp_action.title.clone(), style.text.clone())
 995                                .with_soft_wrap(false)
 996                                .contained()
 997                                .with_style(item_style)
 998                                .boxed()
 999                        })
1000                        .with_cursor_style(CursorStyle::PointingHand)
1001                        .on_down(MouseButton::Left, move |_, cx| {
1002                            cx.dispatch_action(ConfirmCodeAction {
1003                                item_ix: Some(item_ix),
1004                            });
1005                        })
1006                        .boxed(),
1007                    );
1008                }
1009            },
1010        )
1011        .with_width_from_item(
1012            self.actions
1013                .iter()
1014                .enumerate()
1015                .max_by_key(|(_, action)| action.lsp_action.title.chars().count())
1016                .map(|(ix, _)| ix),
1017        )
1018        .contained()
1019        .with_style(container_style)
1020        .boxed();
1021
1022        if self.deployed_from_indicator {
1023            *cursor_position.column_mut() = 0;
1024        }
1025
1026        (cursor_position, element)
1027    }
1028}
1029
1030#[derive(Debug)]
1031struct ActiveDiagnosticGroup {
1032    primary_range: Range<Anchor>,
1033    primary_message: String,
1034    blocks: HashMap<BlockId, Diagnostic>,
1035    is_valid: bool,
1036}
1037
1038#[derive(Serialize, Deserialize)]
1039pub struct ClipboardSelection {
1040    pub len: usize,
1041    pub is_entire_line: bool,
1042    pub first_line_indent: u32,
1043}
1044
1045#[derive(Debug)]
1046pub struct NavigationData {
1047    // Matching offsets for anchor and scroll_top_anchor allows us to recreate the anchor if the buffer
1048    // has since been closed
1049    cursor_anchor: Anchor,
1050    cursor_position: Point,
1051    scroll_position: Vector2F,
1052    scroll_top_anchor: Anchor,
1053    scroll_top_row: u32,
1054}
1055
1056pub struct EditorCreated(pub ViewHandle<Editor>);
1057
1058enum GotoDefinitionKind {
1059    Symbol,
1060    Type,
1061}
1062
1063impl Editor {
1064    pub fn single_line(
1065        field_editor_style: Option<GetFieldEditorTheme>,
1066        cx: &mut ViewContext<Self>,
1067    ) -> Self {
1068        let buffer = cx.add_model(|cx| Buffer::new(0, String::new(), cx));
1069        let buffer = cx.add_model(|cx| MultiBuffer::singleton(buffer, cx));
1070        Self::new(EditorMode::SingleLine, buffer, None, field_editor_style, cx)
1071    }
1072
1073    pub fn auto_height(
1074        max_lines: usize,
1075        field_editor_style: Option<GetFieldEditorTheme>,
1076        cx: &mut ViewContext<Self>,
1077    ) -> Self {
1078        let buffer = cx.add_model(|cx| Buffer::new(0, String::new(), cx));
1079        let buffer = cx.add_model(|cx| MultiBuffer::singleton(buffer, cx));
1080        Self::new(
1081            EditorMode::AutoHeight { max_lines },
1082            buffer,
1083            None,
1084            field_editor_style,
1085            cx,
1086        )
1087    }
1088
1089    pub fn for_buffer(
1090        buffer: ModelHandle<Buffer>,
1091        project: Option<ModelHandle<Project>>,
1092        cx: &mut ViewContext<Self>,
1093    ) -> Self {
1094        let buffer = cx.add_model(|cx| MultiBuffer::singleton(buffer, cx));
1095        Self::new(EditorMode::Full, buffer, project, None, cx)
1096    }
1097
1098    pub fn for_multibuffer(
1099        buffer: ModelHandle<MultiBuffer>,
1100        project: Option<ModelHandle<Project>>,
1101        cx: &mut ViewContext<Self>,
1102    ) -> Self {
1103        Self::new(EditorMode::Full, buffer, project, None, cx)
1104    }
1105
1106    pub fn clone(&self, cx: &mut ViewContext<Self>) -> Self {
1107        let mut clone = Self::new(
1108            self.mode,
1109            self.buffer.clone(),
1110            self.project.clone(),
1111            self.get_field_editor_theme,
1112            cx,
1113        );
1114        self.display_map.update(cx, |display_map, cx| {
1115            let snapshot = display_map.snapshot(cx);
1116            clone.display_map.update(cx, |display_map, cx| {
1117                display_map.set_state(&snapshot, cx);
1118            });
1119        });
1120        clone.selections.set_state(&self.selections);
1121        clone.scroll_position = self.scroll_position;
1122        clone.scroll_top_anchor = self.scroll_top_anchor.clone();
1123        clone.searchable = self.searchable;
1124        clone
1125    }
1126
1127    fn new(
1128        mode: EditorMode,
1129        buffer: ModelHandle<MultiBuffer>,
1130        project: Option<ModelHandle<Project>>,
1131        get_field_editor_theme: Option<GetFieldEditorTheme>,
1132        cx: &mut ViewContext<Self>,
1133    ) -> Self {
1134        let display_map = cx.add_model(|cx| {
1135            let settings = cx.global::<Settings>();
1136            let style = build_style(&*settings, get_field_editor_theme, None, cx);
1137            DisplayMap::new(
1138                buffer.clone(),
1139                style.text.font_id,
1140                style.text.font_size,
1141                None,
1142                2,
1143                1,
1144                cx,
1145            )
1146        });
1147
1148        let selections = SelectionsCollection::new(display_map.clone(), buffer.clone());
1149
1150        let blink_manager = cx.add_model(|cx| BlinkManager::new(CURSOR_BLINK_INTERVAL, cx));
1151
1152        let mut this = Self {
1153            handle: cx.weak_handle(),
1154            buffer: buffer.clone(),
1155            display_map: display_map.clone(),
1156            selections,
1157            columnar_selection_tail: None,
1158            add_selections_state: None,
1159            select_next_state: None,
1160            selection_history: Default::default(),
1161            autoclose_regions: Default::default(),
1162            snippet_stack: Default::default(),
1163            select_larger_syntax_node_stack: Vec::new(),
1164            ime_transaction: Default::default(),
1165            active_diagnostics: None,
1166            soft_wrap_mode_override: None,
1167            get_field_editor_theme,
1168            project,
1169            ongoing_scroll: OngoingScroll::initial(),
1170            scroll_position: Vector2F::zero(),
1171            scroll_top_anchor: Anchor::min(),
1172            autoscroll_request: None,
1173            focused: false,
1174            blink_manager: blink_manager.clone(),
1175            show_local_selections: true,
1176            show_scrollbars: true,
1177            hide_scrollbar_task: None,
1178            mode,
1179            vertical_scroll_margin: 3.0,
1180            placeholder_text: None,
1181            highlighted_rows: None,
1182            background_highlights: Default::default(),
1183            nav_history: None,
1184            context_menu: None,
1185            mouse_context_menu: cx.add_view(context_menu::ContextMenu::new),
1186            completion_tasks: Default::default(),
1187            next_completion_id: 0,
1188            available_code_actions: Default::default(),
1189            code_actions_task: Default::default(),
1190            document_highlights_task: Default::default(),
1191            pending_rename: Default::default(),
1192            searchable: true,
1193            override_text_style: None,
1194            cursor_shape: Default::default(),
1195            keymap_context_layers: Default::default(),
1196            input_enabled: true,
1197            leader_replica_id: None,
1198            hover_state: Default::default(),
1199            link_go_to_definition_state: Default::default(),
1200            visible_line_count: None,
1201            _subscriptions: vec![
1202                cx.observe(&buffer, Self::on_buffer_changed),
1203                cx.subscribe(&buffer, Self::on_buffer_event),
1204                cx.observe(&display_map, Self::on_display_map_changed),
1205                cx.observe(&blink_manager, |_, _, cx| cx.notify()),
1206            ],
1207        };
1208        this.end_selection(cx);
1209        this.make_scrollbar_visible(cx);
1210
1211        let editor_created_event = EditorCreated(cx.handle());
1212        cx.emit_global(editor_created_event);
1213
1214        if mode == EditorMode::Full {
1215            let should_auto_hide_scrollbars = cx.platform().should_auto_hide_scrollbars();
1216            cx.set_global(ScrollbarAutoHide(should_auto_hide_scrollbars));
1217        }
1218
1219        this.report_event("open editor", cx);
1220        this
1221    }
1222
1223    pub fn new_file(
1224        workspace: &mut Workspace,
1225        _: &workspace::NewFile,
1226        cx: &mut ViewContext<Workspace>,
1227    ) {
1228        let project = workspace.project().clone();
1229        if project.read(cx).is_remote() {
1230            cx.propagate_action();
1231        } else if let Some(buffer) = project
1232            .update(cx, |project, cx| project.create_buffer("", None, cx))
1233            .log_err()
1234        {
1235            workspace.add_item(
1236                Box::new(cx.add_view(|cx| Editor::for_buffer(buffer, Some(project.clone()), cx))),
1237                cx,
1238            );
1239        }
1240    }
1241
1242    pub fn replica_id(&self, cx: &AppContext) -> ReplicaId {
1243        self.buffer.read(cx).replica_id()
1244    }
1245
1246    pub fn leader_replica_id(&self) -> Option<ReplicaId> {
1247        self.leader_replica_id
1248    }
1249
1250    pub fn buffer(&self) -> &ModelHandle<MultiBuffer> {
1251        &self.buffer
1252    }
1253
1254    pub fn title<'a>(&self, cx: &'a AppContext) -> Cow<'a, str> {
1255        self.buffer().read(cx).title(cx)
1256    }
1257
1258    pub fn snapshot(&mut self, cx: &mut MutableAppContext) -> EditorSnapshot {
1259        EditorSnapshot {
1260            mode: self.mode,
1261            display_snapshot: self.display_map.update(cx, |map, cx| map.snapshot(cx)),
1262            ongoing_scroll: self.ongoing_scroll,
1263            scroll_position: self.scroll_position,
1264            scroll_top_anchor: self.scroll_top_anchor.clone(),
1265            placeholder_text: self.placeholder_text.clone(),
1266            is_focused: self
1267                .handle
1268                .upgrade(cx)
1269                .map_or(false, |handle| handle.is_focused(cx)),
1270        }
1271    }
1272
1273    pub fn language_at<'a, T: ToOffset>(
1274        &self,
1275        point: T,
1276        cx: &'a AppContext,
1277    ) -> Option<Arc<Language>> {
1278        self.buffer.read(cx).language_at(point, cx)
1279    }
1280
1281    fn style(&self, cx: &AppContext) -> EditorStyle {
1282        build_style(
1283            cx.global::<Settings>(),
1284            self.get_field_editor_theme,
1285            self.override_text_style.as_deref(),
1286            cx,
1287        )
1288    }
1289
1290    pub fn mode(&self) -> EditorMode {
1291        self.mode
1292    }
1293
1294    pub fn set_placeholder_text(
1295        &mut self,
1296        placeholder_text: impl Into<Arc<str>>,
1297        cx: &mut ViewContext<Self>,
1298    ) {
1299        self.placeholder_text = Some(placeholder_text.into());
1300        cx.notify();
1301    }
1302
1303    pub fn set_vertical_scroll_margin(&mut self, margin_rows: usize, cx: &mut ViewContext<Self>) {
1304        self.vertical_scroll_margin = margin_rows as f32;
1305        cx.notify();
1306    }
1307
1308    pub fn set_scroll_position(&mut self, scroll_position: Vector2F, cx: &mut ViewContext<Self>) {
1309        self.set_scroll_position_internal(scroll_position, true, cx);
1310    }
1311
1312    fn set_scroll_position_internal(
1313        &mut self,
1314        scroll_position: Vector2F,
1315        local: bool,
1316        cx: &mut ViewContext<Self>,
1317    ) {
1318        let map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
1319
1320        if scroll_position.y() <= 0. {
1321            self.scroll_top_anchor = Anchor::min();
1322            self.scroll_position = scroll_position.max(vec2f(0., 0.));
1323        } else {
1324            let scroll_top_buffer_offset =
1325                DisplayPoint::new(scroll_position.y() as u32, 0).to_offset(&map, Bias::Right);
1326            let anchor = map
1327                .buffer_snapshot
1328                .anchor_at(scroll_top_buffer_offset, Bias::Right);
1329            self.scroll_position = vec2f(
1330                scroll_position.x(),
1331                scroll_position.y() - anchor.to_display_point(&map).row() as f32,
1332            );
1333            self.scroll_top_anchor = anchor;
1334        }
1335
1336        self.make_scrollbar_visible(cx);
1337        self.autoscroll_request.take();
1338        hide_hover(self, cx);
1339
1340        cx.emit(Event::ScrollPositionChanged { local });
1341        cx.notify();
1342    }
1343
1344    fn set_visible_line_count(&mut self, lines: f32) {
1345        self.visible_line_count = Some(lines)
1346    }
1347
1348    fn set_scroll_top_anchor(
1349        &mut self,
1350        anchor: Anchor,
1351        position: Vector2F,
1352        cx: &mut ViewContext<Self>,
1353    ) {
1354        self.scroll_top_anchor = anchor;
1355        self.scroll_position = position;
1356        self.make_scrollbar_visible(cx);
1357        cx.emit(Event::ScrollPositionChanged { local: false });
1358        cx.notify();
1359    }
1360
1361    pub fn set_cursor_shape(&mut self, cursor_shape: CursorShape, cx: &mut ViewContext<Self>) {
1362        self.cursor_shape = cursor_shape;
1363        cx.notify();
1364    }
1365
1366    pub fn set_clip_at_line_ends(&mut self, clip: bool, cx: &mut ViewContext<Self>) {
1367        if self.display_map.read(cx).clip_at_line_ends != clip {
1368            self.display_map
1369                .update(cx, |map, _| map.clip_at_line_ends = clip);
1370        }
1371    }
1372
1373    pub fn set_keymap_context_layer<Tag: 'static>(&mut self, context: gpui::keymap::Context) {
1374        self.keymap_context_layers
1375            .insert(TypeId::of::<Tag>(), context);
1376    }
1377
1378    pub fn remove_keymap_context_layer<Tag: 'static>(&mut self) {
1379        self.keymap_context_layers.remove(&TypeId::of::<Tag>());
1380    }
1381
1382    pub fn set_input_enabled(&mut self, input_enabled: bool) {
1383        self.input_enabled = input_enabled;
1384    }
1385
1386    pub fn scroll_position(&self, cx: &mut ViewContext<Self>) -> Vector2F {
1387        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
1388        compute_scroll_position(&display_map, self.scroll_position, &self.scroll_top_anchor)
1389    }
1390
1391    pub fn clamp_scroll_left(&mut self, max: f32) -> bool {
1392        if max < self.scroll_position.x() {
1393            self.scroll_position.set_x(max);
1394            true
1395        } else {
1396            false
1397        }
1398    }
1399
1400    pub fn autoscroll_vertically(
1401        &mut self,
1402        viewport_height: f32,
1403        line_height: f32,
1404        cx: &mut ViewContext<Self>,
1405    ) -> bool {
1406        let visible_lines = viewport_height / line_height;
1407        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
1408        let mut scroll_position =
1409            compute_scroll_position(&display_map, self.scroll_position, &self.scroll_top_anchor);
1410        let max_scroll_top = if matches!(self.mode, EditorMode::AutoHeight { .. }) {
1411            (display_map.max_point().row() as f32 - visible_lines + 1.).max(0.)
1412        } else {
1413            display_map.max_point().row() as f32
1414        };
1415        if scroll_position.y() > max_scroll_top {
1416            scroll_position.set_y(max_scroll_top);
1417            self.set_scroll_position(scroll_position, cx);
1418        }
1419
1420        let (autoscroll, local) = if let Some(autoscroll) = self.autoscroll_request.take() {
1421            autoscroll
1422        } else {
1423            return false;
1424        };
1425
1426        let first_cursor_top;
1427        let last_cursor_bottom;
1428        if let Some(highlighted_rows) = &self.highlighted_rows {
1429            first_cursor_top = highlighted_rows.start as f32;
1430            last_cursor_bottom = first_cursor_top + 1.;
1431        } else if autoscroll == Autoscroll::Newest {
1432            let newest_selection = self.selections.newest::<Point>(cx);
1433            first_cursor_top = newest_selection.head().to_display_point(&display_map).row() as f32;
1434            last_cursor_bottom = first_cursor_top + 1.;
1435        } else {
1436            let selections = self.selections.all::<Point>(cx);
1437            first_cursor_top = selections
1438                .first()
1439                .unwrap()
1440                .head()
1441                .to_display_point(&display_map)
1442                .row() as f32;
1443            last_cursor_bottom = selections
1444                .last()
1445                .unwrap()
1446                .head()
1447                .to_display_point(&display_map)
1448                .row() as f32
1449                + 1.0;
1450        }
1451
1452        let margin = if matches!(self.mode, EditorMode::AutoHeight { .. }) {
1453            0.
1454        } else {
1455            ((visible_lines - (last_cursor_bottom - first_cursor_top)) / 2.0).floor()
1456        };
1457        if margin < 0.0 {
1458            return false;
1459        }
1460
1461        match autoscroll {
1462            Autoscroll::Fit | Autoscroll::Newest => {
1463                let margin = margin.min(self.vertical_scroll_margin);
1464                let target_top = (first_cursor_top - margin).max(0.0);
1465                let target_bottom = last_cursor_bottom + margin;
1466                let start_row = scroll_position.y();
1467                let end_row = start_row + visible_lines;
1468
1469                if target_top < start_row {
1470                    scroll_position.set_y(target_top);
1471                    self.set_scroll_position_internal(scroll_position, local, cx);
1472                } else if target_bottom >= end_row {
1473                    scroll_position.set_y(target_bottom - visible_lines);
1474                    self.set_scroll_position_internal(scroll_position, local, cx);
1475                }
1476            }
1477            Autoscroll::Center => {
1478                scroll_position.set_y((first_cursor_top - margin).max(0.0));
1479                self.set_scroll_position_internal(scroll_position, local, cx);
1480            }
1481        }
1482
1483        true
1484    }
1485
1486    pub fn autoscroll_horizontally(
1487        &mut self,
1488        start_row: u32,
1489        viewport_width: f32,
1490        scroll_width: f32,
1491        max_glyph_width: f32,
1492        layouts: &[text_layout::Line],
1493        cx: &mut ViewContext<Self>,
1494    ) -> bool {
1495        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
1496        let selections = self.selections.all::<Point>(cx);
1497
1498        let mut target_left;
1499        let mut target_right;
1500
1501        if self.highlighted_rows.is_some() {
1502            target_left = 0.0_f32;
1503            target_right = 0.0_f32;
1504        } else {
1505            target_left = std::f32::INFINITY;
1506            target_right = 0.0_f32;
1507            for selection in selections {
1508                let head = selection.head().to_display_point(&display_map);
1509                if head.row() >= start_row && head.row() < start_row + layouts.len() as u32 {
1510                    let start_column = head.column().saturating_sub(3);
1511                    let end_column = cmp::min(display_map.line_len(head.row()), head.column() + 3);
1512                    target_left = target_left.min(
1513                        layouts[(head.row() - start_row) as usize]
1514                            .x_for_index(start_column as usize),
1515                    );
1516                    target_right = target_right.max(
1517                        layouts[(head.row() - start_row) as usize].x_for_index(end_column as usize)
1518                            + max_glyph_width,
1519                    );
1520                }
1521            }
1522        }
1523
1524        target_right = target_right.min(scroll_width);
1525
1526        if target_right - target_left > viewport_width {
1527            return false;
1528        }
1529
1530        let scroll_left = self.scroll_position.x() * max_glyph_width;
1531        let scroll_right = scroll_left + viewport_width;
1532
1533        if target_left < scroll_left {
1534            self.scroll_position.set_x(target_left / max_glyph_width);
1535            true
1536        } else if target_right > scroll_right {
1537            self.scroll_position
1538                .set_x((target_right - viewport_width) / max_glyph_width);
1539            true
1540        } else {
1541            false
1542        }
1543    }
1544
1545    fn selections_did_change(
1546        &mut self,
1547        local: bool,
1548        old_cursor_position: &Anchor,
1549        cx: &mut ViewContext<Self>,
1550    ) {
1551        if self.focused && self.leader_replica_id.is_none() {
1552            self.buffer.update(cx, |buffer, cx| {
1553                buffer.set_active_selections(
1554                    &self.selections.disjoint_anchors(),
1555                    self.selections.line_mode,
1556                    self.cursor_shape,
1557                    cx,
1558                )
1559            });
1560        }
1561
1562        let display_map = self
1563            .display_map
1564            .update(cx, |display_map, cx| display_map.snapshot(cx));
1565        let buffer = &display_map.buffer_snapshot;
1566        self.add_selections_state = None;
1567        self.select_next_state = None;
1568        self.select_larger_syntax_node_stack.clear();
1569        self.invalidate_autoclose_regions(&self.selections.disjoint_anchors(), buffer);
1570        self.snippet_stack
1571            .invalidate(&self.selections.disjoint_anchors(), buffer);
1572        self.take_rename(false, cx);
1573
1574        let new_cursor_position = self.selections.newest_anchor().head();
1575
1576        self.push_to_nav_history(
1577            old_cursor_position.clone(),
1578            Some(new_cursor_position.to_point(buffer)),
1579            cx,
1580        );
1581
1582        if local {
1583            let new_cursor_position = self.selections.newest_anchor().head();
1584            let completion_menu = match self.context_menu.as_mut() {
1585                Some(ContextMenu::Completions(menu)) => Some(menu),
1586                _ => {
1587                    self.context_menu.take();
1588                    None
1589                }
1590            };
1591
1592            if let Some(completion_menu) = completion_menu {
1593                let cursor_position = new_cursor_position.to_offset(buffer);
1594                let (word_range, kind) =
1595                    buffer.surrounding_word(completion_menu.initial_position.clone());
1596                if kind == Some(CharKind::Word)
1597                    && word_range.to_inclusive().contains(&cursor_position)
1598                {
1599                    let query = Self::completion_query(buffer, cursor_position);
1600                    cx.background()
1601                        .block(completion_menu.filter(query.as_deref(), cx.background().clone()));
1602                    self.show_completions(&ShowCompletions, cx);
1603                } else {
1604                    self.hide_context_menu(cx);
1605                }
1606            }
1607
1608            hide_hover(self, cx);
1609
1610            if old_cursor_position.to_display_point(&display_map).row()
1611                != new_cursor_position.to_display_point(&display_map).row()
1612            {
1613                self.available_code_actions.take();
1614            }
1615            self.refresh_code_actions(cx);
1616            self.refresh_document_highlights(cx);
1617            refresh_matching_bracket_highlights(self, cx);
1618        }
1619
1620        self.blink_manager.update(cx, BlinkManager::pause_blinking);
1621        cx.emit(Event::SelectionsChanged { local });
1622        cx.notify();
1623    }
1624
1625    pub fn change_selections<R>(
1626        &mut self,
1627        autoscroll: Option<Autoscroll>,
1628        cx: &mut ViewContext<Self>,
1629        change: impl FnOnce(&mut MutableSelectionsCollection<'_>) -> R,
1630    ) -> R {
1631        let old_cursor_position = self.selections.newest_anchor().head();
1632        self.push_to_selection_history();
1633
1634        let (changed, result) = self.selections.change_with(cx, change);
1635
1636        if changed {
1637            if let Some(autoscroll) = autoscroll {
1638                self.request_autoscroll(autoscroll, cx);
1639            }
1640            self.selections_did_change(true, &old_cursor_position, cx);
1641        }
1642
1643        result
1644    }
1645
1646    pub fn edit<I, S, T>(&mut self, edits: I, cx: &mut ViewContext<Self>)
1647    where
1648        I: IntoIterator<Item = (Range<S>, T)>,
1649        S: ToOffset,
1650        T: Into<Arc<str>>,
1651    {
1652        self.buffer
1653            .update(cx, |buffer, cx| buffer.edit(edits, None, cx));
1654    }
1655
1656    pub fn edit_with_autoindent<I, S, T>(&mut self, edits: I, cx: &mut ViewContext<Self>)
1657    where
1658        I: IntoIterator<Item = (Range<S>, T)>,
1659        S: ToOffset,
1660        T: Into<Arc<str>>,
1661    {
1662        self.buffer.update(cx, |buffer, cx| {
1663            buffer.edit(edits, Some(AutoindentMode::EachLine), cx)
1664        });
1665    }
1666
1667    fn scroll(&mut self, action: &Scroll, cx: &mut ViewContext<Self>) {
1668        self.ongoing_scroll.update(action.axis);
1669        self.set_scroll_position(action.scroll_position, cx);
1670    }
1671
1672    fn select(&mut self, Select(phase): &Select, cx: &mut ViewContext<Self>) {
1673        self.hide_context_menu(cx);
1674
1675        match phase {
1676            SelectPhase::Begin {
1677                position,
1678                add,
1679                click_count,
1680            } => self.begin_selection(*position, *add, *click_count, cx),
1681            SelectPhase::BeginColumnar {
1682                position,
1683                goal_column,
1684            } => self.begin_columnar_selection(*position, *goal_column, cx),
1685            SelectPhase::Extend {
1686                position,
1687                click_count,
1688            } => self.extend_selection(*position, *click_count, cx),
1689            SelectPhase::Update {
1690                position,
1691                goal_column,
1692                scroll_position,
1693            } => self.update_selection(*position, *goal_column, *scroll_position, cx),
1694            SelectPhase::End => self.end_selection(cx),
1695        }
1696    }
1697
1698    fn extend_selection(
1699        &mut self,
1700        position: DisplayPoint,
1701        click_count: usize,
1702        cx: &mut ViewContext<Self>,
1703    ) {
1704        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
1705        let tail = self.selections.newest::<usize>(cx).tail();
1706        self.begin_selection(position, false, click_count, cx);
1707
1708        let position = position.to_offset(&display_map, Bias::Left);
1709        let tail_anchor = display_map.buffer_snapshot.anchor_before(tail);
1710
1711        let mut pending_selection = self
1712            .selections
1713            .pending_anchor()
1714            .expect("extend_selection not called with pending selection");
1715        if position >= tail {
1716            pending_selection.start = tail_anchor.clone();
1717        } else {
1718            pending_selection.end = tail_anchor.clone();
1719            pending_selection.reversed = true;
1720        }
1721
1722        let mut pending_mode = self.selections.pending_mode().unwrap();
1723        match &mut pending_mode {
1724            SelectMode::Word(range) | SelectMode::Line(range) => {
1725                *range = tail_anchor.clone()..tail_anchor
1726            }
1727            _ => {}
1728        }
1729
1730        self.change_selections(Some(Autoscroll::Fit), cx, |s| {
1731            s.set_pending(pending_selection, pending_mode)
1732        });
1733    }
1734
1735    fn begin_selection(
1736        &mut self,
1737        position: DisplayPoint,
1738        add: bool,
1739        click_count: usize,
1740        cx: &mut ViewContext<Self>,
1741    ) {
1742        if !self.focused {
1743            cx.focus_self();
1744        }
1745
1746        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
1747        let buffer = &display_map.buffer_snapshot;
1748        let newest_selection = self.selections.newest_anchor().clone();
1749        let position = display_map.clip_point(position, Bias::Left);
1750
1751        let start;
1752        let end;
1753        let mode;
1754        let auto_scroll;
1755        match click_count {
1756            1 => {
1757                start = buffer.anchor_before(position.to_point(&display_map));
1758                end = start.clone();
1759                mode = SelectMode::Character;
1760                auto_scroll = true;
1761            }
1762            2 => {
1763                let range = movement::surrounding_word(&display_map, position);
1764                start = buffer.anchor_before(range.start.to_point(&display_map));
1765                end = buffer.anchor_before(range.end.to_point(&display_map));
1766                mode = SelectMode::Word(start.clone()..end.clone());
1767                auto_scroll = true;
1768            }
1769            3 => {
1770                let position = display_map
1771                    .clip_point(position, Bias::Left)
1772                    .to_point(&display_map);
1773                let line_start = display_map.prev_line_boundary(position).0;
1774                let next_line_start = buffer.clip_point(
1775                    display_map.next_line_boundary(position).0 + Point::new(1, 0),
1776                    Bias::Left,
1777                );
1778                start = buffer.anchor_before(line_start);
1779                end = buffer.anchor_before(next_line_start);
1780                mode = SelectMode::Line(start.clone()..end.clone());
1781                auto_scroll = true;
1782            }
1783            _ => {
1784                start = buffer.anchor_before(0);
1785                end = buffer.anchor_before(buffer.len());
1786                mode = SelectMode::All;
1787                auto_scroll = false;
1788            }
1789        }
1790
1791        self.change_selections(auto_scroll.then(|| Autoscroll::Newest), cx, |s| {
1792            if !add {
1793                s.clear_disjoint();
1794            } else if click_count > 1 {
1795                s.delete(newest_selection.id)
1796            }
1797
1798            s.set_pending_anchor_range(start..end, mode);
1799        });
1800    }
1801
1802    fn begin_columnar_selection(
1803        &mut self,
1804        position: DisplayPoint,
1805        goal_column: u32,
1806        cx: &mut ViewContext<Self>,
1807    ) {
1808        if !self.focused {
1809            cx.focus_self();
1810        }
1811
1812        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
1813        let tail = self.selections.newest::<Point>(cx).tail();
1814        self.columnar_selection_tail = Some(display_map.buffer_snapshot.anchor_before(tail));
1815
1816        self.select_columns(
1817            tail.to_display_point(&display_map),
1818            position,
1819            goal_column,
1820            &display_map,
1821            cx,
1822        );
1823    }
1824
1825    fn update_selection(
1826        &mut self,
1827        position: DisplayPoint,
1828        goal_column: u32,
1829        scroll_position: Vector2F,
1830        cx: &mut ViewContext<Self>,
1831    ) {
1832        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
1833
1834        if let Some(tail) = self.columnar_selection_tail.as_ref() {
1835            let tail = tail.to_display_point(&display_map);
1836            self.select_columns(tail, position, goal_column, &display_map, cx);
1837        } else if let Some(mut pending) = self.selections.pending_anchor() {
1838            let buffer = self.buffer.read(cx).snapshot(cx);
1839            let head;
1840            let tail;
1841            let mode = self.selections.pending_mode().unwrap();
1842            match &mode {
1843                SelectMode::Character => {
1844                    head = position.to_point(&display_map);
1845                    tail = pending.tail().to_point(&buffer);
1846                }
1847                SelectMode::Word(original_range) => {
1848                    let original_display_range = original_range.start.to_display_point(&display_map)
1849                        ..original_range.end.to_display_point(&display_map);
1850                    let original_buffer_range = original_display_range.start.to_point(&display_map)
1851                        ..original_display_range.end.to_point(&display_map);
1852                    if movement::is_inside_word(&display_map, position)
1853                        || original_display_range.contains(&position)
1854                    {
1855                        let word_range = movement::surrounding_word(&display_map, position);
1856                        if word_range.start < original_display_range.start {
1857                            head = word_range.start.to_point(&display_map);
1858                        } else {
1859                            head = word_range.end.to_point(&display_map);
1860                        }
1861                    } else {
1862                        head = position.to_point(&display_map);
1863                    }
1864
1865                    if head <= original_buffer_range.start {
1866                        tail = original_buffer_range.end;
1867                    } else {
1868                        tail = original_buffer_range.start;
1869                    }
1870                }
1871                SelectMode::Line(original_range) => {
1872                    let original_range = original_range.to_point(&display_map.buffer_snapshot);
1873
1874                    let position = display_map
1875                        .clip_point(position, Bias::Left)
1876                        .to_point(&display_map);
1877                    let line_start = display_map.prev_line_boundary(position).0;
1878                    let next_line_start = buffer.clip_point(
1879                        display_map.next_line_boundary(position).0 + Point::new(1, 0),
1880                        Bias::Left,
1881                    );
1882
1883                    if line_start < original_range.start {
1884                        head = line_start
1885                    } else {
1886                        head = next_line_start
1887                    }
1888
1889                    if head <= original_range.start {
1890                        tail = original_range.end;
1891                    } else {
1892                        tail = original_range.start;
1893                    }
1894                }
1895                SelectMode::All => {
1896                    return;
1897                }
1898            };
1899
1900            if head < tail {
1901                pending.start = buffer.anchor_before(head);
1902                pending.end = buffer.anchor_before(tail);
1903                pending.reversed = true;
1904            } else {
1905                pending.start = buffer.anchor_before(tail);
1906                pending.end = buffer.anchor_before(head);
1907                pending.reversed = false;
1908            }
1909
1910            self.change_selections(None, cx, |s| {
1911                s.set_pending(pending, mode);
1912            });
1913        } else {
1914            log::error!("update_selection dispatched with no pending selection");
1915            return;
1916        }
1917
1918        self.set_scroll_position(scroll_position, cx);
1919        cx.notify();
1920    }
1921
1922    fn end_selection(&mut self, cx: &mut ViewContext<Self>) {
1923        self.columnar_selection_tail.take();
1924        if self.selections.pending_anchor().is_some() {
1925            let selections = self.selections.all::<usize>(cx);
1926            self.change_selections(None, cx, |s| {
1927                s.select(selections);
1928                s.clear_pending();
1929            });
1930        }
1931    }
1932
1933    fn select_columns(
1934        &mut self,
1935        tail: DisplayPoint,
1936        head: DisplayPoint,
1937        goal_column: u32,
1938        display_map: &DisplaySnapshot,
1939        cx: &mut ViewContext<Self>,
1940    ) {
1941        let start_row = cmp::min(tail.row(), head.row());
1942        let end_row = cmp::max(tail.row(), head.row());
1943        let start_column = cmp::min(tail.column(), goal_column);
1944        let end_column = cmp::max(tail.column(), goal_column);
1945        let reversed = start_column < tail.column();
1946
1947        let selection_ranges = (start_row..=end_row)
1948            .filter_map(|row| {
1949                if start_column <= display_map.line_len(row) && !display_map.is_block_line(row) {
1950                    let start = display_map
1951                        .clip_point(DisplayPoint::new(row, start_column), Bias::Left)
1952                        .to_point(display_map);
1953                    let end = display_map
1954                        .clip_point(DisplayPoint::new(row, end_column), Bias::Right)
1955                        .to_point(display_map);
1956                    if reversed {
1957                        Some(end..start)
1958                    } else {
1959                        Some(start..end)
1960                    }
1961                } else {
1962                    None
1963                }
1964            })
1965            .collect::<Vec<_>>();
1966
1967        self.change_selections(None, cx, |s| {
1968            s.select_ranges(selection_ranges);
1969        });
1970        cx.notify();
1971    }
1972
1973    pub fn has_pending_nonempty_selection(&self) -> bool {
1974        let pending_nonempty_selection = match self.selections.pending_anchor() {
1975            Some(Selection { start, end, .. }) => start != end,
1976            None => false,
1977        };
1978        pending_nonempty_selection || self.columnar_selection_tail.is_some()
1979    }
1980
1981    pub fn has_pending_selection(&self) -> bool {
1982        self.selections.pending_anchor().is_some() || self.columnar_selection_tail.is_some()
1983    }
1984
1985    pub fn cancel(&mut self, _: &Cancel, cx: &mut ViewContext<Self>) {
1986        if self.take_rename(false, cx).is_some() {
1987            return;
1988        }
1989
1990        if hide_hover(self, cx) {
1991            return;
1992        }
1993
1994        if self.hide_context_menu(cx).is_some() {
1995            return;
1996        }
1997
1998        if self.snippet_stack.pop().is_some() {
1999            return;
2000        }
2001
2002        if self.mode == EditorMode::Full {
2003            if self.active_diagnostics.is_some() {
2004                self.dismiss_diagnostics(cx);
2005                return;
2006            }
2007
2008            if self.change_selections(Some(Autoscroll::Fit), cx, |s| s.try_cancel()) {
2009                return;
2010            }
2011        }
2012
2013        cx.propagate_action();
2014    }
2015
2016    pub fn handle_input(&mut self, text: &str, cx: &mut ViewContext<Self>) {
2017        if !self.input_enabled {
2018            return;
2019        }
2020
2021        let text: Arc<str> = text.into();
2022        let selections = self.selections.all_adjusted(cx);
2023        let mut edits = Vec::new();
2024        let mut new_selections = Vec::with_capacity(selections.len());
2025        let mut new_autoclose_regions = Vec::new();
2026        let snapshot = self.buffer.read(cx).read(cx);
2027
2028        for (selection, autoclose_region) in
2029            self.selections_with_autoclose_regions(selections, &snapshot)
2030        {
2031            if let Some(language) = snapshot.language_at(selection.head()) {
2032                // Determine if the inserted text matches the opening or closing
2033                // bracket of any of this language's bracket pairs.
2034                let mut bracket_pair = None;
2035                let mut is_bracket_pair_start = false;
2036                for pair in language.brackets() {
2037                    if pair.close && pair.start.ends_with(text.as_ref()) {
2038                        bracket_pair = Some(pair.clone());
2039                        is_bracket_pair_start = true;
2040                        break;
2041                    } else if pair.end.as_str() == text.as_ref() {
2042                        bracket_pair = Some(pair.clone());
2043                        break;
2044                    }
2045                }
2046
2047                if let Some(bracket_pair) = bracket_pair {
2048                    if selection.is_empty() {
2049                        if is_bracket_pair_start {
2050                            let prefix_len = bracket_pair.start.len() - text.len();
2051
2052                            // If the inserted text is a suffix of an opening bracket and the
2053                            // selection is preceded by the rest of the opening bracket, then
2054                            // insert the closing bracket.
2055                            let following_text_allows_autoclose = snapshot
2056                                .chars_at(selection.start)
2057                                .next()
2058                                .map_or(true, |c| language.should_autoclose_before(c));
2059                            let preceding_text_matches_prefix = prefix_len == 0
2060                                || (selection.start.column >= (prefix_len as u32)
2061                                    && snapshot.contains_str_at(
2062                                        Point::new(
2063                                            selection.start.row,
2064                                            selection.start.column - (prefix_len as u32),
2065                                        ),
2066                                        &bracket_pair.start[..prefix_len],
2067                                    ));
2068                            if following_text_allows_autoclose && preceding_text_matches_prefix {
2069                                let anchor = snapshot.anchor_before(selection.end);
2070                                new_selections
2071                                    .push((selection.map(|_| anchor.clone()), text.len()));
2072                                new_autoclose_regions.push((
2073                                    anchor.clone(),
2074                                    text.len(),
2075                                    selection.id,
2076                                    bracket_pair.clone(),
2077                                ));
2078                                edits.push((
2079                                    selection.range(),
2080                                    format!("{}{}", text, bracket_pair.end).into(),
2081                                ));
2082                                continue;
2083                            }
2084                        }
2085
2086                        if let Some(region) = autoclose_region {
2087                            // If the selection is followed by an auto-inserted closing bracket,
2088                            // then don't insert that closing bracket again; just move the selection
2089                            // past the closing bracket.
2090                            let should_skip = selection.end == region.range.end.to_point(&snapshot)
2091                                && text.as_ref() == region.pair.end.as_str();
2092                            if should_skip {
2093                                let anchor = snapshot.anchor_after(selection.end);
2094                                new_selections.push((
2095                                    selection.map(|_| anchor.clone()),
2096                                    region.pair.end.len(),
2097                                ));
2098                                continue;
2099                            }
2100                        }
2101                    }
2102                    // If an opening bracket is typed while text is selected, then
2103                    // surround that text with the bracket pair.
2104                    else if is_bracket_pair_start {
2105                        edits.push((selection.start..selection.start, text.clone()));
2106                        edits.push((
2107                            selection.end..selection.end,
2108                            bracket_pair.end.as_str().into(),
2109                        ));
2110                        new_selections.push((
2111                            Selection {
2112                                id: selection.id,
2113                                start: snapshot.anchor_after(selection.start),
2114                                end: snapshot.anchor_before(selection.end),
2115                                reversed: selection.reversed,
2116                                goal: selection.goal,
2117                            },
2118                            0,
2119                        ));
2120                        continue;
2121                    }
2122                }
2123            }
2124
2125            // If not handling any auto-close operation, then just replace the selected
2126            // text with the given input and move the selection to the end of the
2127            // newly inserted text.
2128            let anchor = snapshot.anchor_after(selection.end);
2129            new_selections.push((selection.map(|_| anchor.clone()), 0));
2130            edits.push((selection.start..selection.end, text.clone()));
2131        }
2132
2133        drop(snapshot);
2134        self.transact(cx, |this, cx| {
2135            this.buffer.update(cx, |buffer, cx| {
2136                buffer.edit(edits, Some(AutoindentMode::EachLine), cx);
2137            });
2138
2139            let new_anchor_selections = new_selections.iter().map(|e| &e.0);
2140            let new_selection_deltas = new_selections.iter().map(|e| e.1);
2141            let snapshot = this.buffer.read(cx).read(cx);
2142            let new_selections = resolve_multiple::<usize, _>(new_anchor_selections, &snapshot)
2143                .zip(new_selection_deltas)
2144                .map(|(selection, delta)| selection.map(|e| e + delta))
2145                .collect::<Vec<_>>();
2146
2147            let mut i = 0;
2148            for (position, delta, selection_id, pair) in new_autoclose_regions {
2149                let position = position.to_offset(&snapshot) + delta;
2150                let start = snapshot.anchor_before(position);
2151                let end = snapshot.anchor_after(position);
2152                while let Some(existing_state) = this.autoclose_regions.get(i) {
2153                    match existing_state.range.start.cmp(&start, &snapshot) {
2154                        Ordering::Less => i += 1,
2155                        Ordering::Greater => break,
2156                        Ordering::Equal => match end.cmp(&existing_state.range.end, &snapshot) {
2157                            Ordering::Less => i += 1,
2158                            Ordering::Equal => break,
2159                            Ordering::Greater => break,
2160                        },
2161                    }
2162                }
2163                this.autoclose_regions.insert(
2164                    i,
2165                    AutocloseRegion {
2166                        selection_id,
2167                        range: start..end,
2168                        pair,
2169                    },
2170                );
2171            }
2172
2173            drop(snapshot);
2174            this.change_selections(Some(Autoscroll::Fit), cx, |s| s.select(new_selections));
2175            this.trigger_completion_on_input(&text, cx);
2176        });
2177    }
2178
2179    pub fn newline(&mut self, _: &Newline, cx: &mut ViewContext<Self>) {
2180        self.transact(cx, |this, cx| {
2181            let (edits, selection_fixup_info): (Vec<_>, Vec<_>) = {
2182                let selections = this.selections.all::<usize>(cx);
2183
2184                let buffer = this.buffer.read(cx).snapshot(cx);
2185                selections
2186                    .iter()
2187                    .map(|selection| {
2188                        let start_point = selection.start.to_point(&buffer);
2189                        let mut indent = buffer.indent_size_for_line(start_point.row);
2190                        indent.len = cmp::min(indent.len, start_point.column);
2191                        let start = selection.start;
2192                        let end = selection.end;
2193
2194                        let mut insert_extra_newline = false;
2195                        if let Some(language) = buffer.language_at(start) {
2196                            let leading_whitespace_len = buffer
2197                                .reversed_chars_at(start)
2198                                .take_while(|c| c.is_whitespace() && *c != '\n')
2199                                .map(|c| c.len_utf8())
2200                                .sum::<usize>();
2201
2202                            let trailing_whitespace_len = buffer
2203                                .chars_at(end)
2204                                .take_while(|c| c.is_whitespace() && *c != '\n')
2205                                .map(|c| c.len_utf8())
2206                                .sum::<usize>();
2207
2208                            insert_extra_newline = language.brackets().iter().any(|pair| {
2209                                let pair_start = pair.start.trim_end();
2210                                let pair_end = pair.end.trim_start();
2211
2212                                pair.newline
2213                                    && buffer
2214                                        .contains_str_at(end + trailing_whitespace_len, pair_end)
2215                                    && buffer.contains_str_at(
2216                                        (start - leading_whitespace_len)
2217                                            .saturating_sub(pair_start.len()),
2218                                        pair_start,
2219                                    )
2220                            });
2221                        }
2222
2223                        let mut new_text = String::with_capacity(1 + indent.len as usize);
2224                        new_text.push('\n');
2225                        new_text.extend(indent.chars());
2226                        if insert_extra_newline {
2227                            new_text = new_text.repeat(2);
2228                        }
2229
2230                        let anchor = buffer.anchor_after(end);
2231                        let new_selection = selection.map(|_| anchor.clone());
2232                        (
2233                            (start..end, new_text),
2234                            (insert_extra_newline, new_selection),
2235                        )
2236                    })
2237                    .unzip()
2238            };
2239
2240            this.edit_with_autoindent(edits, cx);
2241            let buffer = this.buffer.read(cx).snapshot(cx);
2242            let new_selections = selection_fixup_info
2243                .into_iter()
2244                .map(|(extra_newline_inserted, new_selection)| {
2245                    let mut cursor = new_selection.end.to_point(&buffer);
2246                    if extra_newline_inserted {
2247                        cursor.row -= 1;
2248                        cursor.column = buffer.line_len(cursor.row);
2249                    }
2250                    new_selection.map(|_| cursor)
2251                })
2252                .collect();
2253
2254            this.change_selections(Some(Autoscroll::Fit), cx, |s| s.select(new_selections));
2255        });
2256    }
2257
2258    pub fn newline_below(&mut self, _: &NewlineBelow, cx: &mut ViewContext<Self>) {
2259        let buffer = self.buffer.read(cx);
2260        let snapshot = buffer.snapshot(cx);
2261
2262        let mut edits = Vec::new();
2263        let mut rows = Vec::new();
2264        let mut rows_inserted = 0;
2265
2266        for selection in self.selections.all_adjusted(cx) {
2267            let cursor = selection.head();
2268            let row = cursor.row;
2269
2270            let end_of_line = snapshot
2271                .clip_point(Point::new(row, snapshot.line_len(row)), Bias::Left)
2272                .to_point(&snapshot);
2273
2274            let newline = "\n".to_string();
2275            edits.push((end_of_line..end_of_line, newline));
2276
2277            rows_inserted += 1;
2278            rows.push(row + rows_inserted);
2279        }
2280
2281        self.transact(cx, |editor, cx| {
2282            editor.edit_with_autoindent(edits, cx);
2283
2284            editor.change_selections(Some(Autoscroll::Fit), cx, |s| {
2285                let mut index = 0;
2286                s.move_cursors_with(|map, _, _| {
2287                    let row = rows[index];
2288                    index += 1;
2289
2290                    let point = Point::new(row, 0);
2291                    let boundary = map.next_line_boundary(point).1;
2292                    let clipped = map.clip_point(boundary, Bias::Left);
2293
2294                    (clipped, SelectionGoal::None)
2295                });
2296            });
2297        });
2298    }
2299
2300    pub fn insert(&mut self, text: &str, cx: &mut ViewContext<Self>) {
2301        let text: Arc<str> = text.into();
2302        self.transact(cx, |this, cx| {
2303            let old_selections = this.selections.all_adjusted(cx);
2304            let selection_anchors = this.buffer.update(cx, |buffer, cx| {
2305                let anchors = {
2306                    let snapshot = buffer.read(cx);
2307                    old_selections
2308                        .iter()
2309                        .map(|s| {
2310                            let anchor = snapshot.anchor_after(s.end);
2311                            s.map(|_| anchor.clone())
2312                        })
2313                        .collect::<Vec<_>>()
2314                };
2315                buffer.edit(
2316                    old_selections
2317                        .iter()
2318                        .map(|s| (s.start..s.end, text.clone())),
2319                    Some(AutoindentMode::EachLine),
2320                    cx,
2321                );
2322                anchors
2323            });
2324
2325            this.change_selections(Some(Autoscroll::Fit), cx, |s| {
2326                s.select_anchors(selection_anchors);
2327            })
2328        });
2329    }
2330
2331    fn trigger_completion_on_input(&mut self, text: &str, cx: &mut ViewContext<Self>) {
2332        if !cx.global::<Settings>().show_completions_on_input {
2333            return;
2334        }
2335
2336        let selection = self.selections.newest_anchor();
2337        if self
2338            .buffer
2339            .read(cx)
2340            .is_completion_trigger(selection.head(), text, cx)
2341        {
2342            self.show_completions(&ShowCompletions, cx);
2343        } else {
2344            self.hide_context_menu(cx);
2345        }
2346    }
2347
2348    /// If any empty selections is touching the start of its innermost containing autoclose
2349    /// region, expand it to select the brackets.
2350    fn select_autoclose_pair(&mut self, cx: &mut ViewContext<Self>) {
2351        let selections = self.selections.all::<usize>(cx);
2352        let buffer = self.buffer.read(cx).read(cx);
2353        let mut new_selections = Vec::new();
2354        for (mut selection, region) in self.selections_with_autoclose_regions(selections, &buffer) {
2355            if let (Some(region), true) = (region, selection.is_empty()) {
2356                let mut range = region.range.to_offset(&buffer);
2357                if selection.start == range.start {
2358                    if range.start >= region.pair.start.len() {
2359                        range.start -= region.pair.start.len();
2360                        if buffer.contains_str_at(range.start, &region.pair.start) {
2361                            if buffer.contains_str_at(range.end, &region.pair.end) {
2362                                range.end += region.pair.end.len();
2363                                selection.start = range.start;
2364                                selection.end = range.end;
2365                            }
2366                        }
2367                    }
2368                }
2369            }
2370            new_selections.push(selection);
2371        }
2372
2373        drop(buffer);
2374        self.change_selections(None, cx, |selections| selections.select(new_selections));
2375    }
2376
2377    /// Iterate the given selections, and for each one, find the smallest surrounding
2378    /// autoclose region. This uses the ordering of the selections and the autoclose
2379    /// regions to avoid repeated comparisons.
2380    fn selections_with_autoclose_regions<'a, D: ToOffset + Clone>(
2381        &'a self,
2382        selections: impl IntoIterator<Item = Selection<D>>,
2383        buffer: &'a MultiBufferSnapshot,
2384    ) -> impl Iterator<Item = (Selection<D>, Option<&'a AutocloseRegion>)> {
2385        let mut i = 0;
2386        let mut regions = self.autoclose_regions.as_slice();
2387        selections.into_iter().map(move |selection| {
2388            let range = selection.start.to_offset(buffer)..selection.end.to_offset(buffer);
2389
2390            let mut enclosing = None;
2391            while let Some(pair_state) = regions.get(i) {
2392                if pair_state.range.end.to_offset(buffer) < range.start {
2393                    regions = &regions[i + 1..];
2394                    i = 0;
2395                } else if pair_state.range.start.to_offset(buffer) > range.end {
2396                    break;
2397                } else if pair_state.selection_id == selection.id {
2398                    enclosing = Some(pair_state);
2399                    i += 1;
2400                }
2401            }
2402
2403            (selection.clone(), enclosing)
2404        })
2405    }
2406
2407    /// Remove any autoclose regions that no longer contain their selection.
2408    fn invalidate_autoclose_regions(
2409        &mut self,
2410        mut selections: &[Selection<Anchor>],
2411        buffer: &MultiBufferSnapshot,
2412    ) {
2413        self.autoclose_regions.retain(|state| {
2414            let mut i = 0;
2415            while let Some(selection) = selections.get(i) {
2416                if selection.end.cmp(&state.range.start, buffer).is_lt() {
2417                    selections = &selections[1..];
2418                    continue;
2419                }
2420                if selection.start.cmp(&state.range.end, buffer).is_gt() {
2421                    break;
2422                }
2423                if selection.id == state.selection_id {
2424                    return true;
2425                } else {
2426                    i += 1;
2427                }
2428            }
2429            false
2430        });
2431    }
2432
2433    fn completion_query(buffer: &MultiBufferSnapshot, position: impl ToOffset) -> Option<String> {
2434        let offset = position.to_offset(buffer);
2435        let (word_range, kind) = buffer.surrounding_word(offset);
2436        if offset > word_range.start && kind == Some(CharKind::Word) {
2437            Some(
2438                buffer
2439                    .text_for_range(word_range.start..offset)
2440                    .collect::<String>(),
2441            )
2442        } else {
2443            None
2444        }
2445    }
2446
2447    fn show_completions(&mut self, _: &ShowCompletions, cx: &mut ViewContext<Self>) {
2448        if self.pending_rename.is_some() {
2449            return;
2450        }
2451
2452        let project = if let Some(project) = self.project.clone() {
2453            project
2454        } else {
2455            return;
2456        };
2457
2458        let position = self.selections.newest_anchor().head();
2459        let (buffer, buffer_position) = if let Some(output) = self
2460            .buffer
2461            .read(cx)
2462            .text_anchor_for_position(position.clone(), cx)
2463        {
2464            output
2465        } else {
2466            return;
2467        };
2468
2469        let query = Self::completion_query(&self.buffer.read(cx).read(cx), position.clone());
2470        let completions = project.update(cx, |project, cx| {
2471            project.completions(&buffer, buffer_position, cx)
2472        });
2473
2474        let id = post_inc(&mut self.next_completion_id);
2475        let task = cx.spawn_weak(|this, mut cx| {
2476            async move {
2477                let completions = completions.await?;
2478                if completions.is_empty() {
2479                    return Ok(());
2480                }
2481
2482                let mut menu = CompletionsMenu {
2483                    id,
2484                    initial_position: position,
2485                    match_candidates: completions
2486                        .iter()
2487                        .enumerate()
2488                        .map(|(id, completion)| {
2489                            StringMatchCandidate::new(
2490                                id,
2491                                completion.label.text[completion.label.filter_range.clone()].into(),
2492                            )
2493                        })
2494                        .collect(),
2495                    buffer,
2496                    completions: completions.into(),
2497                    matches: Vec::new().into(),
2498                    selected_item: 0,
2499                    list: Default::default(),
2500                };
2501
2502                menu.filter(query.as_deref(), cx.background()).await;
2503
2504                if let Some(this) = this.upgrade(&cx) {
2505                    this.update(&mut cx, |this, cx| {
2506                        match this.context_menu.as_ref() {
2507                            None => {}
2508                            Some(ContextMenu::Completions(prev_menu)) => {
2509                                if prev_menu.id > menu.id {
2510                                    return;
2511                                }
2512                            }
2513                            _ => return,
2514                        }
2515
2516                        this.completion_tasks.retain(|(id, _)| *id > menu.id);
2517                        if this.focused {
2518                            this.show_context_menu(ContextMenu::Completions(menu), cx);
2519                        }
2520
2521                        cx.notify();
2522                    });
2523                }
2524                Ok::<_, anyhow::Error>(())
2525            }
2526            .log_err()
2527        });
2528        self.completion_tasks.push((id, task));
2529    }
2530
2531    pub fn confirm_completion(
2532        &mut self,
2533        action: &ConfirmCompletion,
2534        cx: &mut ViewContext<Self>,
2535    ) -> Option<Task<Result<()>>> {
2536        use language::ToOffset as _;
2537
2538        let completions_menu = if let ContextMenu::Completions(menu) = self.hide_context_menu(cx)? {
2539            menu
2540        } else {
2541            return None;
2542        };
2543
2544        let mat = completions_menu
2545            .matches
2546            .get(action.item_ix.unwrap_or(completions_menu.selected_item))?;
2547        let buffer_handle = completions_menu.buffer;
2548        let completion = completions_menu.completions.get(mat.candidate_id)?;
2549
2550        let snippet;
2551        let text;
2552        if completion.is_snippet() {
2553            snippet = Some(Snippet::parse(&completion.new_text).log_err()?);
2554            text = snippet.as_ref().unwrap().text.clone();
2555        } else {
2556            snippet = None;
2557            text = completion.new_text.clone();
2558        };
2559        let selections = self.selections.all::<usize>(cx);
2560        let buffer = buffer_handle.read(cx);
2561        let old_range = completion.old_range.to_offset(buffer);
2562        let old_text = buffer.text_for_range(old_range.clone()).collect::<String>();
2563
2564        let newest_selection = self.selections.newest_anchor();
2565        if newest_selection.start.buffer_id != Some(buffer_handle.id()) {
2566            return None;
2567        }
2568
2569        let lookbehind = newest_selection
2570            .start
2571            .text_anchor
2572            .to_offset(buffer)
2573            .saturating_sub(old_range.start);
2574        let lookahead = old_range
2575            .end
2576            .saturating_sub(newest_selection.end.text_anchor.to_offset(buffer));
2577        let mut common_prefix_len = old_text
2578            .bytes()
2579            .zip(text.bytes())
2580            .take_while(|(a, b)| a == b)
2581            .count();
2582
2583        let snapshot = self.buffer.read(cx).snapshot(cx);
2584        let mut ranges = Vec::new();
2585        for selection in &selections {
2586            if snapshot.contains_str_at(selection.start.saturating_sub(lookbehind), &old_text) {
2587                let start = selection.start.saturating_sub(lookbehind);
2588                let end = selection.end + lookahead;
2589                ranges.push(start + common_prefix_len..end);
2590            } else {
2591                common_prefix_len = 0;
2592                ranges.clear();
2593                ranges.extend(selections.iter().map(|s| {
2594                    if s.id == newest_selection.id {
2595                        old_range.clone()
2596                    } else {
2597                        s.start..s.end
2598                    }
2599                }));
2600                break;
2601            }
2602        }
2603        let text = &text[common_prefix_len..];
2604
2605        self.transact(cx, |this, cx| {
2606            if let Some(mut snippet) = snippet {
2607                snippet.text = text.to_string();
2608                for tabstop in snippet.tabstops.iter_mut().flatten() {
2609                    tabstop.start -= common_prefix_len as isize;
2610                    tabstop.end -= common_prefix_len as isize;
2611                }
2612
2613                this.insert_snippet(&ranges, snippet, cx).log_err();
2614            } else {
2615                this.buffer.update(cx, |buffer, cx| {
2616                    buffer.edit(
2617                        ranges.iter().map(|range| (range.clone(), text)),
2618                        Some(AutoindentMode::EachLine),
2619                        cx,
2620                    );
2621                });
2622            }
2623        });
2624
2625        let project = self.project.clone()?;
2626        let apply_edits = project.update(cx, |project, cx| {
2627            project.apply_additional_edits_for_completion(
2628                buffer_handle,
2629                completion.clone(),
2630                true,
2631                cx,
2632            )
2633        });
2634        Some(cx.foreground().spawn(async move {
2635            apply_edits.await?;
2636            Ok(())
2637        }))
2638    }
2639
2640    pub fn toggle_code_actions(&mut self, action: &ToggleCodeActions, cx: &mut ViewContext<Self>) {
2641        if matches!(
2642            self.context_menu.as_ref(),
2643            Some(ContextMenu::CodeActions(_))
2644        ) {
2645            self.context_menu.take();
2646            cx.notify();
2647            return;
2648        }
2649
2650        let deployed_from_indicator = action.deployed_from_indicator;
2651        let mut task = self.code_actions_task.take();
2652        cx.spawn_weak(|this, mut cx| async move {
2653            while let Some(prev_task) = task {
2654                prev_task.await;
2655                task = this
2656                    .upgrade(&cx)
2657                    .and_then(|this| this.update(&mut cx, |this, _| this.code_actions_task.take()));
2658            }
2659
2660            if let Some(this) = this.upgrade(&cx) {
2661                this.update(&mut cx, |this, cx| {
2662                    if this.focused {
2663                        if let Some((buffer, actions)) = this.available_code_actions.clone() {
2664                            this.show_context_menu(
2665                                ContextMenu::CodeActions(CodeActionsMenu {
2666                                    buffer,
2667                                    actions,
2668                                    selected_item: Default::default(),
2669                                    list: Default::default(),
2670                                    deployed_from_indicator,
2671                                }),
2672                                cx,
2673                            );
2674                        }
2675                    }
2676                })
2677            }
2678            Ok::<_, anyhow::Error>(())
2679        })
2680        .detach_and_log_err(cx);
2681    }
2682
2683    pub fn confirm_code_action(
2684        workspace: &mut Workspace,
2685        action: &ConfirmCodeAction,
2686        cx: &mut ViewContext<Workspace>,
2687    ) -> Option<Task<Result<()>>> {
2688        let editor = workspace.active_item(cx)?.act_as::<Editor>(cx)?;
2689        let actions_menu = if let ContextMenu::CodeActions(menu) =
2690            editor.update(cx, |editor, cx| editor.hide_context_menu(cx))?
2691        {
2692            menu
2693        } else {
2694            return None;
2695        };
2696        let action_ix = action.item_ix.unwrap_or(actions_menu.selected_item);
2697        let action = actions_menu.actions.get(action_ix)?.clone();
2698        let title = action.lsp_action.title.clone();
2699        let buffer = actions_menu.buffer;
2700
2701        let apply_code_actions = workspace.project().clone().update(cx, |project, cx| {
2702            project.apply_code_action(buffer, action, true, cx)
2703        });
2704        Some(cx.spawn(|workspace, cx| async move {
2705            let project_transaction = apply_code_actions.await?;
2706            Self::open_project_transaction(editor, workspace, project_transaction, title, cx).await
2707        }))
2708    }
2709
2710    async fn open_project_transaction(
2711        this: ViewHandle<Editor>,
2712        workspace: ViewHandle<Workspace>,
2713        transaction: ProjectTransaction,
2714        title: String,
2715        mut cx: AsyncAppContext,
2716    ) -> Result<()> {
2717        let replica_id = this.read_with(&cx, |this, cx| this.replica_id(cx));
2718
2719        let mut entries = transaction.0.into_iter().collect::<Vec<_>>();
2720        entries.sort_unstable_by_key(|(buffer, _)| {
2721            buffer.read_with(&cx, |buffer, _| buffer.file().map(|f| f.path().clone()))
2722        });
2723
2724        // If the project transaction's edits are all contained within this editor, then
2725        // avoid opening a new editor to display them.
2726
2727        if let Some((buffer, transaction)) = entries.first() {
2728            if entries.len() == 1 {
2729                let excerpt = this.read_with(&cx, |editor, cx| {
2730                    editor
2731                        .buffer()
2732                        .read(cx)
2733                        .excerpt_containing(editor.selections.newest_anchor().head(), cx)
2734                });
2735                if let Some((_, excerpted_buffer, excerpt_range)) = excerpt {
2736                    if excerpted_buffer == *buffer {
2737                        let all_edits_within_excerpt = buffer.read_with(&cx, |buffer, _| {
2738                            let excerpt_range = excerpt_range.to_offset(buffer);
2739                            buffer
2740                                .edited_ranges_for_transaction(transaction)
2741                                .all(|range| {
2742                                    excerpt_range.start <= range.start
2743                                        && excerpt_range.end >= range.end
2744                                })
2745                        });
2746
2747                        if all_edits_within_excerpt {
2748                            return Ok(());
2749                        }
2750                    }
2751                }
2752            }
2753        } else {
2754            return Ok(());
2755        }
2756
2757        let mut ranges_to_highlight = Vec::new();
2758        let excerpt_buffer = cx.add_model(|cx| {
2759            let mut multibuffer = MultiBuffer::new(replica_id).with_title(title);
2760            for (buffer_handle, transaction) in &entries {
2761                let buffer = buffer_handle.read(cx);
2762                ranges_to_highlight.extend(
2763                    multibuffer.push_excerpts_with_context_lines(
2764                        buffer_handle.clone(),
2765                        buffer
2766                            .edited_ranges_for_transaction::<usize>(transaction)
2767                            .collect(),
2768                        1,
2769                        cx,
2770                    ),
2771                );
2772            }
2773            multibuffer.push_transaction(entries.iter().map(|(b, t)| (b, t)));
2774            multibuffer
2775        });
2776
2777        workspace.update(&mut cx, |workspace, cx| {
2778            let project = workspace.project().clone();
2779            let editor =
2780                cx.add_view(|cx| Editor::for_multibuffer(excerpt_buffer, Some(project), cx));
2781            workspace.add_item(Box::new(editor.clone()), cx);
2782            editor.update(cx, |editor, cx| {
2783                editor.highlight_background::<Self>(
2784                    ranges_to_highlight,
2785                    |theme| theme.editor.highlighted_line_background,
2786                    cx,
2787                );
2788            });
2789        });
2790
2791        Ok(())
2792    }
2793
2794    fn refresh_code_actions(&mut self, cx: &mut ViewContext<Self>) -> Option<()> {
2795        let project = self.project.as_ref()?;
2796        let buffer = self.buffer.read(cx);
2797        let newest_selection = self.selections.newest_anchor().clone();
2798        let (start_buffer, start) = buffer.text_anchor_for_position(newest_selection.start, cx)?;
2799        let (end_buffer, end) = buffer.text_anchor_for_position(newest_selection.end, cx)?;
2800        if start_buffer != end_buffer {
2801            return None;
2802        }
2803
2804        let actions = project.update(cx, |project, cx| {
2805            project.code_actions(&start_buffer, start..end, cx)
2806        });
2807        self.code_actions_task = Some(cx.spawn_weak(|this, mut cx| async move {
2808            let actions = actions.await;
2809            if let Some(this) = this.upgrade(&cx) {
2810                this.update(&mut cx, |this, cx| {
2811                    this.available_code_actions = actions.log_err().and_then(|actions| {
2812                        if actions.is_empty() {
2813                            None
2814                        } else {
2815                            Some((start_buffer, actions.into()))
2816                        }
2817                    });
2818                    cx.notify();
2819                })
2820            }
2821        }));
2822        None
2823    }
2824
2825    fn refresh_document_highlights(&mut self, cx: &mut ViewContext<Self>) -> Option<()> {
2826        if self.pending_rename.is_some() {
2827            return None;
2828        }
2829
2830        let project = self.project.as_ref()?;
2831        let buffer = self.buffer.read(cx);
2832        let newest_selection = self.selections.newest_anchor().clone();
2833        let cursor_position = newest_selection.head();
2834        let (cursor_buffer, cursor_buffer_position) =
2835            buffer.text_anchor_for_position(cursor_position.clone(), cx)?;
2836        let (tail_buffer, _) = buffer.text_anchor_for_position(newest_selection.tail(), cx)?;
2837        if cursor_buffer != tail_buffer {
2838            return None;
2839        }
2840
2841        let highlights = project.update(cx, |project, cx| {
2842            project.document_highlights(&cursor_buffer, cursor_buffer_position, cx)
2843        });
2844
2845        self.document_highlights_task = Some(cx.spawn_weak(|this, mut cx| async move {
2846            let highlights = highlights.log_err().await;
2847            if let Some((this, highlights)) = this.upgrade(&cx).zip(highlights) {
2848                this.update(&mut cx, |this, cx| {
2849                    if this.pending_rename.is_some() {
2850                        return;
2851                    }
2852
2853                    let buffer_id = cursor_position.buffer_id;
2854                    let buffer = this.buffer.read(cx);
2855                    if !buffer
2856                        .text_anchor_for_position(cursor_position, cx)
2857                        .map_or(false, |(buffer, _)| buffer == cursor_buffer)
2858                    {
2859                        return;
2860                    }
2861
2862                    let cursor_buffer_snapshot = cursor_buffer.read(cx);
2863                    let mut write_ranges = Vec::new();
2864                    let mut read_ranges = Vec::new();
2865                    for highlight in highlights {
2866                        for (excerpt_id, excerpt_range) in
2867                            buffer.excerpts_for_buffer(&cursor_buffer, cx)
2868                        {
2869                            let start = highlight
2870                                .range
2871                                .start
2872                                .max(&excerpt_range.context.start, cursor_buffer_snapshot);
2873                            let end = highlight
2874                                .range
2875                                .end
2876                                .min(&excerpt_range.context.end, cursor_buffer_snapshot);
2877                            if start.cmp(&end, cursor_buffer_snapshot).is_ge() {
2878                                continue;
2879                            }
2880
2881                            let range = Anchor {
2882                                buffer_id,
2883                                excerpt_id: excerpt_id.clone(),
2884                                text_anchor: start,
2885                            }..Anchor {
2886                                buffer_id,
2887                                excerpt_id,
2888                                text_anchor: end,
2889                            };
2890                            if highlight.kind == lsp::DocumentHighlightKind::WRITE {
2891                                write_ranges.push(range);
2892                            } else {
2893                                read_ranges.push(range);
2894                            }
2895                        }
2896                    }
2897
2898                    this.highlight_background::<DocumentHighlightRead>(
2899                        read_ranges,
2900                        |theme| theme.editor.document_highlight_read_background,
2901                        cx,
2902                    );
2903                    this.highlight_background::<DocumentHighlightWrite>(
2904                        write_ranges,
2905                        |theme| theme.editor.document_highlight_write_background,
2906                        cx,
2907                    );
2908                    cx.notify();
2909                });
2910            }
2911        }));
2912        None
2913    }
2914
2915    pub fn render_code_actions_indicator(
2916        &self,
2917        style: &EditorStyle,
2918        cx: &mut RenderContext<Self>,
2919    ) -> Option<ElementBox> {
2920        if self.available_code_actions.is_some() {
2921            enum Tag {}
2922            Some(
2923                MouseEventHandler::<Tag>::new(0, cx, |_, _| {
2924                    Svg::new("icons/bolt_8.svg")
2925                        .with_color(style.code_actions.indicator)
2926                        .boxed()
2927                })
2928                .with_cursor_style(CursorStyle::PointingHand)
2929                .with_padding(Padding::uniform(3.))
2930                .on_down(MouseButton::Left, |_, cx| {
2931                    cx.dispatch_action(ToggleCodeActions {
2932                        deployed_from_indicator: true,
2933                    });
2934                })
2935                .boxed(),
2936            )
2937        } else {
2938            None
2939        }
2940    }
2941
2942    pub fn context_menu_visible(&self) -> bool {
2943        self.context_menu
2944            .as_ref()
2945            .map_or(false, |menu| menu.visible())
2946    }
2947
2948    pub fn render_context_menu(
2949        &self,
2950        cursor_position: DisplayPoint,
2951        style: EditorStyle,
2952        cx: &mut RenderContext<Editor>,
2953    ) -> Option<(DisplayPoint, ElementBox)> {
2954        self.context_menu
2955            .as_ref()
2956            .map(|menu| menu.render(cursor_position, style, cx))
2957    }
2958
2959    fn show_context_menu(&mut self, menu: ContextMenu, cx: &mut ViewContext<Self>) {
2960        if !matches!(menu, ContextMenu::Completions(_)) {
2961            self.completion_tasks.clear();
2962        }
2963        self.context_menu = Some(menu);
2964        cx.notify();
2965    }
2966
2967    fn hide_context_menu(&mut self, cx: &mut ViewContext<Self>) -> Option<ContextMenu> {
2968        cx.notify();
2969        self.completion_tasks.clear();
2970        self.context_menu.take()
2971    }
2972
2973    pub fn insert_snippet(
2974        &mut self,
2975        insertion_ranges: &[Range<usize>],
2976        snippet: Snippet,
2977        cx: &mut ViewContext<Self>,
2978    ) -> Result<()> {
2979        let tabstops = self.buffer.update(cx, |buffer, cx| {
2980            let snippet_text: Arc<str> = snippet.text.clone().into();
2981            buffer.edit(
2982                insertion_ranges
2983                    .iter()
2984                    .cloned()
2985                    .map(|range| (range, snippet_text.clone())),
2986                Some(AutoindentMode::EachLine),
2987                cx,
2988            );
2989
2990            let snapshot = &*buffer.read(cx);
2991            let snippet = &snippet;
2992            snippet
2993                .tabstops
2994                .iter()
2995                .map(|tabstop| {
2996                    let mut tabstop_ranges = tabstop
2997                        .iter()
2998                        .flat_map(|tabstop_range| {
2999                            let mut delta = 0_isize;
3000                            insertion_ranges.iter().map(move |insertion_range| {
3001                                let insertion_start = insertion_range.start as isize + delta;
3002                                delta +=
3003                                    snippet.text.len() as isize - insertion_range.len() as isize;
3004
3005                                let start = snapshot.anchor_before(
3006                                    (insertion_start + tabstop_range.start) as usize,
3007                                );
3008                                let end = snapshot
3009                                    .anchor_after((insertion_start + tabstop_range.end) as usize);
3010                                start..end
3011                            })
3012                        })
3013                        .collect::<Vec<_>>();
3014                    tabstop_ranges.sort_unstable_by(|a, b| a.start.cmp(&b.start, snapshot));
3015                    tabstop_ranges
3016                })
3017                .collect::<Vec<_>>()
3018        });
3019
3020        if let Some(tabstop) = tabstops.first() {
3021            self.change_selections(Some(Autoscroll::Fit), cx, |s| {
3022                s.select_ranges(tabstop.iter().cloned());
3023            });
3024            self.snippet_stack.push(SnippetState {
3025                active_index: 0,
3026                ranges: tabstops,
3027            });
3028        }
3029
3030        Ok(())
3031    }
3032
3033    pub fn move_to_next_snippet_tabstop(&mut self, cx: &mut ViewContext<Self>) -> bool {
3034        self.move_to_snippet_tabstop(Bias::Right, cx)
3035    }
3036
3037    pub fn move_to_prev_snippet_tabstop(&mut self, cx: &mut ViewContext<Self>) -> bool {
3038        self.move_to_snippet_tabstop(Bias::Left, cx)
3039    }
3040
3041    pub fn move_to_snippet_tabstop(&mut self, bias: Bias, cx: &mut ViewContext<Self>) -> bool {
3042        if let Some(mut snippet) = self.snippet_stack.pop() {
3043            match bias {
3044                Bias::Left => {
3045                    if snippet.active_index > 0 {
3046                        snippet.active_index -= 1;
3047                    } else {
3048                        self.snippet_stack.push(snippet);
3049                        return false;
3050                    }
3051                }
3052                Bias::Right => {
3053                    if snippet.active_index + 1 < snippet.ranges.len() {
3054                        snippet.active_index += 1;
3055                    } else {
3056                        self.snippet_stack.push(snippet);
3057                        return false;
3058                    }
3059                }
3060            }
3061            if let Some(current_ranges) = snippet.ranges.get(snippet.active_index) {
3062                self.change_selections(Some(Autoscroll::Fit), cx, |s| {
3063                    s.select_anchor_ranges(current_ranges.iter().cloned())
3064                });
3065                // If snippet state is not at the last tabstop, push it back on the stack
3066                if snippet.active_index + 1 < snippet.ranges.len() {
3067                    self.snippet_stack.push(snippet);
3068                }
3069                return true;
3070            }
3071        }
3072
3073        false
3074    }
3075
3076    pub fn clear(&mut self, cx: &mut ViewContext<Self>) {
3077        self.transact(cx, |this, cx| {
3078            this.select_all(&SelectAll, cx);
3079            this.insert("", cx);
3080        });
3081    }
3082
3083    pub fn backspace(&mut self, _: &Backspace, cx: &mut ViewContext<Self>) {
3084        self.transact(cx, |this, cx| {
3085            this.select_autoclose_pair(cx);
3086            let mut selections = this.selections.all::<Point>(cx);
3087            if !this.selections.line_mode {
3088                let display_map = this.display_map.update(cx, |map, cx| map.snapshot(cx));
3089                for selection in &mut selections {
3090                    if selection.is_empty() {
3091                        let old_head = selection.head();
3092                        let mut new_head =
3093                            movement::left(&display_map, old_head.to_display_point(&display_map))
3094                                .to_point(&display_map);
3095                        if let Some((buffer, line_buffer_range)) = display_map
3096                            .buffer_snapshot
3097                            .buffer_line_for_row(old_head.row)
3098                        {
3099                            let indent_size =
3100                                buffer.indent_size_for_line(line_buffer_range.start.row);
3101                            let language_name = buffer
3102                                .language_at(line_buffer_range.start)
3103                                .map(|language| language.name());
3104                            let indent_len = match indent_size.kind {
3105                                IndentKind::Space => {
3106                                    cx.global::<Settings>().tab_size(language_name.as_deref())
3107                                }
3108                                IndentKind::Tab => NonZeroU32::new(1).unwrap(),
3109                            };
3110                            if old_head.column <= indent_size.len && old_head.column > 0 {
3111                                let indent_len = indent_len.get();
3112                                new_head = cmp::min(
3113                                    new_head,
3114                                    Point::new(
3115                                        old_head.row,
3116                                        ((old_head.column - 1) / indent_len) * indent_len,
3117                                    ),
3118                                );
3119                            }
3120                        }
3121
3122                        selection.set_head(new_head, SelectionGoal::None);
3123                    }
3124                }
3125            }
3126
3127            this.change_selections(Some(Autoscroll::Fit), cx, |s| s.select(selections));
3128            this.insert("", cx);
3129        });
3130    }
3131
3132    pub fn delete(&mut self, _: &Delete, cx: &mut ViewContext<Self>) {
3133        self.transact(cx, |this, cx| {
3134            this.change_selections(Some(Autoscroll::Fit), cx, |s| {
3135                let line_mode = s.line_mode;
3136                s.move_with(|map, selection| {
3137                    if selection.is_empty() && !line_mode {
3138                        let cursor = movement::right(map, selection.head());
3139                        selection.set_head(cursor, SelectionGoal::None);
3140                    }
3141                })
3142            });
3143            this.insert("", cx);
3144        });
3145    }
3146
3147    pub fn tab_prev(&mut self, _: &TabPrev, cx: &mut ViewContext<Self>) {
3148        if self.move_to_prev_snippet_tabstop(cx) {
3149            return;
3150        }
3151
3152        self.outdent(&Outdent, cx);
3153    }
3154
3155    pub fn tab(&mut self, _: &Tab, cx: &mut ViewContext<Self>) {
3156        if self.move_to_next_snippet_tabstop(cx) {
3157            return;
3158        }
3159
3160        let mut selections = self.selections.all_adjusted(cx);
3161        let buffer = self.buffer.read(cx);
3162        let snapshot = buffer.snapshot(cx);
3163        let rows_iter = selections.iter().map(|s| s.head().row);
3164        let suggested_indents = snapshot.suggested_indents(rows_iter, cx);
3165
3166        let mut edits = Vec::new();
3167        let mut prev_edited_row = 0;
3168        let mut row_delta = 0;
3169        for selection in &mut selections {
3170            if selection.start.row != prev_edited_row {
3171                row_delta = 0;
3172            }
3173            prev_edited_row = selection.end.row;
3174
3175            // If the selection is non-empty, then increase the indentation of the selected lines.
3176            if !selection.is_empty() {
3177                row_delta =
3178                    Self::indent_selection(buffer, &snapshot, selection, &mut edits, row_delta, cx);
3179                continue;
3180            }
3181
3182            // If the selection is empty and the cursor is in the leading whitespace before the
3183            // suggested indentation, then auto-indent the line.
3184            let cursor = selection.head();
3185            if let Some(suggested_indent) = suggested_indents.get(&cursor.row).copied() {
3186                let current_indent = snapshot.indent_size_for_line(cursor.row);
3187                if cursor.column < suggested_indent.len
3188                    && cursor.column <= current_indent.len
3189                    && current_indent.len <= suggested_indent.len
3190                {
3191                    selection.start = Point::new(cursor.row, suggested_indent.len);
3192                    selection.end = selection.start;
3193                    if row_delta == 0 {
3194                        edits.extend(Buffer::edit_for_indent_size_adjustment(
3195                            cursor.row,
3196                            current_indent,
3197                            suggested_indent,
3198                        ));
3199                        row_delta = suggested_indent.len - current_indent.len;
3200                    }
3201                    continue;
3202                }
3203            }
3204
3205            // Otherwise, insert a hard or soft tab.
3206            let settings = cx.global::<Settings>();
3207            let language_name = buffer.language_at(cursor, cx).map(|l| l.name());
3208            let tab_size = if settings.hard_tabs(language_name.as_deref()) {
3209                IndentSize::tab()
3210            } else {
3211                let tab_size = settings.tab_size(language_name.as_deref()).get();
3212                let char_column = snapshot
3213                    .text_for_range(Point::new(cursor.row, 0)..cursor)
3214                    .flat_map(str::chars)
3215                    .count()
3216                    + row_delta as usize;
3217                let chars_to_next_tab_stop = tab_size - (char_column as u32 % tab_size);
3218                IndentSize::spaces(chars_to_next_tab_stop)
3219            };
3220            selection.start = Point::new(cursor.row, cursor.column + row_delta + tab_size.len);
3221            selection.end = selection.start;
3222            edits.push((cursor..cursor, tab_size.chars().collect::<String>()));
3223            row_delta += tab_size.len;
3224        }
3225
3226        self.transact(cx, |this, cx| {
3227            this.buffer.update(cx, |b, cx| b.edit(edits, None, cx));
3228            this.change_selections(Some(Autoscroll::Fit), cx, |s| s.select(selections))
3229        });
3230    }
3231
3232    pub fn indent(&mut self, _: &Indent, cx: &mut ViewContext<Self>) {
3233        let mut selections = self.selections.all::<Point>(cx);
3234        let mut prev_edited_row = 0;
3235        let mut row_delta = 0;
3236        let mut edits = Vec::new();
3237        let buffer = self.buffer.read(cx);
3238        let snapshot = buffer.snapshot(cx);
3239        for selection in &mut selections {
3240            if selection.start.row != prev_edited_row {
3241                row_delta = 0;
3242            }
3243            prev_edited_row = selection.end.row;
3244
3245            row_delta =
3246                Self::indent_selection(buffer, &snapshot, selection, &mut edits, row_delta, cx);
3247        }
3248
3249        self.transact(cx, |this, cx| {
3250            this.buffer.update(cx, |b, cx| b.edit(edits, None, cx));
3251            this.change_selections(Some(Autoscroll::Fit), cx, |s| s.select(selections));
3252        });
3253    }
3254
3255    fn indent_selection(
3256        buffer: &MultiBuffer,
3257        snapshot: &MultiBufferSnapshot,
3258        selection: &mut Selection<Point>,
3259        edits: &mut Vec<(Range<Point>, String)>,
3260        delta_for_start_row: u32,
3261        cx: &AppContext,
3262    ) -> u32 {
3263        let language_name = buffer.language_at(selection.start, cx).map(|l| l.name());
3264        let settings = cx.global::<Settings>();
3265        let tab_size = settings.tab_size(language_name.as_deref()).get();
3266        let indent_kind = if settings.hard_tabs(language_name.as_deref()) {
3267            IndentKind::Tab
3268        } else {
3269            IndentKind::Space
3270        };
3271        let mut start_row = selection.start.row;
3272        let mut end_row = selection.end.row + 1;
3273
3274        // If a selection ends at the beginning of a line, don't indent
3275        // that last line.
3276        if selection.end.column == 0 {
3277            end_row -= 1;
3278        }
3279
3280        // Avoid re-indenting a row that has already been indented by a
3281        // previous selection, but still update this selection's column
3282        // to reflect that indentation.
3283        if delta_for_start_row > 0 {
3284            start_row += 1;
3285            selection.start.column += delta_for_start_row;
3286            if selection.end.row == selection.start.row {
3287                selection.end.column += delta_for_start_row;
3288            }
3289        }
3290
3291        let mut delta_for_end_row = 0;
3292        for row in start_row..end_row {
3293            let current_indent = snapshot.indent_size_for_line(row);
3294            let indent_delta = match (current_indent.kind, indent_kind) {
3295                (IndentKind::Space, IndentKind::Space) => {
3296                    let columns_to_next_tab_stop = tab_size - (current_indent.len % tab_size);
3297                    IndentSize::spaces(columns_to_next_tab_stop)
3298                }
3299                (IndentKind::Tab, IndentKind::Space) => IndentSize::spaces(tab_size),
3300                (_, IndentKind::Tab) => IndentSize::tab(),
3301            };
3302
3303            let row_start = Point::new(row, 0);
3304            edits.push((
3305                row_start..row_start,
3306                indent_delta.chars().collect::<String>(),
3307            ));
3308
3309            // Update this selection's endpoints to reflect the indentation.
3310            if row == selection.start.row {
3311                selection.start.column += indent_delta.len;
3312            }
3313            if row == selection.end.row {
3314                selection.end.column += indent_delta.len;
3315                delta_for_end_row = indent_delta.len;
3316            }
3317        }
3318
3319        if selection.start.row == selection.end.row {
3320            delta_for_start_row + delta_for_end_row
3321        } else {
3322            delta_for_end_row
3323        }
3324    }
3325
3326    pub fn outdent(&mut self, _: &Outdent, cx: &mut ViewContext<Self>) {
3327        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
3328        let selections = self.selections.all::<Point>(cx);
3329        let mut deletion_ranges = Vec::new();
3330        let mut last_outdent = None;
3331        {
3332            let buffer = self.buffer.read(cx);
3333            let snapshot = buffer.snapshot(cx);
3334            for selection in &selections {
3335                let language_name = buffer.language_at(selection.start, cx).map(|l| l.name());
3336                let tab_size = cx
3337                    .global::<Settings>()
3338                    .tab_size(language_name.as_deref())
3339                    .get();
3340                let mut rows = selection.spanned_rows(false, &display_map);
3341
3342                // Avoid re-outdenting a row that has already been outdented by a
3343                // previous selection.
3344                if let Some(last_row) = last_outdent {
3345                    if last_row == rows.start {
3346                        rows.start += 1;
3347                    }
3348                }
3349
3350                for row in rows {
3351                    let indent_size = snapshot.indent_size_for_line(row);
3352                    if indent_size.len > 0 {
3353                        let deletion_len = match indent_size.kind {
3354                            IndentKind::Space => {
3355                                let columns_to_prev_tab_stop = indent_size.len % tab_size;
3356                                if columns_to_prev_tab_stop == 0 {
3357                                    tab_size
3358                                } else {
3359                                    columns_to_prev_tab_stop
3360                                }
3361                            }
3362                            IndentKind::Tab => 1,
3363                        };
3364                        deletion_ranges.push(Point::new(row, 0)..Point::new(row, deletion_len));
3365                        last_outdent = Some(row);
3366                    }
3367                }
3368            }
3369        }
3370
3371        self.transact(cx, |this, cx| {
3372            this.buffer.update(cx, |buffer, cx| {
3373                let empty_str: Arc<str> = "".into();
3374                buffer.edit(
3375                    deletion_ranges
3376                        .into_iter()
3377                        .map(|range| (range, empty_str.clone())),
3378                    None,
3379                    cx,
3380                );
3381            });
3382            let selections = this.selections.all::<usize>(cx);
3383            this.change_selections(Some(Autoscroll::Fit), cx, |s| s.select(selections));
3384        });
3385    }
3386
3387    pub fn delete_line(&mut self, _: &DeleteLine, cx: &mut ViewContext<Self>) {
3388        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
3389        let selections = self.selections.all::<Point>(cx);
3390
3391        let mut new_cursors = Vec::new();
3392        let mut edit_ranges = Vec::new();
3393        let mut selections = selections.iter().peekable();
3394        while let Some(selection) = selections.next() {
3395            let mut rows = selection.spanned_rows(false, &display_map);
3396            let goal_display_column = selection.head().to_display_point(&display_map).column();
3397
3398            // Accumulate contiguous regions of rows that we want to delete.
3399            while let Some(next_selection) = selections.peek() {
3400                let next_rows = next_selection.spanned_rows(false, &display_map);
3401                if next_rows.start <= rows.end {
3402                    rows.end = next_rows.end;
3403                    selections.next().unwrap();
3404                } else {
3405                    break;
3406                }
3407            }
3408
3409            let buffer = &display_map.buffer_snapshot;
3410            let mut edit_start = Point::new(rows.start, 0).to_offset(buffer);
3411            let edit_end;
3412            let cursor_buffer_row;
3413            if buffer.max_point().row >= rows.end {
3414                // If there's a line after the range, delete the \n from the end of the row range
3415                // and position the cursor on the next line.
3416                edit_end = Point::new(rows.end, 0).to_offset(buffer);
3417                cursor_buffer_row = rows.end;
3418            } else {
3419                // If there isn't a line after the range, delete the \n from the line before the
3420                // start of the row range and position the cursor there.
3421                edit_start = edit_start.saturating_sub(1);
3422                edit_end = buffer.len();
3423                cursor_buffer_row = rows.start.saturating_sub(1);
3424            }
3425
3426            let mut cursor = Point::new(cursor_buffer_row, 0).to_display_point(&display_map);
3427            *cursor.column_mut() =
3428                cmp::min(goal_display_column, display_map.line_len(cursor.row()));
3429
3430            new_cursors.push((
3431                selection.id,
3432                buffer.anchor_after(cursor.to_point(&display_map)),
3433            ));
3434            edit_ranges.push(edit_start..edit_end);
3435        }
3436
3437        self.transact(cx, |this, cx| {
3438            let buffer = this.buffer.update(cx, |buffer, cx| {
3439                let empty_str: Arc<str> = "".into();
3440                buffer.edit(
3441                    edit_ranges
3442                        .into_iter()
3443                        .map(|range| (range, empty_str.clone())),
3444                    None,
3445                    cx,
3446                );
3447                buffer.snapshot(cx)
3448            });
3449            let new_selections = new_cursors
3450                .into_iter()
3451                .map(|(id, cursor)| {
3452                    let cursor = cursor.to_point(&buffer);
3453                    Selection {
3454                        id,
3455                        start: cursor,
3456                        end: cursor,
3457                        reversed: false,
3458                        goal: SelectionGoal::None,
3459                    }
3460                })
3461                .collect();
3462
3463            this.change_selections(Some(Autoscroll::Fit), cx, |s| {
3464                s.select(new_selections);
3465            });
3466        });
3467    }
3468
3469    pub fn duplicate_line(&mut self, _: &DuplicateLine, cx: &mut ViewContext<Self>) {
3470        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
3471        let buffer = &display_map.buffer_snapshot;
3472        let selections = self.selections.all::<Point>(cx);
3473
3474        let mut edits = Vec::new();
3475        let mut selections_iter = selections.iter().peekable();
3476        while let Some(selection) = selections_iter.next() {
3477            // Avoid duplicating the same lines twice.
3478            let mut rows = selection.spanned_rows(false, &display_map);
3479
3480            while let Some(next_selection) = selections_iter.peek() {
3481                let next_rows = next_selection.spanned_rows(false, &display_map);
3482                if next_rows.start < rows.end {
3483                    rows.end = next_rows.end;
3484                    selections_iter.next().unwrap();
3485                } else {
3486                    break;
3487                }
3488            }
3489
3490            // Copy the text from the selected row region and splice it at the start of the region.
3491            let start = Point::new(rows.start, 0);
3492            let end = Point::new(rows.end - 1, buffer.line_len(rows.end - 1));
3493            let text = buffer
3494                .text_for_range(start..end)
3495                .chain(Some("\n"))
3496                .collect::<String>();
3497            edits.push((start..start, text));
3498        }
3499
3500        self.transact(cx, |this, cx| {
3501            this.buffer.update(cx, |buffer, cx| {
3502                buffer.edit(edits, None, cx);
3503            });
3504
3505            this.request_autoscroll(Autoscroll::Fit, cx);
3506        });
3507    }
3508
3509    pub fn move_line_up(&mut self, _: &MoveLineUp, cx: &mut ViewContext<Self>) {
3510        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
3511        let buffer = self.buffer.read(cx).snapshot(cx);
3512
3513        let mut edits = Vec::new();
3514        let mut unfold_ranges = Vec::new();
3515        let mut refold_ranges = Vec::new();
3516
3517        let selections = self.selections.all::<Point>(cx);
3518        let mut selections = selections.iter().peekable();
3519        let mut contiguous_row_selections = Vec::new();
3520        let mut new_selections = Vec::new();
3521
3522        while let Some(selection) = selections.next() {
3523            // Find all the selections that span a contiguous row range
3524            contiguous_row_selections.push(selection.clone());
3525            let start_row = selection.start.row;
3526            let mut end_row = if selection.end.column > 0 || selection.is_empty() {
3527                display_map.next_line_boundary(selection.end).0.row + 1
3528            } else {
3529                selection.end.row
3530            };
3531
3532            while let Some(next_selection) = selections.peek() {
3533                if next_selection.start.row <= end_row {
3534                    end_row = if next_selection.end.column > 0 || next_selection.is_empty() {
3535                        display_map.next_line_boundary(next_selection.end).0.row + 1
3536                    } else {
3537                        next_selection.end.row
3538                    };
3539                    contiguous_row_selections.push(selections.next().unwrap().clone());
3540                } else {
3541                    break;
3542                }
3543            }
3544
3545            // Move the text spanned by the row range to be before the line preceding the row range
3546            if start_row > 0 {
3547                let range_to_move = Point::new(start_row - 1, buffer.line_len(start_row - 1))
3548                    ..Point::new(end_row - 1, buffer.line_len(end_row - 1));
3549                let insertion_point = display_map
3550                    .prev_line_boundary(Point::new(start_row - 1, 0))
3551                    .0;
3552
3553                // Don't move lines across excerpts
3554                if buffer
3555                    .excerpt_boundaries_in_range((
3556                        Bound::Excluded(insertion_point),
3557                        Bound::Included(range_to_move.end),
3558                    ))
3559                    .next()
3560                    .is_none()
3561                {
3562                    let text = buffer
3563                        .text_for_range(range_to_move.clone())
3564                        .flat_map(|s| s.chars())
3565                        .skip(1)
3566                        .chain(['\n'])
3567                        .collect::<String>();
3568
3569                    edits.push((
3570                        buffer.anchor_after(range_to_move.start)
3571                            ..buffer.anchor_before(range_to_move.end),
3572                        String::new(),
3573                    ));
3574                    let insertion_anchor = buffer.anchor_after(insertion_point);
3575                    edits.push((insertion_anchor.clone()..insertion_anchor, text));
3576
3577                    let row_delta = range_to_move.start.row - insertion_point.row + 1;
3578
3579                    // Move selections up
3580                    new_selections.extend(contiguous_row_selections.drain(..).map(
3581                        |mut selection| {
3582                            selection.start.row -= row_delta;
3583                            selection.end.row -= row_delta;
3584                            selection
3585                        },
3586                    ));
3587
3588                    // Move folds up
3589                    unfold_ranges.push(range_to_move.clone());
3590                    for fold in display_map.folds_in_range(
3591                        buffer.anchor_before(range_to_move.start)
3592                            ..buffer.anchor_after(range_to_move.end),
3593                    ) {
3594                        let mut start = fold.start.to_point(&buffer);
3595                        let mut end = fold.end.to_point(&buffer);
3596                        start.row -= row_delta;
3597                        end.row -= row_delta;
3598                        refold_ranges.push(start..end);
3599                    }
3600                }
3601            }
3602
3603            // If we didn't move line(s), preserve the existing selections
3604            new_selections.append(&mut contiguous_row_selections);
3605        }
3606
3607        self.transact(cx, |this, cx| {
3608            this.unfold_ranges(unfold_ranges, true, cx);
3609            this.buffer.update(cx, |buffer, cx| {
3610                for (range, text) in edits {
3611                    buffer.edit([(range, text)], None, cx);
3612                }
3613            });
3614            this.fold_ranges(refold_ranges, cx);
3615            this.change_selections(Some(Autoscroll::Fit), cx, |s| {
3616                s.select(new_selections);
3617            })
3618        });
3619    }
3620
3621    pub fn move_line_down(&mut self, _: &MoveLineDown, cx: &mut ViewContext<Self>) {
3622        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
3623        let buffer = self.buffer.read(cx).snapshot(cx);
3624
3625        let mut edits = Vec::new();
3626        let mut unfold_ranges = Vec::new();
3627        let mut refold_ranges = Vec::new();
3628
3629        let selections = self.selections.all::<Point>(cx);
3630        let mut selections = selections.iter().peekable();
3631        let mut contiguous_row_selections = Vec::new();
3632        let mut new_selections = Vec::new();
3633
3634        while let Some(selection) = selections.next() {
3635            // Find all the selections that span a contiguous row range
3636            contiguous_row_selections.push(selection.clone());
3637            let start_row = selection.start.row;
3638            let mut end_row = if selection.end.column > 0 || selection.is_empty() {
3639                display_map.next_line_boundary(selection.end).0.row + 1
3640            } else {
3641                selection.end.row
3642            };
3643
3644            while let Some(next_selection) = selections.peek() {
3645                if next_selection.start.row <= end_row {
3646                    end_row = if next_selection.end.column > 0 || next_selection.is_empty() {
3647                        display_map.next_line_boundary(next_selection.end).0.row + 1
3648                    } else {
3649                        next_selection.end.row
3650                    };
3651                    contiguous_row_selections.push(selections.next().unwrap().clone());
3652                } else {
3653                    break;
3654                }
3655            }
3656
3657            // Move the text spanned by the row range to be after the last line of the row range
3658            if end_row <= buffer.max_point().row {
3659                let range_to_move = Point::new(start_row, 0)..Point::new(end_row, 0);
3660                let insertion_point = display_map.next_line_boundary(Point::new(end_row, 0)).0;
3661
3662                // Don't move lines across excerpt boundaries
3663                if buffer
3664                    .excerpt_boundaries_in_range((
3665                        Bound::Excluded(range_to_move.start),
3666                        Bound::Included(insertion_point),
3667                    ))
3668                    .next()
3669                    .is_none()
3670                {
3671                    let mut text = String::from("\n");
3672                    text.extend(buffer.text_for_range(range_to_move.clone()));
3673                    text.pop(); // Drop trailing newline
3674                    edits.push((
3675                        buffer.anchor_after(range_to_move.start)
3676                            ..buffer.anchor_before(range_to_move.end),
3677                        String::new(),
3678                    ));
3679                    let insertion_anchor = buffer.anchor_after(insertion_point);
3680                    edits.push((insertion_anchor.clone()..insertion_anchor, text));
3681
3682                    let row_delta = insertion_point.row - range_to_move.end.row + 1;
3683
3684                    // Move selections down
3685                    new_selections.extend(contiguous_row_selections.drain(..).map(
3686                        |mut selection| {
3687                            selection.start.row += row_delta;
3688                            selection.end.row += row_delta;
3689                            selection
3690                        },
3691                    ));
3692
3693                    // Move folds down
3694                    unfold_ranges.push(range_to_move.clone());
3695                    for fold in display_map.folds_in_range(
3696                        buffer.anchor_before(range_to_move.start)
3697                            ..buffer.anchor_after(range_to_move.end),
3698                    ) {
3699                        let mut start = fold.start.to_point(&buffer);
3700                        let mut end = fold.end.to_point(&buffer);
3701                        start.row += row_delta;
3702                        end.row += row_delta;
3703                        refold_ranges.push(start..end);
3704                    }
3705                }
3706            }
3707
3708            // If we didn't move line(s), preserve the existing selections
3709            new_selections.append(&mut contiguous_row_selections);
3710        }
3711
3712        self.transact(cx, |this, cx| {
3713            this.unfold_ranges(unfold_ranges, true, cx);
3714            this.buffer.update(cx, |buffer, cx| {
3715                for (range, text) in edits {
3716                    buffer.edit([(range, text)], None, cx);
3717                }
3718            });
3719            this.fold_ranges(refold_ranges, cx);
3720            this.change_selections(Some(Autoscroll::Fit), cx, |s| s.select(new_selections));
3721        });
3722    }
3723
3724    pub fn transpose(&mut self, _: &Transpose, cx: &mut ViewContext<Self>) {
3725        self.transact(cx, |this, cx| {
3726            let edits = this.change_selections(Some(Autoscroll::Fit), cx, |s| {
3727                let mut edits: Vec<(Range<usize>, String)> = Default::default();
3728                let line_mode = s.line_mode;
3729                s.move_with(|display_map, selection| {
3730                    if !selection.is_empty() || line_mode {
3731                        return;
3732                    }
3733
3734                    let mut head = selection.head();
3735                    let mut transpose_offset = head.to_offset(display_map, Bias::Right);
3736                    if head.column() == display_map.line_len(head.row()) {
3737                        transpose_offset = display_map
3738                            .buffer_snapshot
3739                            .clip_offset(transpose_offset.saturating_sub(1), Bias::Left);
3740                    }
3741
3742                    if transpose_offset == 0 {
3743                        return;
3744                    }
3745
3746                    *head.column_mut() += 1;
3747                    head = display_map.clip_point(head, Bias::Right);
3748                    selection.collapse_to(head, SelectionGoal::Column(head.column()));
3749
3750                    let transpose_start = display_map
3751                        .buffer_snapshot
3752                        .clip_offset(transpose_offset.saturating_sub(1), Bias::Left);
3753                    if edits.last().map_or(true, |e| e.0.end <= transpose_start) {
3754                        let transpose_end = display_map
3755                            .buffer_snapshot
3756                            .clip_offset(transpose_offset + 1, Bias::Right);
3757                        if let Some(ch) =
3758                            display_map.buffer_snapshot.chars_at(transpose_start).next()
3759                        {
3760                            edits.push((transpose_start..transpose_offset, String::new()));
3761                            edits.push((transpose_end..transpose_end, ch.to_string()));
3762                        }
3763                    }
3764                });
3765                edits
3766            });
3767            this.buffer
3768                .update(cx, |buffer, cx| buffer.edit(edits, None, cx));
3769            let selections = this.selections.all::<usize>(cx);
3770            this.change_selections(Some(Autoscroll::Fit), cx, |s| {
3771                s.select(selections);
3772            });
3773        });
3774    }
3775
3776    pub fn cut(&mut self, _: &Cut, cx: &mut ViewContext<Self>) {
3777        let mut text = String::new();
3778        let buffer = self.buffer.read(cx).snapshot(cx);
3779        let mut selections = self.selections.all::<Point>(cx);
3780        let mut clipboard_selections = Vec::with_capacity(selections.len());
3781        {
3782            let max_point = buffer.max_point();
3783            for selection in &mut selections {
3784                let is_entire_line = selection.is_empty() || self.selections.line_mode;
3785                if is_entire_line {
3786                    selection.start = Point::new(selection.start.row, 0);
3787                    selection.end = cmp::min(max_point, Point::new(selection.end.row + 1, 0));
3788                    selection.goal = SelectionGoal::None;
3789                }
3790                let mut len = 0;
3791                for chunk in buffer.text_for_range(selection.start..selection.end) {
3792                    text.push_str(chunk);
3793                    len += chunk.len();
3794                }
3795                clipboard_selections.push(ClipboardSelection {
3796                    len,
3797                    is_entire_line,
3798                    first_line_indent: buffer.indent_size_for_line(selection.start.row).len,
3799                });
3800            }
3801        }
3802
3803        self.transact(cx, |this, cx| {
3804            this.change_selections(Some(Autoscroll::Fit), cx, |s| {
3805                s.select(selections);
3806            });
3807            this.insert("", cx);
3808            cx.write_to_clipboard(ClipboardItem::new(text).with_metadata(clipboard_selections));
3809        });
3810    }
3811
3812    pub fn copy(&mut self, _: &Copy, cx: &mut ViewContext<Self>) {
3813        let selections = self.selections.all::<Point>(cx);
3814        let buffer = self.buffer.read(cx).read(cx);
3815        let mut text = String::new();
3816
3817        let mut clipboard_selections = Vec::with_capacity(selections.len());
3818        {
3819            let max_point = buffer.max_point();
3820            for selection in selections.iter() {
3821                let mut start = selection.start;
3822                let mut end = selection.end;
3823                let is_entire_line = selection.is_empty() || self.selections.line_mode;
3824                if is_entire_line {
3825                    start = Point::new(start.row, 0);
3826                    end = cmp::min(max_point, Point::new(end.row + 1, 0));
3827                }
3828                let mut len = 0;
3829                for chunk in buffer.text_for_range(start..end) {
3830                    text.push_str(chunk);
3831                    len += chunk.len();
3832                }
3833                clipboard_selections.push(ClipboardSelection {
3834                    len,
3835                    is_entire_line,
3836                    first_line_indent: buffer.indent_size_for_line(start.row).len,
3837                });
3838            }
3839        }
3840
3841        cx.write_to_clipboard(ClipboardItem::new(text).with_metadata(clipboard_selections));
3842    }
3843
3844    pub fn paste(&mut self, _: &Paste, cx: &mut ViewContext<Self>) {
3845        self.transact(cx, |this, cx| {
3846            if let Some(item) = cx.as_mut().read_from_clipboard() {
3847                let mut clipboard_text = Cow::Borrowed(item.text());
3848                if let Some(mut clipboard_selections) = item.metadata::<Vec<ClipboardSelection>>() {
3849                    let old_selections = this.selections.all::<usize>(cx);
3850                    let all_selections_were_entire_line =
3851                        clipboard_selections.iter().all(|s| s.is_entire_line);
3852                    let first_selection_indent_column =
3853                        clipboard_selections.first().map(|s| s.first_line_indent);
3854                    if clipboard_selections.len() != old_selections.len() {
3855                        let mut newline_separated_text = String::new();
3856                        let mut clipboard_selections = clipboard_selections.drain(..).peekable();
3857                        let mut ix = 0;
3858                        while let Some(clipboard_selection) = clipboard_selections.next() {
3859                            newline_separated_text
3860                                .push_str(&clipboard_text[ix..ix + clipboard_selection.len]);
3861                            ix += clipboard_selection.len;
3862                            if clipboard_selections.peek().is_some() {
3863                                newline_separated_text.push('\n');
3864                            }
3865                        }
3866                        clipboard_text = Cow::Owned(newline_separated_text);
3867                    }
3868
3869                    this.buffer.update(cx, |buffer, cx| {
3870                        let snapshot = buffer.read(cx);
3871                        let mut start_offset = 0;
3872                        let mut edits = Vec::new();
3873                        let mut original_indent_columns = Vec::new();
3874                        let line_mode = this.selections.line_mode;
3875                        for (ix, selection) in old_selections.iter().enumerate() {
3876                            let to_insert;
3877                            let entire_line;
3878                            let original_indent_column;
3879                            if let Some(clipboard_selection) = clipboard_selections.get(ix) {
3880                                let end_offset = start_offset + clipboard_selection.len;
3881                                to_insert = &clipboard_text[start_offset..end_offset];
3882                                entire_line = clipboard_selection.is_entire_line;
3883                                start_offset = end_offset;
3884                                original_indent_column =
3885                                    Some(clipboard_selection.first_line_indent);
3886                            } else {
3887                                to_insert = clipboard_text.as_str();
3888                                entire_line = all_selections_were_entire_line;
3889                                original_indent_column = first_selection_indent_column
3890                            }
3891
3892                            // If the corresponding selection was empty when this slice of the
3893                            // clipboard text was written, then the entire line containing the
3894                            // selection was copied. If this selection is also currently empty,
3895                            // then paste the line before the current line of the buffer.
3896                            let range = if selection.is_empty() && !line_mode && entire_line {
3897                                let column = selection.start.to_point(&snapshot).column as usize;
3898                                let line_start = selection.start - column;
3899                                line_start..line_start
3900                            } else {
3901                                selection.range()
3902                            };
3903
3904                            edits.push((range, to_insert));
3905                            original_indent_columns.extend(original_indent_column);
3906                        }
3907                        drop(snapshot);
3908
3909                        buffer.edit(
3910                            edits,
3911                            Some(AutoindentMode::Block {
3912                                original_indent_columns,
3913                            }),
3914                            cx,
3915                        );
3916                    });
3917
3918                    let selections = this.selections.all::<usize>(cx);
3919                    this.change_selections(Some(Autoscroll::Fit), cx, |s| s.select(selections));
3920                } else {
3921                    this.insert(&clipboard_text, cx);
3922                }
3923            }
3924        });
3925    }
3926
3927    pub fn undo(&mut self, _: &Undo, cx: &mut ViewContext<Self>) {
3928        if let Some(tx_id) = self.buffer.update(cx, |buffer, cx| buffer.undo(cx)) {
3929            if let Some((selections, _)) = self.selection_history.transaction(tx_id).cloned() {
3930                self.change_selections(None, cx, |s| {
3931                    s.select_anchors(selections.to_vec());
3932                });
3933            }
3934            self.request_autoscroll(Autoscroll::Fit, cx);
3935            self.unmark_text(cx);
3936            cx.emit(Event::Edited);
3937        }
3938    }
3939
3940    pub fn redo(&mut self, _: &Redo, cx: &mut ViewContext<Self>) {
3941        if let Some(tx_id) = self.buffer.update(cx, |buffer, cx| buffer.redo(cx)) {
3942            if let Some((_, Some(selections))) = self.selection_history.transaction(tx_id).cloned()
3943            {
3944                self.change_selections(None, cx, |s| {
3945                    s.select_anchors(selections.to_vec());
3946                });
3947            }
3948            self.request_autoscroll(Autoscroll::Fit, cx);
3949            self.unmark_text(cx);
3950            cx.emit(Event::Edited);
3951        }
3952    }
3953
3954    pub fn finalize_last_transaction(&mut self, cx: &mut ViewContext<Self>) {
3955        self.buffer
3956            .update(cx, |buffer, cx| buffer.finalize_last_transaction(cx));
3957    }
3958
3959    pub fn move_left(&mut self, _: &MoveLeft, cx: &mut ViewContext<Self>) {
3960        self.change_selections(Some(Autoscroll::Fit), cx, |s| {
3961            let line_mode = s.line_mode;
3962            s.move_with(|map, selection| {
3963                let cursor = if selection.is_empty() && !line_mode {
3964                    movement::left(map, selection.start)
3965                } else {
3966                    selection.start
3967                };
3968                selection.collapse_to(cursor, SelectionGoal::None);
3969            });
3970        })
3971    }
3972
3973    pub fn select_left(&mut self, _: &SelectLeft, cx: &mut ViewContext<Self>) {
3974        self.change_selections(Some(Autoscroll::Fit), cx, |s| {
3975            s.move_heads_with(|map, head, _| (movement::left(map, head), SelectionGoal::None));
3976        })
3977    }
3978
3979    pub fn move_right(&mut self, _: &MoveRight, cx: &mut ViewContext<Self>) {
3980        self.change_selections(Some(Autoscroll::Fit), cx, |s| {
3981            let line_mode = s.line_mode;
3982            s.move_with(|map, selection| {
3983                let cursor = if selection.is_empty() && !line_mode {
3984                    movement::right(map, selection.end)
3985                } else {
3986                    selection.end
3987                };
3988                selection.collapse_to(cursor, SelectionGoal::None)
3989            });
3990        })
3991    }
3992
3993    pub fn select_right(&mut self, _: &SelectRight, cx: &mut ViewContext<Self>) {
3994        self.change_selections(Some(Autoscroll::Fit), cx, |s| {
3995            s.move_heads_with(|map, head, _| (movement::right(map, head), SelectionGoal::None));
3996        })
3997    }
3998
3999    pub fn center_screen(&mut self, _: &CenterScreen, cx: &mut ViewContext<Self>) {
4000        if self.take_rename(true, cx).is_some() {
4001            return;
4002        }
4003
4004        if let Some(_) = self.context_menu.as_mut() {
4005            return;
4006        }
4007
4008        if matches!(self.mode, EditorMode::SingleLine) {
4009            cx.propagate_action();
4010            return;
4011        }
4012
4013        self.request_autoscroll(Autoscroll::Center, cx);
4014    }
4015
4016    pub fn move_up(&mut self, _: &MoveUp, cx: &mut ViewContext<Self>) {
4017        if self.take_rename(true, cx).is_some() {
4018            return;
4019        }
4020
4021        if let Some(context_menu) = self.context_menu.as_mut() {
4022            if context_menu.select_prev(cx) {
4023                return;
4024            }
4025        }
4026
4027        if matches!(self.mode, EditorMode::SingleLine) {
4028            cx.propagate_action();
4029            return;
4030        }
4031
4032        self.change_selections(Some(Autoscroll::Fit), cx, |s| {
4033            let line_mode = s.line_mode;
4034            s.move_with(|map, selection| {
4035                if !selection.is_empty() && !line_mode {
4036                    selection.goal = SelectionGoal::None;
4037                }
4038                let (cursor, goal) = movement::up(map, selection.start, selection.goal, false);
4039                selection.collapse_to(cursor, goal);
4040            });
4041        })
4042    }
4043
4044    pub fn move_page_up(&mut self, action: &MovePageUp, cx: &mut ViewContext<Self>) {
4045        if self.take_rename(true, cx).is_some() {
4046            return;
4047        }
4048
4049        if let Some(context_menu) = self.context_menu.as_mut() {
4050            if context_menu.select_first(cx) {
4051                return;
4052            }
4053        }
4054
4055        if matches!(self.mode, EditorMode::SingleLine) {
4056            cx.propagate_action();
4057            return;
4058        }
4059
4060        let row_count = match self.visible_line_count {
4061            Some(row_count) => row_count as u32 - 1,
4062            None => return,
4063        };
4064
4065        let autoscroll = if action.center_cursor {
4066            Autoscroll::Center
4067        } else {
4068            Autoscroll::Fit
4069        };
4070
4071        self.change_selections(Some(autoscroll), cx, |s| {
4072            let line_mode = s.line_mode;
4073            s.move_with(|map, selection| {
4074                if !selection.is_empty() && !line_mode {
4075                    selection.goal = SelectionGoal::None;
4076                }
4077                let (cursor, goal) =
4078                    movement::up_by_rows(map, selection.end, row_count, selection.goal, false);
4079                selection.collapse_to(cursor, goal);
4080            });
4081        });
4082    }
4083
4084    pub fn page_up(&mut self, _: &PageUp, cx: &mut ViewContext<Self>) {
4085        if self.take_rename(true, cx).is_some() {
4086            return;
4087        }
4088
4089        if let Some(context_menu) = self.context_menu.as_mut() {
4090            if context_menu.select_first(cx) {
4091                return;
4092            }
4093        }
4094
4095        if matches!(self.mode, EditorMode::SingleLine) {
4096            cx.propagate_action();
4097            return;
4098        }
4099
4100        let lines = match self.visible_line_count {
4101            Some(lines) => lines,
4102            None => return,
4103        };
4104
4105        let cur_position = self.scroll_position(cx);
4106        let new_pos = cur_position - vec2f(0., lines + 1.);
4107        self.set_scroll_position(new_pos, cx);
4108    }
4109
4110    pub fn select_up(&mut self, _: &SelectUp, cx: &mut ViewContext<Self>) {
4111        self.change_selections(Some(Autoscroll::Fit), cx, |s| {
4112            s.move_heads_with(|map, head, goal| movement::up(map, head, goal, false))
4113        })
4114    }
4115
4116    pub fn move_down(&mut self, _: &MoveDown, cx: &mut ViewContext<Self>) {
4117        self.take_rename(true, cx);
4118
4119        if let Some(context_menu) = self.context_menu.as_mut() {
4120            if context_menu.select_next(cx) {
4121                return;
4122            }
4123        }
4124
4125        if matches!(self.mode, EditorMode::SingleLine) {
4126            cx.propagate_action();
4127            return;
4128        }
4129
4130        self.change_selections(Some(Autoscroll::Fit), cx, |s| {
4131            let line_mode = s.line_mode;
4132            s.move_with(|map, selection| {
4133                if !selection.is_empty() && !line_mode {
4134                    selection.goal = SelectionGoal::None;
4135                }
4136                let (cursor, goal) = movement::down(map, selection.end, selection.goal, false);
4137                selection.collapse_to(cursor, goal);
4138            });
4139        });
4140    }
4141
4142    pub fn move_page_down(&mut self, action: &MovePageDown, cx: &mut ViewContext<Self>) {
4143        if self.take_rename(true, cx).is_some() {
4144            return;
4145        }
4146
4147        if let Some(context_menu) = self.context_menu.as_mut() {
4148            if context_menu.select_last(cx) {
4149                return;
4150            }
4151        }
4152
4153        if matches!(self.mode, EditorMode::SingleLine) {
4154            cx.propagate_action();
4155            return;
4156        }
4157
4158        let row_count = match self.visible_line_count {
4159            Some(row_count) => row_count as u32 - 1,
4160            None => return,
4161        };
4162
4163        let autoscroll = if action.center_cursor {
4164            Autoscroll::Center
4165        } else {
4166            Autoscroll::Fit
4167        };
4168
4169        self.change_selections(Some(autoscroll), cx, |s| {
4170            let line_mode = s.line_mode;
4171            s.move_with(|map, selection| {
4172                if !selection.is_empty() && !line_mode {
4173                    selection.goal = SelectionGoal::None;
4174                }
4175                let (cursor, goal) =
4176                    movement::down_by_rows(map, selection.end, row_count, selection.goal, false);
4177                selection.collapse_to(cursor, goal);
4178            });
4179        });
4180    }
4181
4182    pub fn page_down(&mut self, _: &PageDown, cx: &mut ViewContext<Self>) {
4183        if self.take_rename(true, cx).is_some() {
4184            return;
4185        }
4186
4187        if let Some(context_menu) = self.context_menu.as_mut() {
4188            if context_menu.select_last(cx) {
4189                return;
4190            }
4191        }
4192
4193        if matches!(self.mode, EditorMode::SingleLine) {
4194            cx.propagate_action();
4195            return;
4196        }
4197
4198        let lines = match self.visible_line_count {
4199            Some(lines) => lines,
4200            None => return,
4201        };
4202
4203        let cur_position = self.scroll_position(cx);
4204        let new_pos = cur_position + vec2f(0., lines - 1.);
4205        self.set_scroll_position(new_pos, cx);
4206    }
4207
4208    pub fn select_down(&mut self, _: &SelectDown, cx: &mut ViewContext<Self>) {
4209        self.change_selections(Some(Autoscroll::Fit), cx, |s| {
4210            s.move_heads_with(|map, head, goal| movement::down(map, head, goal, false))
4211        });
4212    }
4213
4214    pub fn move_to_previous_word_start(
4215        &mut self,
4216        _: &MoveToPreviousWordStart,
4217        cx: &mut ViewContext<Self>,
4218    ) {
4219        self.change_selections(Some(Autoscroll::Fit), cx, |s| {
4220            s.move_cursors_with(|map, head, _| {
4221                (
4222                    movement::previous_word_start(map, head),
4223                    SelectionGoal::None,
4224                )
4225            });
4226        })
4227    }
4228
4229    pub fn move_to_previous_subword_start(
4230        &mut self,
4231        _: &MoveToPreviousSubwordStart,
4232        cx: &mut ViewContext<Self>,
4233    ) {
4234        self.change_selections(Some(Autoscroll::Fit), cx, |s| {
4235            s.move_cursors_with(|map, head, _| {
4236                (
4237                    movement::previous_subword_start(map, head),
4238                    SelectionGoal::None,
4239                )
4240            });
4241        })
4242    }
4243
4244    pub fn select_to_previous_word_start(
4245        &mut self,
4246        _: &SelectToPreviousWordStart,
4247        cx: &mut ViewContext<Self>,
4248    ) {
4249        self.change_selections(Some(Autoscroll::Fit), cx, |s| {
4250            s.move_heads_with(|map, head, _| {
4251                (
4252                    movement::previous_word_start(map, head),
4253                    SelectionGoal::None,
4254                )
4255            });
4256        })
4257    }
4258
4259    pub fn select_to_previous_subword_start(
4260        &mut self,
4261        _: &SelectToPreviousSubwordStart,
4262        cx: &mut ViewContext<Self>,
4263    ) {
4264        self.change_selections(Some(Autoscroll::Fit), cx, |s| {
4265            s.move_heads_with(|map, head, _| {
4266                (
4267                    movement::previous_subword_start(map, head),
4268                    SelectionGoal::None,
4269                )
4270            });
4271        })
4272    }
4273
4274    pub fn delete_to_previous_word_start(
4275        &mut self,
4276        _: &DeleteToPreviousWordStart,
4277        cx: &mut ViewContext<Self>,
4278    ) {
4279        self.transact(cx, |this, cx| {
4280            this.select_autoclose_pair(cx);
4281            this.change_selections(Some(Autoscroll::Fit), cx, |s| {
4282                let line_mode = s.line_mode;
4283                s.move_with(|map, selection| {
4284                    if selection.is_empty() && !line_mode {
4285                        let cursor = movement::previous_word_start(map, selection.head());
4286                        selection.set_head(cursor, SelectionGoal::None);
4287                    }
4288                });
4289            });
4290            this.insert("", cx);
4291        });
4292    }
4293
4294    pub fn delete_to_previous_subword_start(
4295        &mut self,
4296        _: &DeleteToPreviousSubwordStart,
4297        cx: &mut ViewContext<Self>,
4298    ) {
4299        self.transact(cx, |this, cx| {
4300            this.select_autoclose_pair(cx);
4301            this.change_selections(Some(Autoscroll::Fit), cx, |s| {
4302                let line_mode = s.line_mode;
4303                s.move_with(|map, selection| {
4304                    if selection.is_empty() && !line_mode {
4305                        let cursor = movement::previous_subword_start(map, selection.head());
4306                        selection.set_head(cursor, SelectionGoal::None);
4307                    }
4308                });
4309            });
4310            this.insert("", cx);
4311        });
4312    }
4313
4314    pub fn move_to_next_word_end(&mut self, _: &MoveToNextWordEnd, cx: &mut ViewContext<Self>) {
4315        self.change_selections(Some(Autoscroll::Fit), cx, |s| {
4316            s.move_cursors_with(|map, head, _| {
4317                (movement::next_word_end(map, head), SelectionGoal::None)
4318            });
4319        })
4320    }
4321
4322    pub fn move_to_next_subword_end(
4323        &mut self,
4324        _: &MoveToNextSubwordEnd,
4325        cx: &mut ViewContext<Self>,
4326    ) {
4327        self.change_selections(Some(Autoscroll::Fit), cx, |s| {
4328            s.move_cursors_with(|map, head, _| {
4329                (movement::next_subword_end(map, head), SelectionGoal::None)
4330            });
4331        })
4332    }
4333
4334    pub fn select_to_next_word_end(&mut self, _: &SelectToNextWordEnd, cx: &mut ViewContext<Self>) {
4335        self.change_selections(Some(Autoscroll::Fit), cx, |s| {
4336            s.move_heads_with(|map, head, _| {
4337                (movement::next_word_end(map, head), SelectionGoal::None)
4338            });
4339        })
4340    }
4341
4342    pub fn select_to_next_subword_end(
4343        &mut self,
4344        _: &SelectToNextSubwordEnd,
4345        cx: &mut ViewContext<Self>,
4346    ) {
4347        self.change_selections(Some(Autoscroll::Fit), cx, |s| {
4348            s.move_heads_with(|map, head, _| {
4349                (movement::next_subword_end(map, head), SelectionGoal::None)
4350            });
4351        })
4352    }
4353
4354    pub fn delete_to_next_word_end(&mut self, _: &DeleteToNextWordEnd, cx: &mut ViewContext<Self>) {
4355        self.transact(cx, |this, cx| {
4356            this.change_selections(Some(Autoscroll::Fit), cx, |s| {
4357                let line_mode = s.line_mode;
4358                s.move_with(|map, selection| {
4359                    if selection.is_empty() && !line_mode {
4360                        let cursor = movement::next_word_end(map, selection.head());
4361                        selection.set_head(cursor, SelectionGoal::None);
4362                    }
4363                });
4364            });
4365            this.insert("", cx);
4366        });
4367    }
4368
4369    pub fn delete_to_next_subword_end(
4370        &mut self,
4371        _: &DeleteToNextSubwordEnd,
4372        cx: &mut ViewContext<Self>,
4373    ) {
4374        self.transact(cx, |this, cx| {
4375            this.change_selections(Some(Autoscroll::Fit), cx, |s| {
4376                s.move_with(|map, selection| {
4377                    if selection.is_empty() {
4378                        let cursor = movement::next_subword_end(map, selection.head());
4379                        selection.set_head(cursor, SelectionGoal::None);
4380                    }
4381                });
4382            });
4383            this.insert("", cx);
4384        });
4385    }
4386
4387    pub fn move_to_beginning_of_line(
4388        &mut self,
4389        _: &MoveToBeginningOfLine,
4390        cx: &mut ViewContext<Self>,
4391    ) {
4392        self.change_selections(Some(Autoscroll::Fit), cx, |s| {
4393            s.move_cursors_with(|map, head, _| {
4394                (
4395                    movement::indented_line_beginning(map, head, true),
4396                    SelectionGoal::None,
4397                )
4398            });
4399        })
4400    }
4401
4402    pub fn select_to_beginning_of_line(
4403        &mut self,
4404        action: &SelectToBeginningOfLine,
4405        cx: &mut ViewContext<Self>,
4406    ) {
4407        self.change_selections(Some(Autoscroll::Fit), cx, |s| {
4408            s.move_heads_with(|map, head, _| {
4409                (
4410                    movement::indented_line_beginning(map, head, action.stop_at_soft_wraps),
4411                    SelectionGoal::None,
4412                )
4413            });
4414        });
4415    }
4416
4417    pub fn delete_to_beginning_of_line(
4418        &mut self,
4419        _: &DeleteToBeginningOfLine,
4420        cx: &mut ViewContext<Self>,
4421    ) {
4422        self.transact(cx, |this, cx| {
4423            this.change_selections(Some(Autoscroll::Fit), cx, |s| {
4424                s.move_with(|_, selection| {
4425                    selection.reversed = true;
4426                });
4427            });
4428
4429            this.select_to_beginning_of_line(
4430                &SelectToBeginningOfLine {
4431                    stop_at_soft_wraps: false,
4432                },
4433                cx,
4434            );
4435            this.backspace(&Backspace, cx);
4436        });
4437    }
4438
4439    pub fn move_to_end_of_line(&mut self, _: &MoveToEndOfLine, cx: &mut ViewContext<Self>) {
4440        self.change_selections(Some(Autoscroll::Fit), cx, |s| {
4441            s.move_cursors_with(|map, head, _| {
4442                (movement::line_end(map, head, true), SelectionGoal::None)
4443            });
4444        })
4445    }
4446
4447    pub fn select_to_end_of_line(
4448        &mut self,
4449        action: &SelectToEndOfLine,
4450        cx: &mut ViewContext<Self>,
4451    ) {
4452        self.change_selections(Some(Autoscroll::Fit), cx, |s| {
4453            s.move_heads_with(|map, head, _| {
4454                (
4455                    movement::line_end(map, head, action.stop_at_soft_wraps),
4456                    SelectionGoal::None,
4457                )
4458            });
4459        })
4460    }
4461
4462    pub fn delete_to_end_of_line(&mut self, _: &DeleteToEndOfLine, cx: &mut ViewContext<Self>) {
4463        self.transact(cx, |this, cx| {
4464            this.select_to_end_of_line(
4465                &SelectToEndOfLine {
4466                    stop_at_soft_wraps: false,
4467                },
4468                cx,
4469            );
4470            this.delete(&Delete, cx);
4471        });
4472    }
4473
4474    pub fn cut_to_end_of_line(&mut self, _: &CutToEndOfLine, cx: &mut ViewContext<Self>) {
4475        self.transact(cx, |this, cx| {
4476            this.select_to_end_of_line(
4477                &SelectToEndOfLine {
4478                    stop_at_soft_wraps: false,
4479                },
4480                cx,
4481            );
4482            this.cut(&Cut, cx);
4483        });
4484    }
4485
4486    pub fn move_to_beginning(&mut self, _: &MoveToBeginning, cx: &mut ViewContext<Self>) {
4487        if matches!(self.mode, EditorMode::SingleLine) {
4488            cx.propagate_action();
4489            return;
4490        }
4491
4492        self.change_selections(Some(Autoscroll::Fit), cx, |s| {
4493            s.select_ranges(vec![0..0]);
4494        });
4495    }
4496
4497    pub fn select_to_beginning(&mut self, _: &SelectToBeginning, cx: &mut ViewContext<Self>) {
4498        let mut selection = self.selections.last::<Point>(cx);
4499        selection.set_head(Point::zero(), SelectionGoal::None);
4500
4501        self.change_selections(Some(Autoscroll::Fit), cx, |s| {
4502            s.select(vec![selection]);
4503        });
4504    }
4505
4506    pub fn move_to_end(&mut self, _: &MoveToEnd, cx: &mut ViewContext<Self>) {
4507        if matches!(self.mode, EditorMode::SingleLine) {
4508            cx.propagate_action();
4509            return;
4510        }
4511
4512        let cursor = self.buffer.read(cx).read(cx).len();
4513        self.change_selections(Some(Autoscroll::Fit), cx, |s| {
4514            s.select_ranges(vec![cursor..cursor])
4515        });
4516    }
4517
4518    pub fn set_nav_history(&mut self, nav_history: Option<ItemNavHistory>) {
4519        self.nav_history = nav_history;
4520    }
4521
4522    pub fn nav_history(&self) -> Option<&ItemNavHistory> {
4523        self.nav_history.as_ref()
4524    }
4525
4526    fn push_to_nav_history(
4527        &self,
4528        position: Anchor,
4529        new_position: Option<Point>,
4530        cx: &mut ViewContext<Self>,
4531    ) {
4532        if let Some(nav_history) = &self.nav_history {
4533            let buffer = self.buffer.read(cx).read(cx);
4534            let point = position.to_point(&buffer);
4535            let scroll_top_row = self.scroll_top_anchor.to_point(&buffer).row;
4536            drop(buffer);
4537
4538            if let Some(new_position) = new_position {
4539                let row_delta = (new_position.row as i64 - point.row as i64).abs();
4540                if row_delta < MIN_NAVIGATION_HISTORY_ROW_DELTA {
4541                    return;
4542                }
4543            }
4544
4545            nav_history.push(
4546                Some(NavigationData {
4547                    cursor_anchor: position,
4548                    cursor_position: point,
4549                    scroll_position: self.scroll_position,
4550                    scroll_top_anchor: self.scroll_top_anchor.clone(),
4551                    scroll_top_row,
4552                }),
4553                cx,
4554            );
4555        }
4556    }
4557
4558    pub fn select_to_end(&mut self, _: &SelectToEnd, cx: &mut ViewContext<Self>) {
4559        let buffer = self.buffer.read(cx).snapshot(cx);
4560        let mut selection = self.selections.first::<usize>(cx);
4561        selection.set_head(buffer.len(), SelectionGoal::None);
4562        self.change_selections(Some(Autoscroll::Fit), cx, |s| {
4563            s.select(vec![selection]);
4564        });
4565    }
4566
4567    pub fn select_all(&mut self, _: &SelectAll, cx: &mut ViewContext<Self>) {
4568        let end = self.buffer.read(cx).read(cx).len();
4569        self.change_selections(Some(Autoscroll::Fit), cx, |s| {
4570            s.select_ranges(vec![0..end]);
4571        });
4572    }
4573
4574    pub fn select_line(&mut self, _: &SelectLine, cx: &mut ViewContext<Self>) {
4575        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
4576        let mut selections = self.selections.all::<Point>(cx);
4577        let max_point = display_map.buffer_snapshot.max_point();
4578        for selection in &mut selections {
4579            let rows = selection.spanned_rows(true, &display_map);
4580            selection.start = Point::new(rows.start, 0);
4581            selection.end = cmp::min(max_point, Point::new(rows.end, 0));
4582            selection.reversed = false;
4583        }
4584        self.change_selections(Some(Autoscroll::Fit), cx, |s| {
4585            s.select(selections);
4586        });
4587    }
4588
4589    pub fn split_selection_into_lines(
4590        &mut self,
4591        _: &SplitSelectionIntoLines,
4592        cx: &mut ViewContext<Self>,
4593    ) {
4594        let mut to_unfold = Vec::new();
4595        let mut new_selection_ranges = Vec::new();
4596        {
4597            let selections = self.selections.all::<Point>(cx);
4598            let buffer = self.buffer.read(cx).read(cx);
4599            for selection in selections {
4600                for row in selection.start.row..selection.end.row {
4601                    let cursor = Point::new(row, buffer.line_len(row));
4602                    new_selection_ranges.push(cursor..cursor);
4603                }
4604                new_selection_ranges.push(selection.end..selection.end);
4605                to_unfold.push(selection.start..selection.end);
4606            }
4607        }
4608        self.unfold_ranges(to_unfold, true, cx);
4609        self.change_selections(Some(Autoscroll::Fit), cx, |s| {
4610            s.select_ranges(new_selection_ranges);
4611        });
4612    }
4613
4614    pub fn add_selection_above(&mut self, _: &AddSelectionAbove, cx: &mut ViewContext<Self>) {
4615        self.add_selection(true, cx);
4616    }
4617
4618    pub fn add_selection_below(&mut self, _: &AddSelectionBelow, cx: &mut ViewContext<Self>) {
4619        self.add_selection(false, cx);
4620    }
4621
4622    fn add_selection(&mut self, above: bool, cx: &mut ViewContext<Self>) {
4623        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
4624        let mut selections = self.selections.all::<Point>(cx);
4625        let mut state = self.add_selections_state.take().unwrap_or_else(|| {
4626            let oldest_selection = selections.iter().min_by_key(|s| s.id).unwrap().clone();
4627            let range = oldest_selection.display_range(&display_map).sorted();
4628            let columns = cmp::min(range.start.column(), range.end.column())
4629                ..cmp::max(range.start.column(), range.end.column());
4630
4631            selections.clear();
4632            let mut stack = Vec::new();
4633            for row in range.start.row()..=range.end.row() {
4634                if let Some(selection) = self.selections.build_columnar_selection(
4635                    &display_map,
4636                    row,
4637                    &columns,
4638                    oldest_selection.reversed,
4639                ) {
4640                    stack.push(selection.id);
4641                    selections.push(selection);
4642                }
4643            }
4644
4645            if above {
4646                stack.reverse();
4647            }
4648
4649            AddSelectionsState { above, stack }
4650        });
4651
4652        let last_added_selection = *state.stack.last().unwrap();
4653        let mut new_selections = Vec::new();
4654        if above == state.above {
4655            let end_row = if above {
4656                0
4657            } else {
4658                display_map.max_point().row()
4659            };
4660
4661            'outer: for selection in selections {
4662                if selection.id == last_added_selection {
4663                    let range = selection.display_range(&display_map).sorted();
4664                    debug_assert_eq!(range.start.row(), range.end.row());
4665                    let mut row = range.start.row();
4666                    let columns = if let SelectionGoal::ColumnRange { start, end } = selection.goal
4667                    {
4668                        start..end
4669                    } else {
4670                        cmp::min(range.start.column(), range.end.column())
4671                            ..cmp::max(range.start.column(), range.end.column())
4672                    };
4673
4674                    while row != end_row {
4675                        if above {
4676                            row -= 1;
4677                        } else {
4678                            row += 1;
4679                        }
4680
4681                        if let Some(new_selection) = self.selections.build_columnar_selection(
4682                            &display_map,
4683                            row,
4684                            &columns,
4685                            selection.reversed,
4686                        ) {
4687                            state.stack.push(new_selection.id);
4688                            if above {
4689                                new_selections.push(new_selection);
4690                                new_selections.push(selection);
4691                            } else {
4692                                new_selections.push(selection);
4693                                new_selections.push(new_selection);
4694                            }
4695
4696                            continue 'outer;
4697                        }
4698                    }
4699                }
4700
4701                new_selections.push(selection);
4702            }
4703        } else {
4704            new_selections = selections;
4705            new_selections.retain(|s| s.id != last_added_selection);
4706            state.stack.pop();
4707        }
4708
4709        self.change_selections(Some(Autoscroll::Fit), cx, |s| {
4710            s.select(new_selections);
4711        });
4712        if state.stack.len() > 1 {
4713            self.add_selections_state = Some(state);
4714        }
4715    }
4716
4717    pub fn select_next(&mut self, action: &SelectNext, cx: &mut ViewContext<Self>) {
4718        self.push_to_selection_history();
4719        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
4720        let buffer = &display_map.buffer_snapshot;
4721        let mut selections = self.selections.all::<usize>(cx);
4722        if let Some(mut select_next_state) = self.select_next_state.take() {
4723            let query = &select_next_state.query;
4724            if !select_next_state.done {
4725                let first_selection = selections.iter().min_by_key(|s| s.id).unwrap();
4726                let last_selection = selections.iter().max_by_key(|s| s.id).unwrap();
4727                let mut next_selected_range = None;
4728
4729                let bytes_after_last_selection =
4730                    buffer.bytes_in_range(last_selection.end..buffer.len());
4731                let bytes_before_first_selection = buffer.bytes_in_range(0..first_selection.start);
4732                let query_matches = query
4733                    .stream_find_iter(bytes_after_last_selection)
4734                    .map(|result| (last_selection.end, result))
4735                    .chain(
4736                        query
4737                            .stream_find_iter(bytes_before_first_selection)
4738                            .map(|result| (0, result)),
4739                    );
4740                for (start_offset, query_match) in query_matches {
4741                    let query_match = query_match.unwrap(); // can only fail due to I/O
4742                    let offset_range =
4743                        start_offset + query_match.start()..start_offset + query_match.end();
4744                    let display_range = offset_range.start.to_display_point(&display_map)
4745                        ..offset_range.end.to_display_point(&display_map);
4746
4747                    if !select_next_state.wordwise
4748                        || (!movement::is_inside_word(&display_map, display_range.start)
4749                            && !movement::is_inside_word(&display_map, display_range.end))
4750                    {
4751                        next_selected_range = Some(offset_range);
4752                        break;
4753                    }
4754                }
4755
4756                if let Some(next_selected_range) = next_selected_range {
4757                    self.unfold_ranges([next_selected_range.clone()], false, cx);
4758                    self.change_selections(Some(Autoscroll::Newest), cx, |s| {
4759                        if action.replace_newest {
4760                            s.delete(s.newest_anchor().id);
4761                        }
4762                        s.insert_range(next_selected_range);
4763                    });
4764                } else {
4765                    select_next_state.done = true;
4766                }
4767            }
4768
4769            self.select_next_state = Some(select_next_state);
4770        } else if selections.len() == 1 {
4771            let selection = selections.last_mut().unwrap();
4772            if selection.start == selection.end {
4773                let word_range = movement::surrounding_word(
4774                    &display_map,
4775                    selection.start.to_display_point(&display_map),
4776                );
4777                selection.start = word_range.start.to_offset(&display_map, Bias::Left);
4778                selection.end = word_range.end.to_offset(&display_map, Bias::Left);
4779                selection.goal = SelectionGoal::None;
4780                selection.reversed = false;
4781
4782                let query = buffer
4783                    .text_for_range(selection.start..selection.end)
4784                    .collect::<String>();
4785                let select_state = SelectNextState {
4786                    query: AhoCorasick::new_auto_configured(&[query]),
4787                    wordwise: true,
4788                    done: false,
4789                };
4790                self.unfold_ranges([selection.start..selection.end], false, cx);
4791                self.change_selections(Some(Autoscroll::Newest), cx, |s| {
4792                    s.select(selections);
4793                });
4794                self.select_next_state = Some(select_state);
4795            } else {
4796                let query = buffer
4797                    .text_for_range(selection.start..selection.end)
4798                    .collect::<String>();
4799                self.select_next_state = Some(SelectNextState {
4800                    query: AhoCorasick::new_auto_configured(&[query]),
4801                    wordwise: false,
4802                    done: false,
4803                });
4804                self.select_next(action, cx);
4805            }
4806        }
4807    }
4808
4809    pub fn toggle_comments(&mut self, _: &ToggleComments, cx: &mut ViewContext<Self>) {
4810        self.transact(cx, |this, cx| {
4811            let mut selections = this.selections.all::<Point>(cx);
4812            let mut edits = Vec::new();
4813            let mut selection_edit_ranges = Vec::new();
4814            let mut last_toggled_row = None;
4815            let snapshot = this.buffer.read(cx).read(cx);
4816            let empty_str: Arc<str> = "".into();
4817            let mut suffixes_inserted = Vec::new();
4818
4819            fn comment_prefix_range(
4820                snapshot: &MultiBufferSnapshot,
4821                row: u32,
4822                comment_prefix: &str,
4823                comment_prefix_whitespace: &str,
4824            ) -> Range<Point> {
4825                let start = Point::new(row, snapshot.indent_size_for_line(row).len);
4826
4827                let mut line_bytes = snapshot
4828                    .bytes_in_range(start..snapshot.max_point())
4829                    .flatten()
4830                    .copied();
4831
4832                // If this line currently begins with the line comment prefix, then record
4833                // the range containing the prefix.
4834                if line_bytes
4835                    .by_ref()
4836                    .take(comment_prefix.len())
4837                    .eq(comment_prefix.bytes())
4838                {
4839                    // Include any whitespace that matches the comment prefix.
4840                    let matching_whitespace_len = line_bytes
4841                        .zip(comment_prefix_whitespace.bytes())
4842                        .take_while(|(a, b)| a == b)
4843                        .count() as u32;
4844                    let end = Point::new(
4845                        start.row,
4846                        start.column + comment_prefix.len() as u32 + matching_whitespace_len,
4847                    );
4848                    start..end
4849                } else {
4850                    start..start
4851                }
4852            }
4853
4854            fn comment_suffix_range(
4855                snapshot: &MultiBufferSnapshot,
4856                row: u32,
4857                comment_suffix: &str,
4858                comment_suffix_has_leading_space: bool,
4859            ) -> Range<Point> {
4860                let end = Point::new(row, snapshot.line_len(row));
4861                let suffix_start_column = end.column.saturating_sub(comment_suffix.len() as u32);
4862
4863                let mut line_end_bytes = snapshot
4864                    .bytes_in_range(Point::new(end.row, suffix_start_column.saturating_sub(1))..end)
4865                    .flatten()
4866                    .copied();
4867
4868                let leading_space_len = if suffix_start_column > 0
4869                    && line_end_bytes.next() == Some(b' ')
4870                    && comment_suffix_has_leading_space
4871                {
4872                    1
4873                } else {
4874                    0
4875                };
4876
4877                // If this line currently begins with the line comment prefix, then record
4878                // the range containing the prefix.
4879                if line_end_bytes.by_ref().eq(comment_suffix.bytes()) {
4880                    let start = Point::new(end.row, suffix_start_column - leading_space_len);
4881                    start..end
4882                } else {
4883                    end..end
4884                }
4885            }
4886
4887            // TODO: Handle selections that cross excerpts
4888            for selection in &mut selections {
4889                let language = if let Some(language) = snapshot.language_at(selection.start) {
4890                    language
4891                } else {
4892                    continue;
4893                };
4894
4895                selection_edit_ranges.clear();
4896
4897                // If multiple selections contain a given row, avoid processing that
4898                // row more than once.
4899                let mut start_row = selection.start.row;
4900                if last_toggled_row == Some(start_row) {
4901                    start_row += 1;
4902                }
4903                let end_row =
4904                    if selection.end.row > selection.start.row && selection.end.column == 0 {
4905                        selection.end.row - 1
4906                    } else {
4907                        selection.end.row
4908                    };
4909                last_toggled_row = Some(end_row);
4910
4911                if start_row > end_row {
4912                    continue;
4913                }
4914
4915                // If the language has line comments, toggle those.
4916                if let Some(full_comment_prefix) = language.line_comment_prefix() {
4917                    // Split the comment prefix's trailing whitespace into a separate string,
4918                    // as that portion won't be used for detecting if a line is a comment.
4919                    let comment_prefix = full_comment_prefix.trim_end_matches(' ');
4920                    let comment_prefix_whitespace = &full_comment_prefix[comment_prefix.len()..];
4921                    let mut all_selection_lines_are_comments = true;
4922
4923                    for row in start_row..=end_row {
4924                        if snapshot.is_line_blank(row) {
4925                            continue;
4926                        }
4927
4928                        let prefix_range = comment_prefix_range(
4929                            snapshot.deref(),
4930                            row,
4931                            comment_prefix,
4932                            comment_prefix_whitespace,
4933                        );
4934                        if prefix_range.is_empty() {
4935                            all_selection_lines_are_comments = false;
4936                        }
4937                        selection_edit_ranges.push(prefix_range);
4938                    }
4939
4940                    if all_selection_lines_are_comments {
4941                        edits.extend(
4942                            selection_edit_ranges
4943                                .iter()
4944                                .cloned()
4945                                .map(|range| (range, empty_str.clone())),
4946                        );
4947                    } else {
4948                        let min_column = selection_edit_ranges
4949                            .iter()
4950                            .map(|r| r.start.column)
4951                            .min()
4952                            .unwrap_or(0);
4953                        edits.extend(selection_edit_ranges.iter().map(|range| {
4954                            let position = Point::new(range.start.row, min_column);
4955                            (position..position, full_comment_prefix.clone())
4956                        }));
4957                    }
4958                } else if let Some((full_comment_prefix, comment_suffix)) =
4959                    language.block_comment_delimiters()
4960                {
4961                    let comment_prefix = full_comment_prefix.trim_end_matches(' ');
4962                    let comment_prefix_whitespace = &full_comment_prefix[comment_prefix.len()..];
4963                    let prefix_range = comment_prefix_range(
4964                        snapshot.deref(),
4965                        start_row,
4966                        comment_prefix,
4967                        comment_prefix_whitespace,
4968                    );
4969                    let suffix_range = comment_suffix_range(
4970                        snapshot.deref(),
4971                        end_row,
4972                        comment_suffix.trim_start_matches(' '),
4973                        comment_suffix.starts_with(' '),
4974                    );
4975
4976                    if prefix_range.is_empty() || suffix_range.is_empty() {
4977                        edits.push((
4978                            prefix_range.start..prefix_range.start,
4979                            full_comment_prefix.clone(),
4980                        ));
4981                        edits.push((suffix_range.end..suffix_range.end, comment_suffix.clone()));
4982                        suffixes_inserted.push((end_row, comment_suffix.len()));
4983                    } else {
4984                        edits.push((prefix_range, empty_str.clone()));
4985                        edits.push((suffix_range, empty_str.clone()));
4986                    }
4987                } else {
4988                    continue;
4989                }
4990            }
4991
4992            drop(snapshot);
4993            this.buffer.update(cx, |buffer, cx| {
4994                buffer.edit(edits, None, cx);
4995            });
4996
4997            // Adjust selections so that they end before any comment suffixes that
4998            // were inserted.
4999            let mut suffixes_inserted = suffixes_inserted.into_iter().peekable();
5000            let mut selections = this.selections.all::<Point>(cx);
5001            let snapshot = this.buffer.read(cx).read(cx);
5002            for selection in &mut selections {
5003                while let Some((row, suffix_len)) = suffixes_inserted.peek().copied() {
5004                    match row.cmp(&selection.end.row) {
5005                        Ordering::Less => {
5006                            suffixes_inserted.next();
5007                            continue;
5008                        }
5009                        Ordering::Greater => break,
5010                        Ordering::Equal => {
5011                            if selection.end.column == snapshot.line_len(row) {
5012                                if selection.is_empty() {
5013                                    selection.start.column -= suffix_len as u32;
5014                                }
5015                                selection.end.column -= suffix_len as u32;
5016                            }
5017                            break;
5018                        }
5019                    }
5020                }
5021            }
5022
5023            drop(snapshot);
5024            this.change_selections(Some(Autoscroll::Fit), cx, |s| s.select(selections));
5025        });
5026    }
5027
5028    pub fn select_larger_syntax_node(
5029        &mut self,
5030        _: &SelectLargerSyntaxNode,
5031        cx: &mut ViewContext<Self>,
5032    ) {
5033        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
5034        let buffer = self.buffer.read(cx).snapshot(cx);
5035        let old_selections = self.selections.all::<usize>(cx).into_boxed_slice();
5036
5037        let mut stack = mem::take(&mut self.select_larger_syntax_node_stack);
5038        let mut selected_larger_node = false;
5039        let new_selections = old_selections
5040            .iter()
5041            .map(|selection| {
5042                let old_range = selection.start..selection.end;
5043                let mut new_range = old_range.clone();
5044                while let Some(containing_range) =
5045                    buffer.range_for_syntax_ancestor(new_range.clone())
5046                {
5047                    new_range = containing_range;
5048                    if !display_map.intersects_fold(new_range.start)
5049                        && !display_map.intersects_fold(new_range.end)
5050                    {
5051                        break;
5052                    }
5053                }
5054
5055                selected_larger_node |= new_range != old_range;
5056                Selection {
5057                    id: selection.id,
5058                    start: new_range.start,
5059                    end: new_range.end,
5060                    goal: SelectionGoal::None,
5061                    reversed: selection.reversed,
5062                }
5063            })
5064            .collect::<Vec<_>>();
5065
5066        if selected_larger_node {
5067            stack.push(old_selections);
5068            self.change_selections(Some(Autoscroll::Fit), cx, |s| {
5069                s.select(new_selections);
5070            });
5071        }
5072        self.select_larger_syntax_node_stack = stack;
5073    }
5074
5075    pub fn select_smaller_syntax_node(
5076        &mut self,
5077        _: &SelectSmallerSyntaxNode,
5078        cx: &mut ViewContext<Self>,
5079    ) {
5080        let mut stack = mem::take(&mut self.select_larger_syntax_node_stack);
5081        if let Some(selections) = stack.pop() {
5082            self.change_selections(Some(Autoscroll::Fit), cx, |s| {
5083                s.select(selections.to_vec());
5084            });
5085        }
5086        self.select_larger_syntax_node_stack = stack;
5087    }
5088
5089    pub fn move_to_enclosing_bracket(
5090        &mut self,
5091        _: &MoveToEnclosingBracket,
5092        cx: &mut ViewContext<Self>,
5093    ) {
5094        let buffer = self.buffer.read(cx).snapshot(cx);
5095        let mut selections = self.selections.all::<usize>(cx);
5096        for selection in &mut selections {
5097            if let Some((open_range, close_range)) =
5098                buffer.enclosing_bracket_ranges(selection.start..selection.end)
5099            {
5100                let close_range = close_range.to_inclusive();
5101                let destination = if close_range.contains(&selection.start)
5102                    && close_range.contains(&selection.end)
5103                {
5104                    open_range.end
5105                } else {
5106                    *close_range.start()
5107                };
5108                selection.start = destination;
5109                selection.end = destination;
5110            }
5111        }
5112
5113        self.change_selections(Some(Autoscroll::Fit), cx, |s| {
5114            s.select(selections);
5115        });
5116    }
5117
5118    pub fn undo_selection(&mut self, _: &UndoSelection, cx: &mut ViewContext<Self>) {
5119        self.end_selection(cx);
5120        self.selection_history.mode = SelectionHistoryMode::Undoing;
5121        if let Some(entry) = self.selection_history.undo_stack.pop_back() {
5122            self.change_selections(None, cx, |s| s.select_anchors(entry.selections.to_vec()));
5123            self.select_next_state = entry.select_next_state;
5124            self.add_selections_state = entry.add_selections_state;
5125            self.request_autoscroll(Autoscroll::Newest, cx);
5126        }
5127        self.selection_history.mode = SelectionHistoryMode::Normal;
5128    }
5129
5130    pub fn redo_selection(&mut self, _: &RedoSelection, cx: &mut ViewContext<Self>) {
5131        self.end_selection(cx);
5132        self.selection_history.mode = SelectionHistoryMode::Redoing;
5133        if let Some(entry) = self.selection_history.redo_stack.pop_back() {
5134            self.change_selections(None, cx, |s| s.select_anchors(entry.selections.to_vec()));
5135            self.select_next_state = entry.select_next_state;
5136            self.add_selections_state = entry.add_selections_state;
5137            self.request_autoscroll(Autoscroll::Newest, cx);
5138        }
5139        self.selection_history.mode = SelectionHistoryMode::Normal;
5140    }
5141
5142    fn go_to_diagnostic(&mut self, _: &GoToDiagnostic, cx: &mut ViewContext<Self>) {
5143        self.go_to_diagnostic_impl(Direction::Next, cx)
5144    }
5145
5146    fn go_to_prev_diagnostic(&mut self, _: &GoToPrevDiagnostic, cx: &mut ViewContext<Self>) {
5147        self.go_to_diagnostic_impl(Direction::Prev, cx)
5148    }
5149
5150    pub fn go_to_diagnostic_impl(&mut self, direction: Direction, cx: &mut ViewContext<Self>) {
5151        let buffer = self.buffer.read(cx).snapshot(cx);
5152        let selection = self.selections.newest::<usize>(cx);
5153
5154        // If there is an active Diagnostic Popover. Jump to it's diagnostic instead.
5155        if direction == Direction::Next {
5156            if let Some(popover) = self.hover_state.diagnostic_popover.as_ref() {
5157                let (group_id, jump_to) = popover.activation_info();
5158                if self.activate_diagnostics(group_id, cx) {
5159                    self.change_selections(Some(Autoscroll::Center), cx, |s| {
5160                        let mut new_selection = s.newest_anchor().clone();
5161                        new_selection.collapse_to(jump_to, SelectionGoal::None);
5162                        s.select_anchors(vec![new_selection.clone()]);
5163                    });
5164                }
5165                return;
5166            }
5167        }
5168
5169        let mut active_primary_range = self.active_diagnostics.as_ref().map(|active_diagnostics| {
5170            active_diagnostics
5171                .primary_range
5172                .to_offset(&buffer)
5173                .to_inclusive()
5174        });
5175        let mut search_start = if let Some(active_primary_range) = active_primary_range.as_ref() {
5176            if active_primary_range.contains(&selection.head()) {
5177                *active_primary_range.end()
5178            } else {
5179                selection.head()
5180            }
5181        } else {
5182            selection.head()
5183        };
5184
5185        loop {
5186            let mut diagnostics = if direction == Direction::Prev {
5187                buffer.diagnostics_in_range::<_, usize>(0..search_start, true)
5188            } else {
5189                buffer.diagnostics_in_range::<_, usize>(search_start..buffer.len(), false)
5190            };
5191            let group = diagnostics.find_map(|entry| {
5192                if entry.diagnostic.is_primary
5193                    && entry.diagnostic.severity <= DiagnosticSeverity::WARNING
5194                    && !entry.range.is_empty()
5195                    && Some(entry.range.end) != active_primary_range.as_ref().map(|r| *r.end())
5196                {
5197                    Some((entry.range, entry.diagnostic.group_id))
5198                } else {
5199                    None
5200                }
5201            });
5202
5203            if let Some((primary_range, group_id)) = group {
5204                if self.activate_diagnostics(group_id, cx) {
5205                    self.change_selections(Some(Autoscroll::Center), cx, |s| {
5206                        s.select(vec![Selection {
5207                            id: selection.id,
5208                            start: primary_range.start,
5209                            end: primary_range.start,
5210                            reversed: false,
5211                            goal: SelectionGoal::None,
5212                        }]);
5213                    });
5214                }
5215                break;
5216            } else {
5217                // Cycle around to the start of the buffer, potentially moving back to the start of
5218                // the currently active diagnostic.
5219                active_primary_range.take();
5220                if direction == Direction::Prev {
5221                    if search_start == buffer.len() {
5222                        break;
5223                    } else {
5224                        search_start = buffer.len();
5225                    }
5226                } else if search_start == 0 {
5227                    break;
5228                } else {
5229                    search_start = 0;
5230                }
5231            }
5232        }
5233    }
5234
5235    pub fn go_to_definition(
5236        workspace: &mut Workspace,
5237        _: &GoToDefinition,
5238        cx: &mut ViewContext<Workspace>,
5239    ) {
5240        Self::go_to_definition_of_kind(GotoDefinitionKind::Symbol, workspace, cx);
5241    }
5242
5243    pub fn go_to_type_definition(
5244        workspace: &mut Workspace,
5245        _: &GoToTypeDefinition,
5246        cx: &mut ViewContext<Workspace>,
5247    ) {
5248        Self::go_to_definition_of_kind(GotoDefinitionKind::Type, workspace, cx);
5249    }
5250
5251    fn go_to_definition_of_kind(
5252        kind: GotoDefinitionKind,
5253        workspace: &mut Workspace,
5254        cx: &mut ViewContext<Workspace>,
5255    ) {
5256        let active_item = workspace.active_item(cx);
5257        let editor_handle = if let Some(editor) = active_item
5258            .as_ref()
5259            .and_then(|item| item.act_as::<Self>(cx))
5260        {
5261            editor
5262        } else {
5263            return;
5264        };
5265
5266        let editor = editor_handle.read(cx);
5267        let buffer = editor.buffer.read(cx);
5268        let head = editor.selections.newest::<usize>(cx).head();
5269        let (buffer, head) = if let Some(text_anchor) = buffer.text_anchor_for_position(head, cx) {
5270            text_anchor
5271        } else {
5272            return;
5273        };
5274
5275        let project = workspace.project().clone();
5276        let definitions = project.update(cx, |project, cx| match kind {
5277            GotoDefinitionKind::Symbol => project.definition(&buffer, head, cx),
5278            GotoDefinitionKind::Type => project.type_definition(&buffer, head, cx),
5279        });
5280
5281        cx.spawn(|workspace, mut cx| async move {
5282            let definitions = definitions.await?;
5283            workspace.update(&mut cx, |workspace, cx| {
5284                Editor::navigate_to_definitions(workspace, editor_handle, definitions, cx);
5285            });
5286
5287            Ok::<(), anyhow::Error>(())
5288        })
5289        .detach_and_log_err(cx);
5290    }
5291
5292    pub fn navigate_to_definitions(
5293        workspace: &mut Workspace,
5294        editor_handle: ViewHandle<Editor>,
5295        definitions: Vec<LocationLink>,
5296        cx: &mut ViewContext<Workspace>,
5297    ) {
5298        let pane = workspace.active_pane().clone();
5299        for definition in definitions {
5300            let range = definition
5301                .target
5302                .range
5303                .to_offset(definition.target.buffer.read(cx));
5304
5305            let target_editor_handle = workspace.open_project_item(definition.target.buffer, cx);
5306            target_editor_handle.update(cx, |target_editor, cx| {
5307                // When selecting a definition in a different buffer, disable the nav history
5308                // to avoid creating a history entry at the previous cursor location.
5309                if editor_handle != target_editor_handle {
5310                    pane.update(cx, |pane, _| pane.disable_history());
5311                }
5312                target_editor.change_selections(Some(Autoscroll::Center), cx, |s| {
5313                    s.select_ranges([range]);
5314                });
5315
5316                pane.update(cx, |pane, _| pane.enable_history());
5317            });
5318        }
5319    }
5320
5321    pub fn find_all_references(
5322        workspace: &mut Workspace,
5323        _: &FindAllReferences,
5324        cx: &mut ViewContext<Workspace>,
5325    ) -> Option<Task<Result<()>>> {
5326        let active_item = workspace.active_item(cx)?;
5327        let editor_handle = active_item.act_as::<Self>(cx)?;
5328
5329        let editor = editor_handle.read(cx);
5330        let buffer = editor.buffer.read(cx);
5331        let head = editor.selections.newest::<usize>(cx).head();
5332        let (buffer, head) = buffer.text_anchor_for_position(head, cx)?;
5333        let replica_id = editor.replica_id(cx);
5334
5335        let project = workspace.project().clone();
5336        let references = project.update(cx, |project, cx| project.references(&buffer, head, cx));
5337        Some(cx.spawn(|workspace, mut cx| async move {
5338            let mut locations = references.await?;
5339            if locations.is_empty() {
5340                return Ok(());
5341            }
5342
5343            locations.sort_by_key(|location| location.buffer.id());
5344            let mut locations = locations.into_iter().peekable();
5345            let mut ranges_to_highlight = Vec::new();
5346
5347            let excerpt_buffer = cx.add_model(|cx| {
5348                let mut symbol_name = None;
5349                let mut multibuffer = MultiBuffer::new(replica_id);
5350                while let Some(location) = locations.next() {
5351                    let buffer = location.buffer.read(cx);
5352                    let mut ranges_for_buffer = Vec::new();
5353                    let range = location.range.to_offset(buffer);
5354                    ranges_for_buffer.push(range.clone());
5355                    if symbol_name.is_none() {
5356                        symbol_name = Some(buffer.text_for_range(range).collect::<String>());
5357                    }
5358
5359                    while let Some(next_location) = locations.peek() {
5360                        if next_location.buffer == location.buffer {
5361                            ranges_for_buffer.push(next_location.range.to_offset(buffer));
5362                            locations.next();
5363                        } else {
5364                            break;
5365                        }
5366                    }
5367
5368                    ranges_for_buffer.sort_by_key(|range| (range.start, Reverse(range.end)));
5369                    ranges_to_highlight.extend(multibuffer.push_excerpts_with_context_lines(
5370                        location.buffer.clone(),
5371                        ranges_for_buffer,
5372                        1,
5373                        cx,
5374                    ));
5375                }
5376                multibuffer.with_title(format!("References to `{}`", symbol_name.unwrap()))
5377            });
5378
5379            workspace.update(&mut cx, |workspace, cx| {
5380                let editor =
5381                    cx.add_view(|cx| Editor::for_multibuffer(excerpt_buffer, Some(project), cx));
5382                editor.update(cx, |editor, cx| {
5383                    editor.highlight_background::<Self>(
5384                        ranges_to_highlight,
5385                        |theme| theme.editor.highlighted_line_background,
5386                        cx,
5387                    );
5388                });
5389                workspace.add_item(Box::new(editor), cx);
5390            });
5391
5392            Ok(())
5393        }))
5394    }
5395
5396    pub fn rename(&mut self, _: &Rename, cx: &mut ViewContext<Self>) -> Option<Task<Result<()>>> {
5397        use language::ToOffset as _;
5398
5399        let project = self.project.clone()?;
5400        let selection = self.selections.newest_anchor().clone();
5401        let (cursor_buffer, cursor_buffer_position) = self
5402            .buffer
5403            .read(cx)
5404            .text_anchor_for_position(selection.head(), cx)?;
5405        let (tail_buffer, _) = self
5406            .buffer
5407            .read(cx)
5408            .text_anchor_for_position(selection.tail(), cx)?;
5409        if tail_buffer != cursor_buffer {
5410            return None;
5411        }
5412
5413        let snapshot = cursor_buffer.read(cx).snapshot();
5414        let cursor_buffer_offset = cursor_buffer_position.to_offset(&snapshot);
5415        let prepare_rename = project.update(cx, |project, cx| {
5416            project.prepare_rename(cursor_buffer, cursor_buffer_offset, cx)
5417        });
5418
5419        Some(cx.spawn(|this, mut cx| async move {
5420            let rename_range = if let Some(range) = prepare_rename.await? {
5421                Some(range)
5422            } else {
5423                this.read_with(&cx, |this, cx| {
5424                    let buffer = this.buffer.read(cx).snapshot(cx);
5425                    let mut buffer_highlights = this
5426                        .document_highlights_for_position(selection.head(), &buffer)
5427                        .filter(|highlight| {
5428                            highlight.start.excerpt_id() == selection.head().excerpt_id()
5429                                && highlight.end.excerpt_id() == selection.head().excerpt_id()
5430                        });
5431                    buffer_highlights
5432                        .next()
5433                        .map(|highlight| highlight.start.text_anchor..highlight.end.text_anchor)
5434                })
5435            };
5436            if let Some(rename_range) = rename_range {
5437                let rename_buffer_range = rename_range.to_offset(&snapshot);
5438                let cursor_offset_in_rename_range =
5439                    cursor_buffer_offset.saturating_sub(rename_buffer_range.start);
5440
5441                this.update(&mut cx, |this, cx| {
5442                    this.take_rename(false, cx);
5443                    let style = this.style(cx);
5444                    let buffer = this.buffer.read(cx).read(cx);
5445                    let cursor_offset = selection.head().to_offset(&buffer);
5446                    let rename_start = cursor_offset.saturating_sub(cursor_offset_in_rename_range);
5447                    let rename_end = rename_start + rename_buffer_range.len();
5448                    let range = buffer.anchor_before(rename_start)..buffer.anchor_after(rename_end);
5449                    let mut old_highlight_id = None;
5450                    let old_name: Arc<str> = buffer
5451                        .chunks(rename_start..rename_end, true)
5452                        .map(|chunk| {
5453                            if old_highlight_id.is_none() {
5454                                old_highlight_id = chunk.syntax_highlight_id;
5455                            }
5456                            chunk.text
5457                        })
5458                        .collect::<String>()
5459                        .into();
5460
5461                    drop(buffer);
5462
5463                    // Position the selection in the rename editor so that it matches the current selection.
5464                    this.show_local_selections = false;
5465                    let rename_editor = cx.add_view(|cx| {
5466                        let mut editor = Editor::single_line(None, cx);
5467                        if let Some(old_highlight_id) = old_highlight_id {
5468                            editor.override_text_style =
5469                                Some(Box::new(move |style| old_highlight_id.style(&style.syntax)));
5470                        }
5471                        editor.buffer.update(cx, |buffer, cx| {
5472                            buffer.edit([(0..0, old_name.clone())], None, cx)
5473                        });
5474                        editor.select_all(&SelectAll, cx);
5475                        editor
5476                    });
5477
5478                    let ranges = this
5479                        .clear_background_highlights::<DocumentHighlightWrite>(cx)
5480                        .into_iter()
5481                        .flat_map(|(_, ranges)| ranges)
5482                        .chain(
5483                            this.clear_background_highlights::<DocumentHighlightRead>(cx)
5484                                .into_iter()
5485                                .flat_map(|(_, ranges)| ranges),
5486                        )
5487                        .collect();
5488
5489                    this.highlight_text::<Rename>(
5490                        ranges,
5491                        HighlightStyle {
5492                            fade_out: Some(style.rename_fade),
5493                            ..Default::default()
5494                        },
5495                        cx,
5496                    );
5497                    cx.focus(&rename_editor);
5498                    let block_id = this.insert_blocks(
5499                        [BlockProperties {
5500                            style: BlockStyle::Flex,
5501                            position: range.start.clone(),
5502                            height: 1,
5503                            render: Arc::new({
5504                                let editor = rename_editor.clone();
5505                                move |cx: &mut BlockContext| {
5506                                    ChildView::new(editor.clone(), cx)
5507                                        .contained()
5508                                        .with_padding_left(cx.anchor_x)
5509                                        .boxed()
5510                                }
5511                            }),
5512                            disposition: BlockDisposition::Below,
5513                        }],
5514                        cx,
5515                    )[0];
5516                    this.pending_rename = Some(RenameState {
5517                        range,
5518                        old_name,
5519                        editor: rename_editor,
5520                        block_id,
5521                    });
5522                });
5523            }
5524
5525            Ok(())
5526        }))
5527    }
5528
5529    pub fn confirm_rename(
5530        workspace: &mut Workspace,
5531        _: &ConfirmRename,
5532        cx: &mut ViewContext<Workspace>,
5533    ) -> Option<Task<Result<()>>> {
5534        let editor = workspace.active_item(cx)?.act_as::<Editor>(cx)?;
5535
5536        let (buffer, range, old_name, new_name) = editor.update(cx, |editor, cx| {
5537            let rename = editor.take_rename(false, cx)?;
5538            let buffer = editor.buffer.read(cx);
5539            let (start_buffer, start) =
5540                buffer.text_anchor_for_position(rename.range.start.clone(), cx)?;
5541            let (end_buffer, end) =
5542                buffer.text_anchor_for_position(rename.range.end.clone(), cx)?;
5543            if start_buffer == end_buffer {
5544                let new_name = rename.editor.read(cx).text(cx);
5545                Some((start_buffer, start..end, rename.old_name, new_name))
5546            } else {
5547                None
5548            }
5549        })?;
5550
5551        let rename = workspace.project().clone().update(cx, |project, cx| {
5552            project.perform_rename(buffer.clone(), range.start, new_name.clone(), true, cx)
5553        });
5554
5555        Some(cx.spawn(|workspace, mut cx| async move {
5556            let project_transaction = rename.await?;
5557            Self::open_project_transaction(
5558                editor.clone(),
5559                workspace,
5560                project_transaction,
5561                format!("Rename: {}{}", old_name, new_name),
5562                cx.clone(),
5563            )
5564            .await?;
5565
5566            editor.update(&mut cx, |editor, cx| {
5567                editor.refresh_document_highlights(cx);
5568            });
5569            Ok(())
5570        }))
5571    }
5572
5573    fn take_rename(
5574        &mut self,
5575        moving_cursor: bool,
5576        cx: &mut ViewContext<Self>,
5577    ) -> Option<RenameState> {
5578        let rename = self.pending_rename.take()?;
5579        self.remove_blocks([rename.block_id].into_iter().collect(), cx);
5580        self.clear_text_highlights::<Rename>(cx);
5581        self.show_local_selections = true;
5582
5583        if moving_cursor {
5584            let rename_editor = rename.editor.read(cx);
5585            let cursor_in_rename_editor = rename_editor.selections.newest::<usize>(cx).head();
5586
5587            // Update the selection to match the position of the selection inside
5588            // the rename editor.
5589            let snapshot = self.buffer.read(cx).read(cx);
5590            let rename_range = rename.range.to_offset(&snapshot);
5591            let cursor_in_editor = snapshot
5592                .clip_offset(rename_range.start + cursor_in_rename_editor, Bias::Left)
5593                .min(rename_range.end);
5594            drop(snapshot);
5595
5596            self.change_selections(None, cx, |s| {
5597                s.select_ranges(vec![cursor_in_editor..cursor_in_editor])
5598            });
5599        } else {
5600            self.refresh_document_highlights(cx);
5601        }
5602
5603        Some(rename)
5604    }
5605
5606    #[cfg(any(test, feature = "test-support"))]
5607    pub fn pending_rename(&self) -> Option<&RenameState> {
5608        self.pending_rename.as_ref()
5609    }
5610
5611    fn format(&mut self, _: &Format, cx: &mut ViewContext<'_, Self>) -> Option<Task<Result<()>>> {
5612        let project = match &self.project {
5613            Some(project) => project.clone(),
5614            None => return None,
5615        };
5616
5617        Some(self.perform_format(project, cx))
5618    }
5619
5620    fn perform_format(
5621        &mut self,
5622        project: ModelHandle<Project>,
5623        cx: &mut ViewContext<'_, Self>,
5624    ) -> Task<Result<()>> {
5625        let buffer = self.buffer().clone();
5626        let buffers = buffer.read(cx).all_buffers();
5627
5628        let mut timeout = cx.background().timer(FORMAT_TIMEOUT).fuse();
5629        let format = project.update(cx, |project, cx| {
5630            project.format(buffers, true, FormatTrigger::Manual, cx)
5631        });
5632
5633        cx.spawn(|_, mut cx| async move {
5634            let transaction = futures::select_biased! {
5635                _ = timeout => {
5636                    log::warn!("timed out waiting for formatting");
5637                    None
5638                }
5639                transaction = format.log_err().fuse() => transaction,
5640            };
5641
5642            buffer.update(&mut cx, |buffer, cx| {
5643                if let Some(transaction) = transaction {
5644                    if !buffer.is_singleton() {
5645                        buffer.push_transaction(&transaction.0);
5646                    }
5647                }
5648
5649                cx.notify();
5650            });
5651
5652            Ok(())
5653        })
5654    }
5655
5656    fn restart_language_server(&mut self, _: &RestartLanguageServer, cx: &mut ViewContext<Self>) {
5657        if let Some(project) = self.project.clone() {
5658            self.buffer.update(cx, |multi_buffer, cx| {
5659                project.update(cx, |project, cx| {
5660                    project.restart_language_servers_for_buffers(multi_buffer.all_buffers(), cx);
5661                });
5662            })
5663        }
5664    }
5665
5666    fn show_character_palette(&mut self, _: &ShowCharacterPalette, cx: &mut ViewContext<Self>) {
5667        cx.show_character_palette();
5668    }
5669
5670    fn refresh_active_diagnostics(&mut self, cx: &mut ViewContext<Editor>) {
5671        if let Some(active_diagnostics) = self.active_diagnostics.as_mut() {
5672            let buffer = self.buffer.read(cx).snapshot(cx);
5673            let primary_range_start = active_diagnostics.primary_range.start.to_offset(&buffer);
5674            let is_valid = buffer
5675                .diagnostics_in_range::<_, usize>(active_diagnostics.primary_range.clone(), false)
5676                .any(|entry| {
5677                    entry.diagnostic.is_primary
5678                        && !entry.range.is_empty()
5679                        && entry.range.start == primary_range_start
5680                        && entry.diagnostic.message == active_diagnostics.primary_message
5681                });
5682
5683            if is_valid != active_diagnostics.is_valid {
5684                active_diagnostics.is_valid = is_valid;
5685                let mut new_styles = HashMap::default();
5686                for (block_id, diagnostic) in &active_diagnostics.blocks {
5687                    new_styles.insert(
5688                        *block_id,
5689                        diagnostic_block_renderer(diagnostic.clone(), is_valid),
5690                    );
5691                }
5692                self.display_map
5693                    .update(cx, |display_map, _| display_map.replace_blocks(new_styles));
5694            }
5695        }
5696    }
5697
5698    fn activate_diagnostics(&mut self, group_id: usize, cx: &mut ViewContext<Self>) -> bool {
5699        self.dismiss_diagnostics(cx);
5700        self.active_diagnostics = self.display_map.update(cx, |display_map, cx| {
5701            let buffer = self.buffer.read(cx).snapshot(cx);
5702
5703            let mut primary_range = None;
5704            let mut primary_message = None;
5705            let mut group_end = Point::zero();
5706            let diagnostic_group = buffer
5707                .diagnostic_group::<Point>(group_id)
5708                .map(|entry| {
5709                    if entry.range.end > group_end {
5710                        group_end = entry.range.end;
5711                    }
5712                    if entry.diagnostic.is_primary {
5713                        primary_range = Some(entry.range.clone());
5714                        primary_message = Some(entry.diagnostic.message.clone());
5715                    }
5716                    entry
5717                })
5718                .collect::<Vec<_>>();
5719            let primary_range = primary_range?;
5720            let primary_message = primary_message?;
5721            let primary_range =
5722                buffer.anchor_after(primary_range.start)..buffer.anchor_before(primary_range.end);
5723
5724            let blocks = display_map
5725                .insert_blocks(
5726                    diagnostic_group.iter().map(|entry| {
5727                        let diagnostic = entry.diagnostic.clone();
5728                        let message_height = diagnostic.message.lines().count() as u8;
5729                        BlockProperties {
5730                            style: BlockStyle::Fixed,
5731                            position: buffer.anchor_after(entry.range.start),
5732                            height: message_height,
5733                            render: diagnostic_block_renderer(diagnostic, true),
5734                            disposition: BlockDisposition::Below,
5735                        }
5736                    }),
5737                    cx,
5738                )
5739                .into_iter()
5740                .zip(diagnostic_group.into_iter().map(|entry| entry.diagnostic))
5741                .collect();
5742
5743            Some(ActiveDiagnosticGroup {
5744                primary_range,
5745                primary_message,
5746                blocks,
5747                is_valid: true,
5748            })
5749        });
5750        self.active_diagnostics.is_some()
5751    }
5752
5753    fn dismiss_diagnostics(&mut self, cx: &mut ViewContext<Self>) {
5754        if let Some(active_diagnostic_group) = self.active_diagnostics.take() {
5755            self.display_map.update(cx, |display_map, cx| {
5756                display_map.remove_blocks(active_diagnostic_group.blocks.into_keys().collect(), cx);
5757            });
5758            cx.notify();
5759        }
5760    }
5761
5762    pub fn set_selections_from_remote(
5763        &mut self,
5764        selections: Vec<Selection<Anchor>>,
5765        cx: &mut ViewContext<Self>,
5766    ) {
5767        let old_cursor_position = self.selections.newest_anchor().head();
5768        self.selections.change_with(cx, |s| {
5769            s.select_anchors(selections);
5770        });
5771        self.selections_did_change(false, &old_cursor_position, cx);
5772    }
5773
5774    fn push_to_selection_history(&mut self) {
5775        self.selection_history.push(SelectionHistoryEntry {
5776            selections: self.selections.disjoint_anchors(),
5777            select_next_state: self.select_next_state.clone(),
5778            add_selections_state: self.add_selections_state.clone(),
5779        });
5780    }
5781
5782    pub fn request_autoscroll(&mut self, autoscroll: Autoscroll, cx: &mut ViewContext<Self>) {
5783        self.autoscroll_request = Some((autoscroll, true));
5784        cx.notify();
5785    }
5786
5787    fn request_autoscroll_remotely(&mut self, autoscroll: Autoscroll, cx: &mut ViewContext<Self>) {
5788        self.autoscroll_request = Some((autoscroll, false));
5789        cx.notify();
5790    }
5791
5792    pub fn transact(
5793        &mut self,
5794        cx: &mut ViewContext<Self>,
5795        update: impl FnOnce(&mut Self, &mut ViewContext<Self>),
5796    ) -> Option<TransactionId> {
5797        self.start_transaction_at(Instant::now(), cx);
5798        update(self, cx);
5799        self.end_transaction_at(Instant::now(), cx)
5800    }
5801
5802    fn start_transaction_at(&mut self, now: Instant, cx: &mut ViewContext<Self>) {
5803        self.end_selection(cx);
5804        if let Some(tx_id) = self
5805            .buffer
5806            .update(cx, |buffer, cx| buffer.start_transaction_at(now, cx))
5807        {
5808            self.selection_history
5809                .insert_transaction(tx_id, self.selections.disjoint_anchors());
5810        }
5811    }
5812
5813    fn end_transaction_at(
5814        &mut self,
5815        now: Instant,
5816        cx: &mut ViewContext<Self>,
5817    ) -> Option<TransactionId> {
5818        if let Some(tx_id) = self
5819            .buffer
5820            .update(cx, |buffer, cx| buffer.end_transaction_at(now, cx))
5821        {
5822            if let Some((_, end_selections)) = self.selection_history.transaction_mut(tx_id) {
5823                *end_selections = Some(self.selections.disjoint_anchors());
5824            } else {
5825                log::error!("unexpectedly ended a transaction that wasn't started by this editor");
5826            }
5827
5828            cx.emit(Event::Edited);
5829            Some(tx_id)
5830        } else {
5831            None
5832        }
5833    }
5834
5835    pub fn fold(&mut self, _: &Fold, cx: &mut ViewContext<Self>) {
5836        let mut fold_ranges = Vec::new();
5837
5838        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
5839        let selections = self.selections.all::<Point>(cx);
5840        for selection in selections {
5841            let range = selection.display_range(&display_map).sorted();
5842            let buffer_start_row = range.start.to_point(&display_map).row;
5843
5844            for row in (0..=range.end.row()).rev() {
5845                if self.is_line_foldable(&display_map, row) && !display_map.is_line_folded(row) {
5846                    let fold_range = self.foldable_range_for_line(&display_map, row);
5847                    if fold_range.end.row >= buffer_start_row {
5848                        fold_ranges.push(fold_range);
5849                        if row <= range.start.row() {
5850                            break;
5851                        }
5852                    }
5853                }
5854            }
5855        }
5856
5857        self.fold_ranges(fold_ranges, cx);
5858    }
5859
5860    pub fn unfold_lines(&mut self, _: &UnfoldLines, cx: &mut ViewContext<Self>) {
5861        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
5862        let buffer = &display_map.buffer_snapshot;
5863        let selections = self.selections.all::<Point>(cx);
5864        let ranges = selections
5865            .iter()
5866            .map(|s| {
5867                let range = s.display_range(&display_map).sorted();
5868                let mut start = range.start.to_point(&display_map);
5869                let mut end = range.end.to_point(&display_map);
5870                start.column = 0;
5871                end.column = buffer.line_len(end.row);
5872                start..end
5873            })
5874            .collect::<Vec<_>>();
5875        self.unfold_ranges(ranges, true, cx);
5876    }
5877
5878    fn is_line_foldable(&self, display_map: &DisplaySnapshot, display_row: u32) -> bool {
5879        let max_point = display_map.max_point();
5880        if display_row >= max_point.row() {
5881            false
5882        } else {
5883            let (start_indent, is_blank) = display_map.line_indent(display_row);
5884            if is_blank {
5885                false
5886            } else {
5887                for display_row in display_row + 1..=max_point.row() {
5888                    let (indent, is_blank) = display_map.line_indent(display_row);
5889                    if !is_blank {
5890                        return indent > start_indent;
5891                    }
5892                }
5893                false
5894            }
5895        }
5896    }
5897
5898    fn foldable_range_for_line(
5899        &self,
5900        display_map: &DisplaySnapshot,
5901        start_row: u32,
5902    ) -> Range<Point> {
5903        let max_point = display_map.max_point();
5904
5905        let (start_indent, _) = display_map.line_indent(start_row);
5906        let start = DisplayPoint::new(start_row, display_map.line_len(start_row));
5907        let mut end = None;
5908        for row in start_row + 1..=max_point.row() {
5909            let (indent, is_blank) = display_map.line_indent(row);
5910            if !is_blank && indent <= start_indent {
5911                end = Some(DisplayPoint::new(row - 1, display_map.line_len(row - 1)));
5912                break;
5913            }
5914        }
5915
5916        let end = end.unwrap_or(max_point);
5917        start.to_point(display_map)..end.to_point(display_map)
5918    }
5919
5920    pub fn fold_selected_ranges(&mut self, _: &FoldSelectedRanges, cx: &mut ViewContext<Self>) {
5921        let selections = self.selections.all::<Point>(cx);
5922        let ranges = selections.into_iter().map(|s| s.start..s.end);
5923        self.fold_ranges(ranges, cx);
5924    }
5925
5926    pub fn fold_ranges<T: ToOffset>(
5927        &mut self,
5928        ranges: impl IntoIterator<Item = Range<T>>,
5929        cx: &mut ViewContext<Self>,
5930    ) {
5931        let mut ranges = ranges.into_iter().peekable();
5932        if ranges.peek().is_some() {
5933            self.display_map.update(cx, |map, cx| map.fold(ranges, cx));
5934            self.request_autoscroll(Autoscroll::Fit, cx);
5935            cx.notify();
5936        }
5937    }
5938
5939    pub fn unfold_ranges<T: ToOffset>(
5940        &mut self,
5941        ranges: impl IntoIterator<Item = Range<T>>,
5942        inclusive: bool,
5943        cx: &mut ViewContext<Self>,
5944    ) {
5945        let mut ranges = ranges.into_iter().peekable();
5946        if ranges.peek().is_some() {
5947            self.display_map
5948                .update(cx, |map, cx| map.unfold(ranges, inclusive, cx));
5949            self.request_autoscroll(Autoscroll::Fit, cx);
5950            cx.notify();
5951        }
5952    }
5953
5954    pub fn insert_blocks(
5955        &mut self,
5956        blocks: impl IntoIterator<Item = BlockProperties<Anchor>>,
5957        cx: &mut ViewContext<Self>,
5958    ) -> Vec<BlockId> {
5959        let blocks = self
5960            .display_map
5961            .update(cx, |display_map, cx| display_map.insert_blocks(blocks, cx));
5962        self.request_autoscroll(Autoscroll::Fit, cx);
5963        blocks
5964    }
5965
5966    pub fn replace_blocks(
5967        &mut self,
5968        blocks: HashMap<BlockId, RenderBlock>,
5969        cx: &mut ViewContext<Self>,
5970    ) {
5971        self.display_map
5972            .update(cx, |display_map, _| display_map.replace_blocks(blocks));
5973        self.request_autoscroll(Autoscroll::Fit, cx);
5974    }
5975
5976    pub fn remove_blocks(&mut self, block_ids: HashSet<BlockId>, cx: &mut ViewContext<Self>) {
5977        self.display_map.update(cx, |display_map, cx| {
5978            display_map.remove_blocks(block_ids, cx)
5979        });
5980    }
5981
5982    pub fn longest_row(&self, cx: &mut MutableAppContext) -> u32 {
5983        self.display_map
5984            .update(cx, |map, cx| map.snapshot(cx))
5985            .longest_row()
5986    }
5987
5988    pub fn max_point(&self, cx: &mut MutableAppContext) -> DisplayPoint {
5989        self.display_map
5990            .update(cx, |map, cx| map.snapshot(cx))
5991            .max_point()
5992    }
5993
5994    pub fn text(&self, cx: &AppContext) -> String {
5995        self.buffer.read(cx).read(cx).text()
5996    }
5997
5998    pub fn set_text(&mut self, text: impl Into<Arc<str>>, cx: &mut ViewContext<Self>) {
5999        self.transact(cx, |this, cx| {
6000            this.buffer
6001                .read(cx)
6002                .as_singleton()
6003                .expect("you can only call set_text on editors for singleton buffers")
6004                .update(cx, |buffer, cx| buffer.set_text(text, cx));
6005        });
6006    }
6007
6008    pub fn display_text(&self, cx: &mut MutableAppContext) -> String {
6009        self.display_map
6010            .update(cx, |map, cx| map.snapshot(cx))
6011            .text()
6012    }
6013
6014    pub fn soft_wrap_mode(&self, cx: &AppContext) -> SoftWrap {
6015        let language_name = self
6016            .buffer
6017            .read(cx)
6018            .as_singleton()
6019            .and_then(|singleton_buffer| singleton_buffer.read(cx).language())
6020            .map(|l| l.name());
6021
6022        let settings = cx.global::<Settings>();
6023        let mode = self
6024            .soft_wrap_mode_override
6025            .unwrap_or_else(|| settings.soft_wrap(language_name.as_deref()));
6026        match mode {
6027            settings::SoftWrap::None => SoftWrap::None,
6028            settings::SoftWrap::EditorWidth => SoftWrap::EditorWidth,
6029            settings::SoftWrap::PreferredLineLength => {
6030                SoftWrap::Column(settings.preferred_line_length(language_name.as_deref()))
6031            }
6032        }
6033    }
6034
6035    pub fn set_soft_wrap_mode(&mut self, mode: settings::SoftWrap, cx: &mut ViewContext<Self>) {
6036        self.soft_wrap_mode_override = Some(mode);
6037        cx.notify();
6038    }
6039
6040    pub fn set_wrap_width(&self, width: Option<f32>, cx: &mut MutableAppContext) -> bool {
6041        self.display_map
6042            .update(cx, |map, cx| map.set_wrap_width(width, cx))
6043    }
6044
6045    pub fn highlight_rows(&mut self, rows: Option<Range<u32>>) {
6046        self.highlighted_rows = rows;
6047    }
6048
6049    pub fn highlighted_rows(&self) -> Option<Range<u32>> {
6050        self.highlighted_rows.clone()
6051    }
6052
6053    pub fn highlight_background<T: 'static>(
6054        &mut self,
6055        ranges: Vec<Range<Anchor>>,
6056        color_fetcher: fn(&Theme) -> Color,
6057        cx: &mut ViewContext<Self>,
6058    ) {
6059        self.background_highlights
6060            .insert(TypeId::of::<T>(), (color_fetcher, ranges));
6061        cx.notify();
6062    }
6063
6064    #[allow(clippy::type_complexity)]
6065    pub fn clear_background_highlights<T: 'static>(
6066        &mut self,
6067        cx: &mut ViewContext<Self>,
6068    ) -> Option<(fn(&Theme) -> Color, Vec<Range<Anchor>>)> {
6069        let highlights = self.background_highlights.remove(&TypeId::of::<T>());
6070        if highlights.is_some() {
6071            cx.notify();
6072        }
6073        highlights
6074    }
6075
6076    #[cfg(feature = "test-support")]
6077    pub fn all_background_highlights(
6078        &mut self,
6079        cx: &mut ViewContext<Self>,
6080    ) -> Vec<(Range<DisplayPoint>, Color)> {
6081        let snapshot = self.snapshot(cx);
6082        let buffer = &snapshot.buffer_snapshot;
6083        let start = buffer.anchor_before(0);
6084        let end = buffer.anchor_after(buffer.len());
6085        let theme = cx.global::<Settings>().theme.as_ref();
6086        self.background_highlights_in_range(start..end, &snapshot, theme)
6087    }
6088
6089    fn document_highlights_for_position<'a>(
6090        &'a self,
6091        position: Anchor,
6092        buffer: &'a MultiBufferSnapshot,
6093    ) -> impl 'a + Iterator<Item = &Range<Anchor>> {
6094        let read_highlights = self
6095            .background_highlights
6096            .get(&TypeId::of::<DocumentHighlightRead>())
6097            .map(|h| &h.1);
6098        let write_highlights = self
6099            .background_highlights
6100            .get(&TypeId::of::<DocumentHighlightWrite>())
6101            .map(|h| &h.1);
6102        let left_position = position.bias_left(buffer);
6103        let right_position = position.bias_right(buffer);
6104        read_highlights
6105            .into_iter()
6106            .chain(write_highlights)
6107            .flat_map(move |ranges| {
6108                let start_ix = match ranges.binary_search_by(|probe| {
6109                    let cmp = probe.end.cmp(&left_position, buffer);
6110                    if cmp.is_ge() {
6111                        Ordering::Greater
6112                    } else {
6113                        Ordering::Less
6114                    }
6115                }) {
6116                    Ok(i) | Err(i) => i,
6117                };
6118
6119                let right_position = right_position.clone();
6120                ranges[start_ix..]
6121                    .iter()
6122                    .take_while(move |range| range.start.cmp(&right_position, buffer).is_le())
6123            })
6124    }
6125
6126    pub fn background_highlights_in_range(
6127        &self,
6128        search_range: Range<Anchor>,
6129        display_snapshot: &DisplaySnapshot,
6130        theme: &Theme,
6131    ) -> Vec<(Range<DisplayPoint>, Color)> {
6132        let mut results = Vec::new();
6133        let buffer = &display_snapshot.buffer_snapshot;
6134        for (color_fetcher, ranges) in self.background_highlights.values() {
6135            let color = color_fetcher(theme);
6136            let start_ix = match ranges.binary_search_by(|probe| {
6137                let cmp = probe.end.cmp(&search_range.start, buffer);
6138                if cmp.is_gt() {
6139                    Ordering::Greater
6140                } else {
6141                    Ordering::Less
6142                }
6143            }) {
6144                Ok(i) | Err(i) => i,
6145            };
6146            for range in &ranges[start_ix..] {
6147                if range.start.cmp(&search_range.end, buffer).is_ge() {
6148                    break;
6149                }
6150                let start = range
6151                    .start
6152                    .to_point(buffer)
6153                    .to_display_point(display_snapshot);
6154                let end = range
6155                    .end
6156                    .to_point(buffer)
6157                    .to_display_point(display_snapshot);
6158                results.push((start..end, color))
6159            }
6160        }
6161        results
6162    }
6163
6164    pub fn highlight_text<T: 'static>(
6165        &mut self,
6166        ranges: Vec<Range<Anchor>>,
6167        style: HighlightStyle,
6168        cx: &mut ViewContext<Self>,
6169    ) {
6170        self.display_map.update(cx, |map, _| {
6171            map.highlight_text(TypeId::of::<T>(), ranges, style)
6172        });
6173        cx.notify();
6174    }
6175
6176    pub fn text_highlights<'a, T: 'static>(
6177        &'a self,
6178        cx: &'a AppContext,
6179    ) -> Option<(HighlightStyle, &'a [Range<Anchor>])> {
6180        self.display_map.read(cx).text_highlights(TypeId::of::<T>())
6181    }
6182
6183    pub fn clear_text_highlights<T: 'static>(
6184        &mut self,
6185        cx: &mut ViewContext<Self>,
6186    ) -> Option<Arc<(HighlightStyle, Vec<Range<Anchor>>)>> {
6187        let highlights = self
6188            .display_map
6189            .update(cx, |map, _| map.clear_text_highlights(TypeId::of::<T>()));
6190        if highlights.is_some() {
6191            cx.notify();
6192        }
6193        highlights
6194    }
6195
6196    pub fn show_local_cursors(&self, cx: &AppContext) -> bool {
6197        self.blink_manager.read(cx).visible() && self.focused
6198    }
6199
6200    pub fn show_scrollbars(&self) -> bool {
6201        self.show_scrollbars
6202    }
6203
6204    fn make_scrollbar_visible(&mut self, cx: &mut ViewContext<Self>) {
6205        if !self.show_scrollbars {
6206            self.show_scrollbars = true;
6207            cx.notify();
6208        }
6209
6210        if cx.default_global::<ScrollbarAutoHide>().0 {
6211            self.hide_scrollbar_task = Some(cx.spawn_weak(|this, mut cx| async move {
6212                Timer::after(SCROLLBAR_SHOW_INTERVAL).await;
6213                if let Some(this) = this.upgrade(&cx) {
6214                    this.update(&mut cx, |this, cx| {
6215                        this.show_scrollbars = false;
6216                        cx.notify();
6217                    });
6218                }
6219            }));
6220        } else {
6221            self.hide_scrollbar_task = None;
6222        }
6223    }
6224
6225    fn on_buffer_changed(&mut self, _: ModelHandle<MultiBuffer>, cx: &mut ViewContext<Self>) {
6226        cx.notify();
6227    }
6228
6229    fn on_buffer_event(
6230        &mut self,
6231        _: ModelHandle<MultiBuffer>,
6232        event: &language::Event,
6233        cx: &mut ViewContext<Self>,
6234    ) {
6235        match event {
6236            language::Event::Edited => {
6237                self.refresh_active_diagnostics(cx);
6238                self.refresh_code_actions(cx);
6239                cx.emit(Event::BufferEdited);
6240            }
6241            language::Event::Reparsed => cx.emit(Event::Reparsed),
6242            language::Event::DirtyChanged => cx.emit(Event::DirtyChanged),
6243            language::Event::Saved => cx.emit(Event::Saved),
6244            language::Event::FileHandleChanged => cx.emit(Event::TitleChanged),
6245            language::Event::Reloaded => cx.emit(Event::TitleChanged),
6246            language::Event::Closed => cx.emit(Event::Closed),
6247            language::Event::DiagnosticsUpdated => {
6248                self.refresh_active_diagnostics(cx);
6249            }
6250            _ => {}
6251        }
6252    }
6253
6254    fn on_display_map_changed(&mut self, _: ModelHandle<DisplayMap>, cx: &mut ViewContext<Self>) {
6255        cx.notify();
6256    }
6257
6258    pub fn set_searchable(&mut self, searchable: bool) {
6259        self.searchable = searchable;
6260    }
6261
6262    pub fn searchable(&self) -> bool {
6263        self.searchable
6264    }
6265
6266    fn open_excerpts(workspace: &mut Workspace, _: &OpenExcerpts, cx: &mut ViewContext<Workspace>) {
6267        let active_item = workspace.active_item(cx);
6268        let editor_handle = if let Some(editor) = active_item
6269            .as_ref()
6270            .and_then(|item| item.act_as::<Self>(cx))
6271        {
6272            editor
6273        } else {
6274            cx.propagate_action();
6275            return;
6276        };
6277
6278        let editor = editor_handle.read(cx);
6279        let buffer = editor.buffer.read(cx);
6280        if buffer.is_singleton() {
6281            cx.propagate_action();
6282            return;
6283        }
6284
6285        let mut new_selections_by_buffer = HashMap::default();
6286        for selection in editor.selections.all::<usize>(cx) {
6287            for (buffer, mut range) in
6288                buffer.range_to_buffer_ranges(selection.start..selection.end, cx)
6289            {
6290                if selection.reversed {
6291                    mem::swap(&mut range.start, &mut range.end);
6292                }
6293                new_selections_by_buffer
6294                    .entry(buffer)
6295                    .or_insert(Vec::new())
6296                    .push(range)
6297            }
6298        }
6299
6300        editor_handle.update(cx, |editor, cx| {
6301            editor.push_to_nav_history(editor.selections.newest_anchor().head(), None, cx);
6302        });
6303        let pane = workspace.active_pane().clone();
6304        pane.update(cx, |pane, _| pane.disable_history());
6305
6306        // We defer the pane interaction because we ourselves are a workspace item
6307        // and activating a new item causes the pane to call a method on us reentrantly,
6308        // which panics if we're on the stack.
6309        cx.defer(move |workspace, cx| {
6310            for (buffer, ranges) in new_selections_by_buffer.into_iter() {
6311                let editor = workspace.open_project_item::<Self>(buffer, cx);
6312                editor.update(cx, |editor, cx| {
6313                    editor.change_selections(Some(Autoscroll::Newest), cx, |s| {
6314                        s.select_ranges(ranges);
6315                    });
6316                });
6317            }
6318
6319            pane.update(cx, |pane, _| pane.enable_history());
6320        });
6321    }
6322
6323    fn jump(workspace: &mut Workspace, action: &Jump, cx: &mut ViewContext<Workspace>) {
6324        let editor = workspace.open_path(action.path.clone(), true, cx);
6325        let position = action.position;
6326        let anchor = action.anchor;
6327        cx.spawn_weak(|_, mut cx| async move {
6328            let editor = editor.await.log_err()?.downcast::<Editor>()?;
6329            editor.update(&mut cx, |editor, cx| {
6330                let buffer = editor.buffer().read(cx).as_singleton()?;
6331                let buffer = buffer.read(cx);
6332                let cursor = if buffer.can_resolve(&anchor) {
6333                    language::ToPoint::to_point(&anchor, buffer)
6334                } else {
6335                    buffer.clip_point(position, Bias::Left)
6336                };
6337
6338                let nav_history = editor.nav_history.take();
6339                editor.change_selections(Some(Autoscroll::Newest), cx, |s| {
6340                    s.select_ranges([cursor..cursor]);
6341                });
6342                editor.nav_history = nav_history;
6343
6344                Some(())
6345            })?;
6346            Some(())
6347        })
6348        .detach()
6349    }
6350
6351    fn marked_text_ranges(&self, cx: &AppContext) -> Option<Vec<Range<OffsetUtf16>>> {
6352        let snapshot = self.buffer.read(cx).read(cx);
6353        let (_, ranges) = self.text_highlights::<InputComposition>(cx)?;
6354        Some(
6355            ranges
6356                .iter()
6357                .map(move |range| {
6358                    range.start.to_offset_utf16(&snapshot)..range.end.to_offset_utf16(&snapshot)
6359                })
6360                .collect(),
6361        )
6362    }
6363
6364    fn selection_replacement_ranges(
6365        &self,
6366        range: Range<OffsetUtf16>,
6367        cx: &AppContext,
6368    ) -> Vec<Range<OffsetUtf16>> {
6369        let selections = self.selections.all::<OffsetUtf16>(cx);
6370        let newest_selection = selections
6371            .iter()
6372            .max_by_key(|selection| selection.id)
6373            .unwrap();
6374        let start_delta = range.start.0 as isize - newest_selection.start.0 as isize;
6375        let end_delta = range.end.0 as isize - newest_selection.end.0 as isize;
6376        let snapshot = self.buffer.read(cx).read(cx);
6377        selections
6378            .into_iter()
6379            .map(|mut selection| {
6380                selection.start.0 =
6381                    (selection.start.0 as isize).saturating_add(start_delta) as usize;
6382                selection.end.0 = (selection.end.0 as isize).saturating_add(end_delta) as usize;
6383                snapshot.clip_offset_utf16(selection.start, Bias::Left)
6384                    ..snapshot.clip_offset_utf16(selection.end, Bias::Right)
6385            })
6386            .collect()
6387    }
6388
6389    fn report_event(&self, name: &str, cx: &AppContext) {
6390        if let Some((project, file)) = self.project.as_ref().zip(
6391            self.buffer
6392                .read(cx)
6393                .as_singleton()
6394                .and_then(|b| b.read(cx).file()),
6395        ) {
6396            project.read(cx).client().report_event(
6397                name,
6398                json!({
6399                    "file_extension": file
6400                        .path()
6401                        .extension()
6402                        .and_then(|e| e.to_str())
6403                }),
6404            );
6405        }
6406    }
6407}
6408
6409impl EditorSnapshot {
6410    pub fn language_at<T: ToOffset>(&self, position: T) -> Option<&Arc<Language>> {
6411        self.display_snapshot.buffer_snapshot.language_at(position)
6412    }
6413
6414    pub fn is_focused(&self) -> bool {
6415        self.is_focused
6416    }
6417
6418    pub fn placeholder_text(&self) -> Option<&Arc<str>> {
6419        self.placeholder_text.as_ref()
6420    }
6421
6422    pub fn scroll_position(&self) -> Vector2F {
6423        compute_scroll_position(
6424            &self.display_snapshot,
6425            self.scroll_position,
6426            &self.scroll_top_anchor,
6427        )
6428    }
6429}
6430
6431impl Deref for EditorSnapshot {
6432    type Target = DisplaySnapshot;
6433
6434    fn deref(&self) -> &Self::Target {
6435        &self.display_snapshot
6436    }
6437}
6438
6439fn compute_scroll_position(
6440    snapshot: &DisplaySnapshot,
6441    mut scroll_position: Vector2F,
6442    scroll_top_anchor: &Anchor,
6443) -> Vector2F {
6444    if *scroll_top_anchor != Anchor::min() {
6445        let scroll_top = scroll_top_anchor.to_display_point(snapshot).row() as f32;
6446        scroll_position.set_y(scroll_top + scroll_position.y());
6447    } else {
6448        scroll_position.set_y(0.);
6449    }
6450    scroll_position
6451}
6452
6453#[derive(Copy, Clone, Debug, PartialEq, Eq)]
6454pub enum Event {
6455    BufferEdited,
6456    Edited,
6457    Reparsed,
6458    Blurred,
6459    DirtyChanged,
6460    Saved,
6461    TitleChanged,
6462    SelectionsChanged { local: bool },
6463    ScrollPositionChanged { local: bool },
6464    Closed,
6465    IgnoredInput,
6466}
6467
6468pub struct EditorFocused(pub ViewHandle<Editor>);
6469pub struct EditorBlurred(pub ViewHandle<Editor>);
6470pub struct EditorReleased(pub WeakViewHandle<Editor>);
6471
6472impl Entity for Editor {
6473    type Event = Event;
6474
6475    fn release(&mut self, cx: &mut MutableAppContext) {
6476        cx.emit_global(EditorReleased(self.handle.clone()));
6477    }
6478}
6479
6480impl View for Editor {
6481    fn render(&mut self, cx: &mut RenderContext<Self>) -> ElementBox {
6482        let style = self.style(cx);
6483        let font_changed = self.display_map.update(cx, |map, cx| {
6484            map.set_font(style.text.font_id, style.text.font_size, cx)
6485        });
6486
6487        if font_changed {
6488            let handle = self.handle.clone();
6489            cx.defer(move |cx| {
6490                if let Some(editor) = handle.upgrade(cx) {
6491                    editor.update(cx, |editor, cx| {
6492                        hide_hover(editor, cx);
6493                        hide_link_definition(editor, cx);
6494                    })
6495                }
6496            });
6497        }
6498
6499        Stack::new()
6500            .with_child(EditorElement::new(self.handle.clone(), style.clone()).boxed())
6501            .with_child(ChildView::new(&self.mouse_context_menu, cx).boxed())
6502            .boxed()
6503    }
6504
6505    fn ui_name() -> &'static str {
6506        "Editor"
6507    }
6508
6509    fn focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext<Self>) {
6510        let focused_event = EditorFocused(cx.handle());
6511        cx.emit_global(focused_event);
6512        if let Some(rename) = self.pending_rename.as_ref() {
6513            cx.focus(&rename.editor);
6514        } else {
6515            if !self.focused {
6516                self.blink_manager.update(cx, BlinkManager::enable);
6517            }
6518            self.focused = true;
6519            self.buffer.update(cx, |buffer, cx| {
6520                buffer.finalize_last_transaction(cx);
6521                if self.leader_replica_id.is_none() {
6522                    buffer.set_active_selections(
6523                        &self.selections.disjoint_anchors(),
6524                        self.selections.line_mode,
6525                        self.cursor_shape,
6526                        cx,
6527                    );
6528                }
6529            });
6530        }
6531    }
6532
6533    fn focus_out(&mut self, _: AnyViewHandle, cx: &mut ViewContext<Self>) {
6534        let blurred_event = EditorBlurred(cx.handle());
6535        cx.emit_global(blurred_event);
6536        self.focused = false;
6537        self.blink_manager.update(cx, BlinkManager::disable);
6538        self.buffer
6539            .update(cx, |buffer, cx| buffer.remove_active_selections(cx));
6540        self.hide_context_menu(cx);
6541        hide_hover(self, cx);
6542        cx.emit(Event::Blurred);
6543        cx.notify();
6544    }
6545
6546    fn modifiers_changed(
6547        &mut self,
6548        event: &gpui::ModifiersChangedEvent,
6549        cx: &mut ViewContext<Self>,
6550    ) -> bool {
6551        let pending_selection = self.has_pending_selection();
6552
6553        if let Some(point) = self.link_go_to_definition_state.last_mouse_location.clone() {
6554            if event.cmd && !pending_selection {
6555                let snapshot = self.snapshot(cx);
6556                let kind = if event.shift {
6557                    LinkDefinitionKind::Type
6558                } else {
6559                    LinkDefinitionKind::Symbol
6560                };
6561
6562                show_link_definition(kind, self, point, snapshot, cx);
6563                return false;
6564            }
6565        }
6566
6567        {
6568            if self.link_go_to_definition_state.symbol_range.is_some()
6569                || !self.link_go_to_definition_state.definitions.is_empty()
6570            {
6571                self.link_go_to_definition_state.symbol_range.take();
6572                self.link_go_to_definition_state.definitions.clear();
6573                cx.notify();
6574            }
6575
6576            self.link_go_to_definition_state.task = None;
6577
6578            self.clear_text_highlights::<LinkGoToDefinitionState>(cx);
6579        }
6580
6581        false
6582    }
6583
6584    fn keymap_context(&self, _: &AppContext) -> gpui::keymap::Context {
6585        let mut context = Self::default_keymap_context();
6586        let mode = match self.mode {
6587            EditorMode::SingleLine => "single_line",
6588            EditorMode::AutoHeight { .. } => "auto_height",
6589            EditorMode::Full => "full",
6590        };
6591        context.map.insert("mode".into(), mode.into());
6592        if self.pending_rename.is_some() {
6593            context.set.insert("renaming".into());
6594        }
6595        match self.context_menu.as_ref() {
6596            Some(ContextMenu::Completions(_)) => {
6597                context.set.insert("showing_completions".into());
6598            }
6599            Some(ContextMenu::CodeActions(_)) => {
6600                context.set.insert("showing_code_actions".into());
6601            }
6602            None => {}
6603        }
6604
6605        for layer in self.keymap_context_layers.values() {
6606            context.extend(layer);
6607        }
6608
6609        context
6610    }
6611
6612    fn text_for_range(&self, range_utf16: Range<usize>, cx: &AppContext) -> Option<String> {
6613        Some(
6614            self.buffer
6615                .read(cx)
6616                .read(cx)
6617                .text_for_range(OffsetUtf16(range_utf16.start)..OffsetUtf16(range_utf16.end))
6618                .collect(),
6619        )
6620    }
6621
6622    fn selected_text_range(&self, cx: &AppContext) -> Option<Range<usize>> {
6623        // Prevent the IME menu from appearing when holding down an alphabetic key
6624        // while input is disabled.
6625        if !self.input_enabled {
6626            return None;
6627        }
6628
6629        let range = self.selections.newest::<OffsetUtf16>(cx).range();
6630        Some(range.start.0..range.end.0)
6631    }
6632
6633    fn marked_text_range(&self, cx: &AppContext) -> Option<Range<usize>> {
6634        let snapshot = self.buffer.read(cx).read(cx);
6635        let range = self.text_highlights::<InputComposition>(cx)?.1.get(0)?;
6636        Some(range.start.to_offset_utf16(&snapshot).0..range.end.to_offset_utf16(&snapshot).0)
6637    }
6638
6639    fn unmark_text(&mut self, cx: &mut ViewContext<Self>) {
6640        self.clear_text_highlights::<InputComposition>(cx);
6641        self.ime_transaction.take();
6642    }
6643
6644    fn replace_text_in_range(
6645        &mut self,
6646        range_utf16: Option<Range<usize>>,
6647        text: &str,
6648        cx: &mut ViewContext<Self>,
6649    ) {
6650        if !self.input_enabled {
6651            cx.emit(Event::IgnoredInput);
6652            return;
6653        }
6654
6655        self.transact(cx, |this, cx| {
6656            let new_selected_ranges = if let Some(range_utf16) = range_utf16 {
6657                let range_utf16 = OffsetUtf16(range_utf16.start)..OffsetUtf16(range_utf16.end);
6658                Some(this.selection_replacement_ranges(range_utf16, cx))
6659            } else {
6660                this.marked_text_ranges(cx)
6661            };
6662
6663            if let Some(new_selected_ranges) = new_selected_ranges {
6664                this.change_selections(None, cx, |selections| {
6665                    selections.select_ranges(new_selected_ranges)
6666                });
6667            }
6668            this.handle_input(text, cx);
6669        });
6670
6671        if let Some(transaction) = self.ime_transaction {
6672            self.buffer.update(cx, |buffer, cx| {
6673                buffer.group_until_transaction(transaction, cx);
6674            });
6675        }
6676
6677        self.unmark_text(cx);
6678    }
6679
6680    fn replace_and_mark_text_in_range(
6681        &mut self,
6682        range_utf16: Option<Range<usize>>,
6683        text: &str,
6684        new_selected_range_utf16: Option<Range<usize>>,
6685        cx: &mut ViewContext<Self>,
6686    ) {
6687        if !self.input_enabled {
6688            cx.emit(Event::IgnoredInput);
6689            return;
6690        }
6691
6692        let transaction = self.transact(cx, |this, cx| {
6693            let ranges_to_replace = if let Some(mut marked_ranges) = this.marked_text_ranges(cx) {
6694                let snapshot = this.buffer.read(cx).read(cx);
6695                if let Some(relative_range_utf16) = range_utf16.as_ref() {
6696                    for marked_range in &mut marked_ranges {
6697                        marked_range.end.0 = marked_range.start.0 + relative_range_utf16.end;
6698                        marked_range.start.0 += relative_range_utf16.start;
6699                        marked_range.start =
6700                            snapshot.clip_offset_utf16(marked_range.start, Bias::Left);
6701                        marked_range.end =
6702                            snapshot.clip_offset_utf16(marked_range.end, Bias::Right);
6703                    }
6704                }
6705                Some(marked_ranges)
6706            } else if let Some(range_utf16) = range_utf16 {
6707                let range_utf16 = OffsetUtf16(range_utf16.start)..OffsetUtf16(range_utf16.end);
6708                Some(this.selection_replacement_ranges(range_utf16, cx))
6709            } else {
6710                None
6711            };
6712
6713            if let Some(ranges) = ranges_to_replace {
6714                this.change_selections(None, cx, |s| s.select_ranges(ranges));
6715            }
6716
6717            let marked_ranges = {
6718                let snapshot = this.buffer.read(cx).read(cx);
6719                this.selections
6720                    .disjoint_anchors()
6721                    .iter()
6722                    .map(|selection| {
6723                        selection.start.bias_left(&*snapshot)..selection.end.bias_right(&*snapshot)
6724                    })
6725                    .collect::<Vec<_>>()
6726            };
6727
6728            if text.is_empty() {
6729                this.unmark_text(cx);
6730            } else {
6731                this.highlight_text::<InputComposition>(
6732                    marked_ranges.clone(),
6733                    this.style(cx).composition_mark,
6734                    cx,
6735                );
6736            }
6737
6738            this.handle_input(text, cx);
6739
6740            if let Some(new_selected_range) = new_selected_range_utf16 {
6741                let snapshot = this.buffer.read(cx).read(cx);
6742                let new_selected_ranges = marked_ranges
6743                    .into_iter()
6744                    .map(|marked_range| {
6745                        let insertion_start = marked_range.start.to_offset_utf16(&snapshot).0;
6746                        let new_start = OffsetUtf16(new_selected_range.start + insertion_start);
6747                        let new_end = OffsetUtf16(new_selected_range.end + insertion_start);
6748                        snapshot.clip_offset_utf16(new_start, Bias::Left)
6749                            ..snapshot.clip_offset_utf16(new_end, Bias::Right)
6750                    })
6751                    .collect::<Vec<_>>();
6752
6753                drop(snapshot);
6754                this.change_selections(None, cx, |selections| {
6755                    selections.select_ranges(new_selected_ranges)
6756                });
6757            }
6758        });
6759
6760        self.ime_transaction = self.ime_transaction.or(transaction);
6761        if let Some(transaction) = self.ime_transaction {
6762            self.buffer.update(cx, |buffer, cx| {
6763                buffer.group_until_transaction(transaction, cx);
6764            });
6765        }
6766
6767        if self.text_highlights::<InputComposition>(cx).is_none() {
6768            self.ime_transaction.take();
6769        }
6770    }
6771}
6772
6773fn build_style(
6774    settings: &Settings,
6775    get_field_editor_theme: Option<GetFieldEditorTheme>,
6776    override_text_style: Option<&OverrideTextStyle>,
6777    cx: &AppContext,
6778) -> EditorStyle {
6779    let font_cache = cx.font_cache();
6780
6781    let mut theme = settings.theme.editor.clone();
6782    let mut style = if let Some(get_field_editor_theme) = get_field_editor_theme {
6783        let field_editor_theme = get_field_editor_theme(&settings.theme);
6784        theme.text_color = field_editor_theme.text.color;
6785        theme.selection = field_editor_theme.selection;
6786        theme.background = field_editor_theme
6787            .container
6788            .background_color
6789            .unwrap_or_default();
6790        EditorStyle {
6791            text: field_editor_theme.text,
6792            placeholder_text: field_editor_theme.placeholder_text,
6793            theme,
6794        }
6795    } else {
6796        let font_family_id = settings.buffer_font_family;
6797        let font_family_name = cx.font_cache().family_name(font_family_id).unwrap();
6798        let font_properties = Default::default();
6799        let font_id = font_cache
6800            .select_font(font_family_id, &font_properties)
6801            .unwrap();
6802        let font_size = settings.buffer_font_size;
6803        EditorStyle {
6804            text: TextStyle {
6805                color: settings.theme.editor.text_color,
6806                font_family_name,
6807                font_family_id,
6808                font_id,
6809                font_size,
6810                font_properties,
6811                underline: Default::default(),
6812            },
6813            placeholder_text: None,
6814            theme,
6815        }
6816    };
6817
6818    if let Some(highlight_style) = override_text_style.and_then(|build_style| build_style(&style)) {
6819        if let Some(highlighted) = style
6820            .text
6821            .clone()
6822            .highlight(highlight_style, font_cache)
6823            .log_err()
6824        {
6825            style.text = highlighted;
6826        }
6827    }
6828
6829    style
6830}
6831
6832trait SelectionExt {
6833    fn offset_range(&self, buffer: &MultiBufferSnapshot) -> Range<usize>;
6834    fn point_range(&self, buffer: &MultiBufferSnapshot) -> Range<Point>;
6835    fn display_range(&self, map: &DisplaySnapshot) -> Range<DisplayPoint>;
6836    fn spanned_rows(&self, include_end_if_at_line_start: bool, map: &DisplaySnapshot)
6837        -> Range<u32>;
6838}
6839
6840impl<T: ToPoint + ToOffset> SelectionExt for Selection<T> {
6841    fn point_range(&self, buffer: &MultiBufferSnapshot) -> Range<Point> {
6842        let start = self.start.to_point(buffer);
6843        let end = self.end.to_point(buffer);
6844        if self.reversed {
6845            end..start
6846        } else {
6847            start..end
6848        }
6849    }
6850
6851    fn offset_range(&self, buffer: &MultiBufferSnapshot) -> Range<usize> {
6852        let start = self.start.to_offset(buffer);
6853        let end = self.end.to_offset(buffer);
6854        if self.reversed {
6855            end..start
6856        } else {
6857            start..end
6858        }
6859    }
6860
6861    fn display_range(&self, map: &DisplaySnapshot) -> Range<DisplayPoint> {
6862        let start = self
6863            .start
6864            .to_point(&map.buffer_snapshot)
6865            .to_display_point(map);
6866        let end = self
6867            .end
6868            .to_point(&map.buffer_snapshot)
6869            .to_display_point(map);
6870        if self.reversed {
6871            end..start
6872        } else {
6873            start..end
6874        }
6875    }
6876
6877    fn spanned_rows(
6878        &self,
6879        include_end_if_at_line_start: bool,
6880        map: &DisplaySnapshot,
6881    ) -> Range<u32> {
6882        let start = self.start.to_point(&map.buffer_snapshot);
6883        let mut end = self.end.to_point(&map.buffer_snapshot);
6884        if !include_end_if_at_line_start && start.row != end.row && end.column == 0 {
6885            end.row -= 1;
6886        }
6887
6888        let buffer_start = map.prev_line_boundary(start).0;
6889        let buffer_end = map.next_line_boundary(end).0;
6890        buffer_start.row..buffer_end.row + 1
6891    }
6892}
6893
6894impl<T: InvalidationRegion> InvalidationStack<T> {
6895    fn invalidate<S>(&mut self, selections: &[Selection<S>], buffer: &MultiBufferSnapshot)
6896    where
6897        S: Clone + ToOffset,
6898    {
6899        while let Some(region) = self.last() {
6900            let all_selections_inside_invalidation_ranges =
6901                if selections.len() == region.ranges().len() {
6902                    selections
6903                        .iter()
6904                        .zip(region.ranges().iter().map(|r| r.to_offset(buffer)))
6905                        .all(|(selection, invalidation_range)| {
6906                            let head = selection.head().to_offset(buffer);
6907                            invalidation_range.start <= head && invalidation_range.end >= head
6908                        })
6909                } else {
6910                    false
6911                };
6912
6913            if all_selections_inside_invalidation_ranges {
6914                break;
6915            } else {
6916                self.pop();
6917            }
6918        }
6919    }
6920}
6921
6922impl<T> Default for InvalidationStack<T> {
6923    fn default() -> Self {
6924        Self(Default::default())
6925    }
6926}
6927
6928impl<T> Deref for InvalidationStack<T> {
6929    type Target = Vec<T>;
6930
6931    fn deref(&self) -> &Self::Target {
6932        &self.0
6933    }
6934}
6935
6936impl<T> DerefMut for InvalidationStack<T> {
6937    fn deref_mut(&mut self) -> &mut Self::Target {
6938        &mut self.0
6939    }
6940}
6941
6942impl InvalidationRegion for SnippetState {
6943    fn ranges(&self) -> &[Range<Anchor>] {
6944        &self.ranges[self.active_index]
6945    }
6946}
6947
6948impl Deref for EditorStyle {
6949    type Target = theme::Editor;
6950
6951    fn deref(&self) -> &Self::Target {
6952        &self.theme
6953    }
6954}
6955
6956pub fn diagnostic_block_renderer(diagnostic: Diagnostic, is_valid: bool) -> RenderBlock {
6957    let mut highlighted_lines = Vec::new();
6958    for line in diagnostic.message.lines() {
6959        highlighted_lines.push(highlight_diagnostic_message(line));
6960    }
6961
6962    Arc::new(move |cx: &mut BlockContext| {
6963        let settings = cx.global::<Settings>();
6964        let theme = &settings.theme.editor;
6965        let style = diagnostic_style(diagnostic.severity, is_valid, theme);
6966        let font_size = (style.text_scale_factor * settings.buffer_font_size).round();
6967        Flex::column()
6968            .with_children(highlighted_lines.iter().map(|(line, highlights)| {
6969                Label::new(
6970                    line.clone(),
6971                    style.message.clone().with_font_size(font_size),
6972                )
6973                .with_highlights(highlights.clone())
6974                .contained()
6975                .with_margin_left(cx.anchor_x)
6976                .boxed()
6977            }))
6978            .aligned()
6979            .left()
6980            .boxed()
6981    })
6982}
6983
6984pub fn highlight_diagnostic_message(message: &str) -> (String, Vec<usize>) {
6985    let mut message_without_backticks = String::new();
6986    let mut prev_offset = 0;
6987    let mut inside_block = false;
6988    let mut highlights = Vec::new();
6989    for (match_ix, (offset, _)) in message
6990        .match_indices('`')
6991        .chain([(message.len(), "")])
6992        .enumerate()
6993    {
6994        message_without_backticks.push_str(&message[prev_offset..offset]);
6995        if inside_block {
6996            highlights.extend(prev_offset - match_ix..offset - match_ix);
6997        }
6998
6999        inside_block = !inside_block;
7000        prev_offset = offset + 1;
7001    }
7002
7003    (message_without_backticks, highlights)
7004}
7005
7006pub fn diagnostic_style(
7007    severity: DiagnosticSeverity,
7008    valid: bool,
7009    theme: &theme::Editor,
7010) -> DiagnosticStyle {
7011    match (severity, valid) {
7012        (DiagnosticSeverity::ERROR, true) => theme.error_diagnostic.clone(),
7013        (DiagnosticSeverity::ERROR, false) => theme.invalid_error_diagnostic.clone(),
7014        (DiagnosticSeverity::WARNING, true) => theme.warning_diagnostic.clone(),
7015        (DiagnosticSeverity::WARNING, false) => theme.invalid_warning_diagnostic.clone(),
7016        (DiagnosticSeverity::INFORMATION, true) => theme.information_diagnostic.clone(),
7017        (DiagnosticSeverity::INFORMATION, false) => theme.invalid_information_diagnostic.clone(),
7018        (DiagnosticSeverity::HINT, true) => theme.hint_diagnostic.clone(),
7019        (DiagnosticSeverity::HINT, false) => theme.invalid_hint_diagnostic.clone(),
7020        _ => theme.invalid_hint_diagnostic.clone(),
7021    }
7022}
7023
7024pub fn combine_syntax_and_fuzzy_match_highlights(
7025    text: &str,
7026    default_style: HighlightStyle,
7027    syntax_ranges: impl Iterator<Item = (Range<usize>, HighlightStyle)>,
7028    match_indices: &[usize],
7029) -> Vec<(Range<usize>, HighlightStyle)> {
7030    let mut result = Vec::new();
7031    let mut match_indices = match_indices.iter().copied().peekable();
7032
7033    for (range, mut syntax_highlight) in syntax_ranges.chain([(usize::MAX..0, Default::default())])
7034    {
7035        syntax_highlight.weight = None;
7036
7037        // Add highlights for any fuzzy match characters before the next
7038        // syntax highlight range.
7039        while let Some(&match_index) = match_indices.peek() {
7040            if match_index >= range.start {
7041                break;
7042            }
7043            match_indices.next();
7044            let end_index = char_ix_after(match_index, text);
7045            let mut match_style = default_style;
7046            match_style.weight = Some(fonts::Weight::BOLD);
7047            result.push((match_index..end_index, match_style));
7048        }
7049
7050        if range.start == usize::MAX {
7051            break;
7052        }
7053
7054        // Add highlights for any fuzzy match characters within the
7055        // syntax highlight range.
7056        let mut offset = range.start;
7057        while let Some(&match_index) = match_indices.peek() {
7058            if match_index >= range.end {
7059                break;
7060            }
7061
7062            match_indices.next();
7063            if match_index > offset {
7064                result.push((offset..match_index, syntax_highlight));
7065            }
7066
7067            let mut end_index = char_ix_after(match_index, text);
7068            while let Some(&next_match_index) = match_indices.peek() {
7069                if next_match_index == end_index && next_match_index < range.end {
7070                    end_index = char_ix_after(next_match_index, text);
7071                    match_indices.next();
7072                } else {
7073                    break;
7074                }
7075            }
7076
7077            let mut match_style = syntax_highlight;
7078            match_style.weight = Some(fonts::Weight::BOLD);
7079            result.push((match_index..end_index, match_style));
7080            offset = end_index;
7081        }
7082
7083        if offset < range.end {
7084            result.push((offset..range.end, syntax_highlight));
7085        }
7086    }
7087
7088    fn char_ix_after(ix: usize, text: &str) -> usize {
7089        ix + text[ix..].chars().next().unwrap().len_utf8()
7090    }
7091
7092    result
7093}
7094
7095pub fn styled_runs_for_code_label<'a>(
7096    label: &'a CodeLabel,
7097    syntax_theme: &'a theme::SyntaxTheme,
7098) -> impl 'a + Iterator<Item = (Range<usize>, HighlightStyle)> {
7099    let fade_out = HighlightStyle {
7100        fade_out: Some(0.35),
7101        ..Default::default()
7102    };
7103
7104    let mut prev_end = label.filter_range.end;
7105    label
7106        .runs
7107        .iter()
7108        .enumerate()
7109        .flat_map(move |(ix, (range, highlight_id))| {
7110            let style = if let Some(style) = highlight_id.style(syntax_theme) {
7111                style
7112            } else {
7113                return Default::default();
7114            };
7115            let mut muted_style = style;
7116            muted_style.highlight(fade_out);
7117
7118            let mut runs = SmallVec::<[(Range<usize>, HighlightStyle); 3]>::new();
7119            if range.start >= label.filter_range.end {
7120                if range.start > prev_end {
7121                    runs.push((prev_end..range.start, fade_out));
7122                }
7123                runs.push((range.clone(), muted_style));
7124            } else if range.end <= label.filter_range.end {
7125                runs.push((range.clone(), style));
7126            } else {
7127                runs.push((range.start..label.filter_range.end, style));
7128                runs.push((label.filter_range.end..range.end, muted_style));
7129            }
7130            prev_end = cmp::max(prev_end, range.end);
7131
7132            if ix + 1 == label.runs.len() && label.text.len() > prev_end {
7133                runs.push((prev_end..label.text.len(), fade_out));
7134            }
7135
7136            runs
7137        })
7138}
7139
7140trait RangeExt<T> {
7141    fn sorted(&self) -> Range<T>;
7142    fn to_inclusive(&self) -> RangeInclusive<T>;
7143}
7144
7145impl<T: Ord + Clone> RangeExt<T> for Range<T> {
7146    fn sorted(&self) -> Self {
7147        cmp::min(&self.start, &self.end).clone()..cmp::max(&self.start, &self.end).clone()
7148    }
7149
7150    fn to_inclusive(&self) -> RangeInclusive<T> {
7151        self.start.clone()..=self.end.clone()
7152    }
7153}
7154
7155trait RangeToAnchorExt {
7156    fn to_anchors(self, snapshot: &MultiBufferSnapshot) -> Range<Anchor>;
7157}
7158
7159impl<T: ToOffset> RangeToAnchorExt for Range<T> {
7160    fn to_anchors(self, snapshot: &MultiBufferSnapshot) -> Range<Anchor> {
7161        snapshot.anchor_after(self.start)..snapshot.anchor_before(self.end)
7162    }
7163}