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