editor.rs

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