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::<usize>(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>) {
3713        if self.take_rename(true, cx).is_some() {
3714            return;
3715        }
3716
3717        if self
3718            .context_menu
3719            .as_mut()
3720            .map(|menu| menu.select_first(cx))
3721            .unwrap_or(false)
3722        {
3723            return;
3724        }
3725
3726        if matches!(self.mode, EditorMode::SingleLine) {
3727            cx.propagate_action();
3728            return;
3729        }
3730
3731        let row_count = if let Some(row_count) = self.visible_line_count() {
3732            row_count as u32 - 1
3733        } else {
3734            return;
3735        };
3736
3737        let autoscroll = if action.center_cursor {
3738            Autoscroll::center()
3739        } else {
3740            Autoscroll::fit()
3741        };
3742
3743        self.change_selections(Some(autoscroll), cx, |s| {
3744            let line_mode = s.line_mode;
3745            s.move_with(|map, selection| {
3746                if !selection.is_empty() && !line_mode {
3747                    selection.goal = SelectionGoal::None;
3748                }
3749                let (cursor, goal) =
3750                    movement::up_by_rows(map, selection.end, row_count, selection.goal, false);
3751                selection.collapse_to(cursor, goal);
3752            });
3753        });
3754    }
3755
3756    pub fn select_up(&mut self, _: &SelectUp, cx: &mut ViewContext<Self>) {
3757        self.change_selections(Some(Autoscroll::fit()), cx, |s| {
3758            s.move_heads_with(|map, head, goal| movement::up(map, head, goal, false))
3759        })
3760    }
3761
3762    pub fn move_down(&mut self, _: &MoveDown, cx: &mut ViewContext<Self>) {
3763        self.take_rename(true, cx);
3764
3765        if let Some(context_menu) = self.context_menu.as_mut() {
3766            if context_menu.select_next(cx) {
3767                return;
3768            }
3769        }
3770
3771        if matches!(self.mode, EditorMode::SingleLine) {
3772            cx.propagate_action();
3773            return;
3774        }
3775
3776        self.change_selections(Some(Autoscroll::fit()), cx, |s| {
3777            let line_mode = s.line_mode;
3778            s.move_with(|map, selection| {
3779                if !selection.is_empty() && !line_mode {
3780                    selection.goal = SelectionGoal::None;
3781                }
3782                let (cursor, goal) = movement::down(map, selection.end, selection.goal, false);
3783                selection.collapse_to(cursor, goal);
3784            });
3785        });
3786    }
3787
3788    pub fn move_page_down(&mut self, action: &MovePageDown, cx: &mut ViewContext<Self>) {
3789        if self.take_rename(true, cx).is_some() {
3790            return;
3791        }
3792
3793        if self
3794            .context_menu
3795            .as_mut()
3796            .map(|menu| menu.select_last(cx))
3797            .unwrap_or(false)
3798        {
3799            return;
3800        }
3801
3802        if matches!(self.mode, EditorMode::SingleLine) {
3803            cx.propagate_action();
3804            return;
3805        }
3806
3807        let row_count = if let Some(row_count) = self.visible_line_count() {
3808            row_count as u32 - 1
3809        } else {
3810            return;
3811        };
3812
3813        let autoscroll = if action.center_cursor {
3814            Autoscroll::center()
3815        } else {
3816            Autoscroll::fit()
3817        };
3818
3819        self.change_selections(Some(autoscroll), cx, |s| {
3820            let line_mode = s.line_mode;
3821            s.move_with(|map, selection| {
3822                if !selection.is_empty() && !line_mode {
3823                    selection.goal = SelectionGoal::None;
3824                }
3825                let (cursor, goal) =
3826                    movement::down_by_rows(map, selection.end, row_count, selection.goal, false);
3827                selection.collapse_to(cursor, goal);
3828            });
3829        });
3830    }
3831
3832    pub fn select_down(&mut self, _: &SelectDown, cx: &mut ViewContext<Self>) {
3833        self.change_selections(Some(Autoscroll::fit()), cx, |s| {
3834            s.move_heads_with(|map, head, goal| movement::down(map, head, goal, false))
3835        });
3836    }
3837
3838    pub fn move_to_previous_word_start(
3839        &mut self,
3840        _: &MoveToPreviousWordStart,
3841        cx: &mut ViewContext<Self>,
3842    ) {
3843        self.change_selections(Some(Autoscroll::fit()), cx, |s| {
3844            s.move_cursors_with(|map, head, _| {
3845                (
3846                    movement::previous_word_start(map, head),
3847                    SelectionGoal::None,
3848                )
3849            });
3850        })
3851    }
3852
3853    pub fn move_to_previous_subword_start(
3854        &mut self,
3855        _: &MoveToPreviousSubwordStart,
3856        cx: &mut ViewContext<Self>,
3857    ) {
3858        self.change_selections(Some(Autoscroll::fit()), cx, |s| {
3859            s.move_cursors_with(|map, head, _| {
3860                (
3861                    movement::previous_subword_start(map, head),
3862                    SelectionGoal::None,
3863                )
3864            });
3865        })
3866    }
3867
3868    pub fn select_to_previous_word_start(
3869        &mut self,
3870        _: &SelectToPreviousWordStart,
3871        cx: &mut ViewContext<Self>,
3872    ) {
3873        self.change_selections(Some(Autoscroll::fit()), cx, |s| {
3874            s.move_heads_with(|map, head, _| {
3875                (
3876                    movement::previous_word_start(map, head),
3877                    SelectionGoal::None,
3878                )
3879            });
3880        })
3881    }
3882
3883    pub fn select_to_previous_subword_start(
3884        &mut self,
3885        _: &SelectToPreviousSubwordStart,
3886        cx: &mut ViewContext<Self>,
3887    ) {
3888        self.change_selections(Some(Autoscroll::fit()), cx, |s| {
3889            s.move_heads_with(|map, head, _| {
3890                (
3891                    movement::previous_subword_start(map, head),
3892                    SelectionGoal::None,
3893                )
3894            });
3895        })
3896    }
3897
3898    pub fn delete_to_previous_word_start(
3899        &mut self,
3900        _: &DeleteToPreviousWordStart,
3901        cx: &mut ViewContext<Self>,
3902    ) {
3903        self.transact(cx, |this, cx| {
3904            this.select_autoclose_pair(cx);
3905            this.change_selections(Some(Autoscroll::fit()), cx, |s| {
3906                let line_mode = s.line_mode;
3907                s.move_with(|map, selection| {
3908                    if selection.is_empty() && !line_mode {
3909                        let cursor = movement::previous_word_start(map, selection.head());
3910                        selection.set_head(cursor, SelectionGoal::None);
3911                    }
3912                });
3913            });
3914            this.insert("", cx);
3915        });
3916    }
3917
3918    pub fn delete_to_previous_subword_start(
3919        &mut self,
3920        _: &DeleteToPreviousSubwordStart,
3921        cx: &mut ViewContext<Self>,
3922    ) {
3923        self.transact(cx, |this, cx| {
3924            this.select_autoclose_pair(cx);
3925            this.change_selections(Some(Autoscroll::fit()), cx, |s| {
3926                let line_mode = s.line_mode;
3927                s.move_with(|map, selection| {
3928                    if selection.is_empty() && !line_mode {
3929                        let cursor = movement::previous_subword_start(map, selection.head());
3930                        selection.set_head(cursor, SelectionGoal::None);
3931                    }
3932                });
3933            });
3934            this.insert("", cx);
3935        });
3936    }
3937
3938    pub fn move_to_next_word_end(&mut self, _: &MoveToNextWordEnd, cx: &mut ViewContext<Self>) {
3939        self.change_selections(Some(Autoscroll::fit()), cx, |s| {
3940            s.move_cursors_with(|map, head, _| {
3941                (movement::next_word_end(map, head), SelectionGoal::None)
3942            });
3943        })
3944    }
3945
3946    pub fn move_to_next_subword_end(
3947        &mut self,
3948        _: &MoveToNextSubwordEnd,
3949        cx: &mut ViewContext<Self>,
3950    ) {
3951        self.change_selections(Some(Autoscroll::fit()), cx, |s| {
3952            s.move_cursors_with(|map, head, _| {
3953                (movement::next_subword_end(map, head), SelectionGoal::None)
3954            });
3955        })
3956    }
3957
3958    pub fn select_to_next_word_end(&mut self, _: &SelectToNextWordEnd, cx: &mut ViewContext<Self>) {
3959        self.change_selections(Some(Autoscroll::fit()), cx, |s| {
3960            s.move_heads_with(|map, head, _| {
3961                (movement::next_word_end(map, head), SelectionGoal::None)
3962            });
3963        })
3964    }
3965
3966    pub fn select_to_next_subword_end(
3967        &mut self,
3968        _: &SelectToNextSubwordEnd,
3969        cx: &mut ViewContext<Self>,
3970    ) {
3971        self.change_selections(Some(Autoscroll::fit()), cx, |s| {
3972            s.move_heads_with(|map, head, _| {
3973                (movement::next_subword_end(map, head), SelectionGoal::None)
3974            });
3975        })
3976    }
3977
3978    pub fn delete_to_next_word_end(&mut self, _: &DeleteToNextWordEnd, cx: &mut ViewContext<Self>) {
3979        self.transact(cx, |this, cx| {
3980            this.change_selections(Some(Autoscroll::fit()), cx, |s| {
3981                let line_mode = s.line_mode;
3982                s.move_with(|map, selection| {
3983                    if selection.is_empty() && !line_mode {
3984                        let cursor = movement::next_word_end(map, selection.head());
3985                        selection.set_head(cursor, SelectionGoal::None);
3986                    }
3987                });
3988            });
3989            this.insert("", cx);
3990        });
3991    }
3992
3993    pub fn delete_to_next_subword_end(
3994        &mut self,
3995        _: &DeleteToNextSubwordEnd,
3996        cx: &mut ViewContext<Self>,
3997    ) {
3998        self.transact(cx, |this, cx| {
3999            this.change_selections(Some(Autoscroll::fit()), cx, |s| {
4000                s.move_with(|map, selection| {
4001                    if selection.is_empty() {
4002                        let cursor = movement::next_subword_end(map, selection.head());
4003                        selection.set_head(cursor, SelectionGoal::None);
4004                    }
4005                });
4006            });
4007            this.insert("", cx);
4008        });
4009    }
4010
4011    pub fn move_to_beginning_of_line(
4012        &mut self,
4013        _: &MoveToBeginningOfLine,
4014        cx: &mut ViewContext<Self>,
4015    ) {
4016        self.change_selections(Some(Autoscroll::fit()), cx, |s| {
4017            s.move_cursors_with(|map, head, _| {
4018                (
4019                    movement::indented_line_beginning(map, head, true),
4020                    SelectionGoal::None,
4021                )
4022            });
4023        })
4024    }
4025
4026    pub fn select_to_beginning_of_line(
4027        &mut self,
4028        action: &SelectToBeginningOfLine,
4029        cx: &mut ViewContext<Self>,
4030    ) {
4031        self.change_selections(Some(Autoscroll::fit()), cx, |s| {
4032            s.move_heads_with(|map, head, _| {
4033                (
4034                    movement::indented_line_beginning(map, head, action.stop_at_soft_wraps),
4035                    SelectionGoal::None,
4036                )
4037            });
4038        });
4039    }
4040
4041    pub fn delete_to_beginning_of_line(
4042        &mut self,
4043        _: &DeleteToBeginningOfLine,
4044        cx: &mut ViewContext<Self>,
4045    ) {
4046        self.transact(cx, |this, cx| {
4047            this.change_selections(Some(Autoscroll::fit()), cx, |s| {
4048                s.move_with(|_, selection| {
4049                    selection.reversed = true;
4050                });
4051            });
4052
4053            this.select_to_beginning_of_line(
4054                &SelectToBeginningOfLine {
4055                    stop_at_soft_wraps: false,
4056                },
4057                cx,
4058            );
4059            this.backspace(&Backspace, cx);
4060        });
4061    }
4062
4063    pub fn move_to_end_of_line(&mut self, _: &MoveToEndOfLine, cx: &mut ViewContext<Self>) {
4064        self.change_selections(Some(Autoscroll::fit()), cx, |s| {
4065            s.move_cursors_with(|map, head, _| {
4066                (movement::line_end(map, head, true), SelectionGoal::None)
4067            });
4068        })
4069    }
4070
4071    pub fn select_to_end_of_line(
4072        &mut self,
4073        action: &SelectToEndOfLine,
4074        cx: &mut ViewContext<Self>,
4075    ) {
4076        self.change_selections(Some(Autoscroll::fit()), cx, |s| {
4077            s.move_heads_with(|map, head, _| {
4078                (
4079                    movement::line_end(map, head, action.stop_at_soft_wraps),
4080                    SelectionGoal::None,
4081                )
4082            });
4083        })
4084    }
4085
4086    pub fn delete_to_end_of_line(&mut self, _: &DeleteToEndOfLine, cx: &mut ViewContext<Self>) {
4087        self.transact(cx, |this, cx| {
4088            this.select_to_end_of_line(
4089                &SelectToEndOfLine {
4090                    stop_at_soft_wraps: false,
4091                },
4092                cx,
4093            );
4094            this.delete(&Delete, cx);
4095        });
4096    }
4097
4098    pub fn cut_to_end_of_line(&mut self, _: &CutToEndOfLine, cx: &mut ViewContext<Self>) {
4099        self.transact(cx, |this, cx| {
4100            this.select_to_end_of_line(
4101                &SelectToEndOfLine {
4102                    stop_at_soft_wraps: false,
4103                },
4104                cx,
4105            );
4106            this.cut(&Cut, cx);
4107        });
4108    }
4109
4110    pub fn move_to_beginning(&mut self, _: &MoveToBeginning, cx: &mut ViewContext<Self>) {
4111        if matches!(self.mode, EditorMode::SingleLine) {
4112            cx.propagate_action();
4113            return;
4114        }
4115
4116        self.change_selections(Some(Autoscroll::fit()), cx, |s| {
4117            s.select_ranges(vec![0..0]);
4118        });
4119    }
4120
4121    pub fn select_to_beginning(&mut self, _: &SelectToBeginning, cx: &mut ViewContext<Self>) {
4122        let mut selection = self.selections.last::<Point>(cx);
4123        selection.set_head(Point::zero(), SelectionGoal::None);
4124
4125        self.change_selections(Some(Autoscroll::fit()), cx, |s| {
4126            s.select(vec![selection]);
4127        });
4128    }
4129
4130    pub fn move_to_end(&mut self, _: &MoveToEnd, cx: &mut ViewContext<Self>) {
4131        if matches!(self.mode, EditorMode::SingleLine) {
4132            cx.propagate_action();
4133            return;
4134        }
4135
4136        let cursor = self.buffer.read(cx).read(cx).len();
4137        self.change_selections(Some(Autoscroll::fit()), cx, |s| {
4138            s.select_ranges(vec![cursor..cursor])
4139        });
4140    }
4141
4142    pub fn set_nav_history(&mut self, nav_history: Option<ItemNavHistory>) {
4143        self.nav_history = nav_history;
4144    }
4145
4146    pub fn nav_history(&self) -> Option<&ItemNavHistory> {
4147        self.nav_history.as_ref()
4148    }
4149
4150    fn push_to_nav_history(
4151        &self,
4152        cursor_anchor: Anchor,
4153        new_position: Option<Point>,
4154        cx: &mut ViewContext<Self>,
4155    ) {
4156        if let Some(nav_history) = &self.nav_history {
4157            let buffer = self.buffer.read(cx).read(cx);
4158            let cursor_position = cursor_anchor.to_point(&buffer);
4159            let scroll_state = self.scroll_manager.anchor();
4160            let scroll_top_row = scroll_state.top_row(&buffer);
4161            drop(buffer);
4162
4163            if let Some(new_position) = new_position {
4164                let row_delta = (new_position.row as i64 - cursor_position.row as i64).abs();
4165                if row_delta < MIN_NAVIGATION_HISTORY_ROW_DELTA {
4166                    return;
4167                }
4168            }
4169
4170            nav_history.push(
4171                Some(NavigationData {
4172                    cursor_anchor,
4173                    cursor_position,
4174                    scroll_anchor: scroll_state,
4175                    scroll_top_row,
4176                }),
4177                cx,
4178            );
4179        }
4180    }
4181
4182    pub fn select_to_end(&mut self, _: &SelectToEnd, cx: &mut ViewContext<Self>) {
4183        let buffer = self.buffer.read(cx).snapshot(cx);
4184        let mut selection = self.selections.first::<usize>(cx);
4185        selection.set_head(buffer.len(), SelectionGoal::None);
4186        self.change_selections(Some(Autoscroll::fit()), cx, |s| {
4187            s.select(vec![selection]);
4188        });
4189    }
4190
4191    pub fn select_all(&mut self, _: &SelectAll, cx: &mut ViewContext<Self>) {
4192        let end = self.buffer.read(cx).read(cx).len();
4193        self.change_selections(Some(Autoscroll::fit()), cx, |s| {
4194            s.select_ranges(vec![0..end]);
4195        });
4196    }
4197
4198    pub fn select_line(&mut self, _: &SelectLine, cx: &mut ViewContext<Self>) {
4199        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
4200        let mut selections = self.selections.all::<Point>(cx);
4201        let max_point = display_map.buffer_snapshot.max_point();
4202        for selection in &mut selections {
4203            let rows = selection.spanned_rows(true, &display_map);
4204            selection.start = Point::new(rows.start, 0);
4205            selection.end = cmp::min(max_point, Point::new(rows.end, 0));
4206            selection.reversed = false;
4207        }
4208        self.change_selections(Some(Autoscroll::fit()), cx, |s| {
4209            s.select(selections);
4210        });
4211    }
4212
4213    pub fn split_selection_into_lines(
4214        &mut self,
4215        _: &SplitSelectionIntoLines,
4216        cx: &mut ViewContext<Self>,
4217    ) {
4218        let mut to_unfold = Vec::new();
4219        let mut new_selection_ranges = Vec::new();
4220        {
4221            let selections = self.selections.all::<Point>(cx);
4222            let buffer = self.buffer.read(cx).read(cx);
4223            for selection in selections {
4224                for row in selection.start.row..selection.end.row {
4225                    let cursor = Point::new(row, buffer.line_len(row));
4226                    new_selection_ranges.push(cursor..cursor);
4227                }
4228                new_selection_ranges.push(selection.end..selection.end);
4229                to_unfold.push(selection.start..selection.end);
4230            }
4231        }
4232        self.unfold_ranges(to_unfold, true, cx);
4233        self.change_selections(Some(Autoscroll::fit()), cx, |s| {
4234            s.select_ranges(new_selection_ranges);
4235        });
4236    }
4237
4238    pub fn add_selection_above(&mut self, _: &AddSelectionAbove, cx: &mut ViewContext<Self>) {
4239        self.add_selection(true, cx);
4240    }
4241
4242    pub fn add_selection_below(&mut self, _: &AddSelectionBelow, cx: &mut ViewContext<Self>) {
4243        self.add_selection(false, cx);
4244    }
4245
4246    fn add_selection(&mut self, above: bool, cx: &mut ViewContext<Self>) {
4247        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
4248        let mut selections = self.selections.all::<Point>(cx);
4249        let mut state = self.add_selections_state.take().unwrap_or_else(|| {
4250            let oldest_selection = selections.iter().min_by_key(|s| s.id).unwrap().clone();
4251            let range = oldest_selection.display_range(&display_map).sorted();
4252            let columns = cmp::min(range.start.column(), range.end.column())
4253                ..cmp::max(range.start.column(), range.end.column());
4254
4255            selections.clear();
4256            let mut stack = Vec::new();
4257            for row in range.start.row()..=range.end.row() {
4258                if let Some(selection) = self.selections.build_columnar_selection(
4259                    &display_map,
4260                    row,
4261                    &columns,
4262                    oldest_selection.reversed,
4263                ) {
4264                    stack.push(selection.id);
4265                    selections.push(selection);
4266                }
4267            }
4268
4269            if above {
4270                stack.reverse();
4271            }
4272
4273            AddSelectionsState { above, stack }
4274        });
4275
4276        let last_added_selection = *state.stack.last().unwrap();
4277        let mut new_selections = Vec::new();
4278        if above == state.above {
4279            let end_row = if above {
4280                0
4281            } else {
4282                display_map.max_point().row()
4283            };
4284
4285            'outer: for selection in selections {
4286                if selection.id == last_added_selection {
4287                    let range = selection.display_range(&display_map).sorted();
4288                    debug_assert_eq!(range.start.row(), range.end.row());
4289                    let mut row = range.start.row();
4290                    let columns = if let SelectionGoal::ColumnRange { start, end } = selection.goal
4291                    {
4292                        start..end
4293                    } else {
4294                        cmp::min(range.start.column(), range.end.column())
4295                            ..cmp::max(range.start.column(), range.end.column())
4296                    };
4297
4298                    while row != end_row {
4299                        if above {
4300                            row -= 1;
4301                        } else {
4302                            row += 1;
4303                        }
4304
4305                        if let Some(new_selection) = self.selections.build_columnar_selection(
4306                            &display_map,
4307                            row,
4308                            &columns,
4309                            selection.reversed,
4310                        ) {
4311                            state.stack.push(new_selection.id);
4312                            if above {
4313                                new_selections.push(new_selection);
4314                                new_selections.push(selection);
4315                            } else {
4316                                new_selections.push(selection);
4317                                new_selections.push(new_selection);
4318                            }
4319
4320                            continue 'outer;
4321                        }
4322                    }
4323                }
4324
4325                new_selections.push(selection);
4326            }
4327        } else {
4328            new_selections = selections;
4329            new_selections.retain(|s| s.id != last_added_selection);
4330            state.stack.pop();
4331        }
4332
4333        self.change_selections(Some(Autoscroll::fit()), cx, |s| {
4334            s.select(new_selections);
4335        });
4336        if state.stack.len() > 1 {
4337            self.add_selections_state = Some(state);
4338        }
4339    }
4340
4341    pub fn select_next(&mut self, action: &SelectNext, cx: &mut ViewContext<Self>) {
4342        self.push_to_selection_history();
4343        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
4344        let buffer = &display_map.buffer_snapshot;
4345        let mut selections = self.selections.all::<usize>(cx);
4346        if let Some(mut select_next_state) = self.select_next_state.take() {
4347            let query = &select_next_state.query;
4348            if !select_next_state.done {
4349                let first_selection = selections.iter().min_by_key(|s| s.id).unwrap();
4350                let last_selection = selections.iter().max_by_key(|s| s.id).unwrap();
4351                let mut next_selected_range = None;
4352
4353                let bytes_after_last_selection =
4354                    buffer.bytes_in_range(last_selection.end..buffer.len());
4355                let bytes_before_first_selection = buffer.bytes_in_range(0..first_selection.start);
4356                let query_matches = query
4357                    .stream_find_iter(bytes_after_last_selection)
4358                    .map(|result| (last_selection.end, result))
4359                    .chain(
4360                        query
4361                            .stream_find_iter(bytes_before_first_selection)
4362                            .map(|result| (0, result)),
4363                    );
4364                for (start_offset, query_match) in query_matches {
4365                    let query_match = query_match.unwrap(); // can only fail due to I/O
4366                    let offset_range =
4367                        start_offset + query_match.start()..start_offset + query_match.end();
4368                    let display_range = offset_range.start.to_display_point(&display_map)
4369                        ..offset_range.end.to_display_point(&display_map);
4370
4371                    if !select_next_state.wordwise
4372                        || (!movement::is_inside_word(&display_map, display_range.start)
4373                            && !movement::is_inside_word(&display_map, display_range.end))
4374                    {
4375                        next_selected_range = Some(offset_range);
4376                        break;
4377                    }
4378                }
4379
4380                if let Some(next_selected_range) = next_selected_range {
4381                    self.unfold_ranges([next_selected_range.clone()], false, cx);
4382                    self.change_selections(Some(Autoscroll::newest()), cx, |s| {
4383                        if action.replace_newest {
4384                            s.delete(s.newest_anchor().id);
4385                        }
4386                        s.insert_range(next_selected_range);
4387                    });
4388                } else {
4389                    select_next_state.done = true;
4390                }
4391            }
4392
4393            self.select_next_state = Some(select_next_state);
4394        } else if selections.len() == 1 {
4395            let selection = selections.last_mut().unwrap();
4396            if selection.start == selection.end {
4397                let word_range = movement::surrounding_word(
4398                    &display_map,
4399                    selection.start.to_display_point(&display_map),
4400                );
4401                selection.start = word_range.start.to_offset(&display_map, Bias::Left);
4402                selection.end = word_range.end.to_offset(&display_map, Bias::Left);
4403                selection.goal = SelectionGoal::None;
4404                selection.reversed = false;
4405
4406                let query = buffer
4407                    .text_for_range(selection.start..selection.end)
4408                    .collect::<String>();
4409                let select_state = SelectNextState {
4410                    query: AhoCorasick::new_auto_configured(&[query]),
4411                    wordwise: true,
4412                    done: false,
4413                };
4414                self.unfold_ranges([selection.start..selection.end], false, cx);
4415                self.change_selections(Some(Autoscroll::newest()), cx, |s| {
4416                    s.select(selections);
4417                });
4418                self.select_next_state = Some(select_state);
4419            } else {
4420                let query = buffer
4421                    .text_for_range(selection.start..selection.end)
4422                    .collect::<String>();
4423                self.select_next_state = Some(SelectNextState {
4424                    query: AhoCorasick::new_auto_configured(&[query]),
4425                    wordwise: false,
4426                    done: false,
4427                });
4428                self.select_next(action, cx);
4429            }
4430        }
4431    }
4432
4433    pub fn toggle_comments(&mut self, _: &ToggleComments, cx: &mut ViewContext<Self>) {
4434        self.transact(cx, |this, cx| {
4435            let mut selections = this.selections.all::<Point>(cx);
4436            let mut edits = Vec::new();
4437            let mut selection_edit_ranges = Vec::new();
4438            let mut last_toggled_row = None;
4439            let snapshot = this.buffer.read(cx).read(cx);
4440            let empty_str: Arc<str> = "".into();
4441            let mut suffixes_inserted = Vec::new();
4442
4443            fn comment_prefix_range(
4444                snapshot: &MultiBufferSnapshot,
4445                row: u32,
4446                comment_prefix: &str,
4447                comment_prefix_whitespace: &str,
4448            ) -> Range<Point> {
4449                let start = Point::new(row, snapshot.indent_size_for_line(row).len);
4450
4451                let mut line_bytes = snapshot
4452                    .bytes_in_range(start..snapshot.max_point())
4453                    .flatten()
4454                    .copied();
4455
4456                // If this line currently begins with the line comment prefix, then record
4457                // the range containing the prefix.
4458                if line_bytes
4459                    .by_ref()
4460                    .take(comment_prefix.len())
4461                    .eq(comment_prefix.bytes())
4462                {
4463                    // Include any whitespace that matches the comment prefix.
4464                    let matching_whitespace_len = line_bytes
4465                        .zip(comment_prefix_whitespace.bytes())
4466                        .take_while(|(a, b)| a == b)
4467                        .count() as u32;
4468                    let end = Point::new(
4469                        start.row,
4470                        start.column + comment_prefix.len() as u32 + matching_whitespace_len,
4471                    );
4472                    start..end
4473                } else {
4474                    start..start
4475                }
4476            }
4477
4478            fn comment_suffix_range(
4479                snapshot: &MultiBufferSnapshot,
4480                row: u32,
4481                comment_suffix: &str,
4482                comment_suffix_has_leading_space: bool,
4483            ) -> Range<Point> {
4484                let end = Point::new(row, snapshot.line_len(row));
4485                let suffix_start_column = end.column.saturating_sub(comment_suffix.len() as u32);
4486
4487                let mut line_end_bytes = snapshot
4488                    .bytes_in_range(Point::new(end.row, suffix_start_column.saturating_sub(1))..end)
4489                    .flatten()
4490                    .copied();
4491
4492                let leading_space_len = if suffix_start_column > 0
4493                    && line_end_bytes.next() == Some(b' ')
4494                    && comment_suffix_has_leading_space
4495                {
4496                    1
4497                } else {
4498                    0
4499                };
4500
4501                // If this line currently begins with the line comment prefix, then record
4502                // the range containing the prefix.
4503                if line_end_bytes.by_ref().eq(comment_suffix.bytes()) {
4504                    let start = Point::new(end.row, suffix_start_column - leading_space_len);
4505                    start..end
4506                } else {
4507                    end..end
4508                }
4509            }
4510
4511            // TODO: Handle selections that cross excerpts
4512            for selection in &mut selections {
4513                let language = if let Some(language) = snapshot.language_at(selection.start) {
4514                    language
4515                } else {
4516                    continue;
4517                };
4518
4519                selection_edit_ranges.clear();
4520
4521                // If multiple selections contain a given row, avoid processing that
4522                // row more than once.
4523                let mut start_row = selection.start.row;
4524                if last_toggled_row == Some(start_row) {
4525                    start_row += 1;
4526                }
4527                let end_row =
4528                    if selection.end.row > selection.start.row && selection.end.column == 0 {
4529                        selection.end.row - 1
4530                    } else {
4531                        selection.end.row
4532                    };
4533                last_toggled_row = Some(end_row);
4534
4535                if start_row > end_row {
4536                    continue;
4537                }
4538
4539                // If the language has line comments, toggle those.
4540                if let Some(full_comment_prefix) = language.line_comment_prefix() {
4541                    // Split the comment prefix's trailing whitespace into a separate string,
4542                    // as that portion won't be used for detecting if a line is a comment.
4543                    let comment_prefix = full_comment_prefix.trim_end_matches(' ');
4544                    let comment_prefix_whitespace = &full_comment_prefix[comment_prefix.len()..];
4545                    let mut all_selection_lines_are_comments = true;
4546
4547                    for row in start_row..=end_row {
4548                        if snapshot.is_line_blank(row) {
4549                            continue;
4550                        }
4551
4552                        let prefix_range = comment_prefix_range(
4553                            snapshot.deref(),
4554                            row,
4555                            comment_prefix,
4556                            comment_prefix_whitespace,
4557                        );
4558                        if prefix_range.is_empty() {
4559                            all_selection_lines_are_comments = false;
4560                        }
4561                        selection_edit_ranges.push(prefix_range);
4562                    }
4563
4564                    if all_selection_lines_are_comments {
4565                        edits.extend(
4566                            selection_edit_ranges
4567                                .iter()
4568                                .cloned()
4569                                .map(|range| (range, empty_str.clone())),
4570                        );
4571                    } else {
4572                        let min_column = selection_edit_ranges
4573                            .iter()
4574                            .map(|r| r.start.column)
4575                            .min()
4576                            .unwrap_or(0);
4577                        edits.extend(selection_edit_ranges.iter().map(|range| {
4578                            let position = Point::new(range.start.row, min_column);
4579                            (position..position, full_comment_prefix.clone())
4580                        }));
4581                    }
4582                } else if let Some((full_comment_prefix, comment_suffix)) =
4583                    language.block_comment_delimiters()
4584                {
4585                    let comment_prefix = full_comment_prefix.trim_end_matches(' ');
4586                    let comment_prefix_whitespace = &full_comment_prefix[comment_prefix.len()..];
4587                    let prefix_range = comment_prefix_range(
4588                        snapshot.deref(),
4589                        start_row,
4590                        comment_prefix,
4591                        comment_prefix_whitespace,
4592                    );
4593                    let suffix_range = comment_suffix_range(
4594                        snapshot.deref(),
4595                        end_row,
4596                        comment_suffix.trim_start_matches(' '),
4597                        comment_suffix.starts_with(' '),
4598                    );
4599
4600                    if prefix_range.is_empty() || suffix_range.is_empty() {
4601                        edits.push((
4602                            prefix_range.start..prefix_range.start,
4603                            full_comment_prefix.clone(),
4604                        ));
4605                        edits.push((suffix_range.end..suffix_range.end, comment_suffix.clone()));
4606                        suffixes_inserted.push((end_row, comment_suffix.len()));
4607                    } else {
4608                        edits.push((prefix_range, empty_str.clone()));
4609                        edits.push((suffix_range, empty_str.clone()));
4610                    }
4611                } else {
4612                    continue;
4613                }
4614            }
4615
4616            drop(snapshot);
4617            this.buffer.update(cx, |buffer, cx| {
4618                buffer.edit(edits, None, cx);
4619            });
4620
4621            // Adjust selections so that they end before any comment suffixes that
4622            // were inserted.
4623            let mut suffixes_inserted = suffixes_inserted.into_iter().peekable();
4624            let mut selections = this.selections.all::<Point>(cx);
4625            let snapshot = this.buffer.read(cx).read(cx);
4626            for selection in &mut selections {
4627                while let Some((row, suffix_len)) = suffixes_inserted.peek().copied() {
4628                    match row.cmp(&selection.end.row) {
4629                        Ordering::Less => {
4630                            suffixes_inserted.next();
4631                            continue;
4632                        }
4633                        Ordering::Greater => break,
4634                        Ordering::Equal => {
4635                            if selection.end.column == snapshot.line_len(row) {
4636                                if selection.is_empty() {
4637                                    selection.start.column -= suffix_len as u32;
4638                                }
4639                                selection.end.column -= suffix_len as u32;
4640                            }
4641                            break;
4642                        }
4643                    }
4644                }
4645            }
4646
4647            drop(snapshot);
4648            this.change_selections(Some(Autoscroll::fit()), cx, |s| s.select(selections));
4649        });
4650    }
4651
4652    pub fn select_larger_syntax_node(
4653        &mut self,
4654        _: &SelectLargerSyntaxNode,
4655        cx: &mut ViewContext<Self>,
4656    ) {
4657        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
4658        let buffer = self.buffer.read(cx).snapshot(cx);
4659        let old_selections = self.selections.all::<usize>(cx).into_boxed_slice();
4660
4661        let mut stack = mem::take(&mut self.select_larger_syntax_node_stack);
4662        let mut selected_larger_node = false;
4663        let new_selections = old_selections
4664            .iter()
4665            .map(|selection| {
4666                let old_range = selection.start..selection.end;
4667                let mut new_range = old_range.clone();
4668                while let Some(containing_range) =
4669                    buffer.range_for_syntax_ancestor(new_range.clone())
4670                {
4671                    new_range = containing_range;
4672                    if !display_map.intersects_fold(new_range.start)
4673                        && !display_map.intersects_fold(new_range.end)
4674                    {
4675                        break;
4676                    }
4677                }
4678
4679                selected_larger_node |= new_range != old_range;
4680                Selection {
4681                    id: selection.id,
4682                    start: new_range.start,
4683                    end: new_range.end,
4684                    goal: SelectionGoal::None,
4685                    reversed: selection.reversed,
4686                }
4687            })
4688            .collect::<Vec<_>>();
4689
4690        if selected_larger_node {
4691            stack.push(old_selections);
4692            self.change_selections(Some(Autoscroll::fit()), cx, |s| {
4693                s.select(new_selections);
4694            });
4695        }
4696        self.select_larger_syntax_node_stack = stack;
4697    }
4698
4699    pub fn select_smaller_syntax_node(
4700        &mut self,
4701        _: &SelectSmallerSyntaxNode,
4702        cx: &mut ViewContext<Self>,
4703    ) {
4704        let mut stack = mem::take(&mut self.select_larger_syntax_node_stack);
4705        if let Some(selections) = stack.pop() {
4706            self.change_selections(Some(Autoscroll::fit()), cx, |s| {
4707                s.select(selections.to_vec());
4708            });
4709        }
4710        self.select_larger_syntax_node_stack = stack;
4711    }
4712
4713    pub fn move_to_enclosing_bracket(
4714        &mut self,
4715        _: &MoveToEnclosingBracket,
4716        cx: &mut ViewContext<Self>,
4717    ) {
4718        let buffer = self.buffer.read(cx).snapshot(cx);
4719        let mut selections = self.selections.all::<usize>(cx);
4720        for selection in &mut selections {
4721            if let Some((open_range, close_range)) =
4722                buffer.enclosing_bracket_ranges(selection.start..selection.end)
4723            {
4724                let close_range = close_range.to_inclusive();
4725                let destination = if close_range.contains(&selection.start)
4726                    && close_range.contains(&selection.end)
4727                {
4728                    open_range.end
4729                } else {
4730                    *close_range.start()
4731                };
4732                selection.start = destination;
4733                selection.end = destination;
4734            }
4735        }
4736
4737        self.change_selections(Some(Autoscroll::fit()), cx, |s| {
4738            s.select(selections);
4739        });
4740    }
4741
4742    pub fn undo_selection(&mut self, _: &UndoSelection, cx: &mut ViewContext<Self>) {
4743        self.end_selection(cx);
4744        self.selection_history.mode = SelectionHistoryMode::Undoing;
4745        if let Some(entry) = self.selection_history.undo_stack.pop_back() {
4746            self.change_selections(None, cx, |s| s.select_anchors(entry.selections.to_vec()));
4747            self.select_next_state = entry.select_next_state;
4748            self.add_selections_state = entry.add_selections_state;
4749            self.request_autoscroll(Autoscroll::newest(), cx);
4750        }
4751        self.selection_history.mode = SelectionHistoryMode::Normal;
4752    }
4753
4754    pub fn redo_selection(&mut self, _: &RedoSelection, cx: &mut ViewContext<Self>) {
4755        self.end_selection(cx);
4756        self.selection_history.mode = SelectionHistoryMode::Redoing;
4757        if let Some(entry) = self.selection_history.redo_stack.pop_back() {
4758            self.change_selections(None, cx, |s| s.select_anchors(entry.selections.to_vec()));
4759            self.select_next_state = entry.select_next_state;
4760            self.add_selections_state = entry.add_selections_state;
4761            self.request_autoscroll(Autoscroll::newest(), cx);
4762        }
4763        self.selection_history.mode = SelectionHistoryMode::Normal;
4764    }
4765
4766    fn go_to_diagnostic(&mut self, _: &GoToDiagnostic, cx: &mut ViewContext<Self>) {
4767        self.go_to_diagnostic_impl(Direction::Next, cx)
4768    }
4769
4770    fn go_to_prev_diagnostic(&mut self, _: &GoToPrevDiagnostic, cx: &mut ViewContext<Self>) {
4771        self.go_to_diagnostic_impl(Direction::Prev, cx)
4772    }
4773
4774    pub fn go_to_diagnostic_impl(&mut self, direction: Direction, cx: &mut ViewContext<Self>) {
4775        let buffer = self.buffer.read(cx).snapshot(cx);
4776        let selection = self.selections.newest::<usize>(cx);
4777
4778        // If there is an active Diagnostic Popover. Jump to it's diagnostic instead.
4779        if direction == Direction::Next {
4780            if let Some(popover) = self.hover_state.diagnostic_popover.as_ref() {
4781                let (group_id, jump_to) = popover.activation_info();
4782                if self.activate_diagnostics(group_id, cx) {
4783                    self.change_selections(Some(Autoscroll::center()), cx, |s| {
4784                        let mut new_selection = s.newest_anchor().clone();
4785                        new_selection.collapse_to(jump_to, SelectionGoal::None);
4786                        s.select_anchors(vec![new_selection.clone()]);
4787                    });
4788                }
4789                return;
4790            }
4791        }
4792
4793        let mut active_primary_range = self.active_diagnostics.as_ref().map(|active_diagnostics| {
4794            active_diagnostics
4795                .primary_range
4796                .to_offset(&buffer)
4797                .to_inclusive()
4798        });
4799        let mut search_start = if let Some(active_primary_range) = active_primary_range.as_ref() {
4800            if active_primary_range.contains(&selection.head()) {
4801                *active_primary_range.end()
4802            } else {
4803                selection.head()
4804            }
4805        } else {
4806            selection.head()
4807        };
4808
4809        loop {
4810            let mut diagnostics = if direction == Direction::Prev {
4811                buffer.diagnostics_in_range::<_, usize>(0..search_start, true)
4812            } else {
4813                buffer.diagnostics_in_range::<_, usize>(search_start..buffer.len(), false)
4814            };
4815            let group = diagnostics.find_map(|entry| {
4816                if entry.diagnostic.is_primary
4817                    && entry.diagnostic.severity <= DiagnosticSeverity::WARNING
4818                    && !entry.range.is_empty()
4819                    && Some(entry.range.end) != active_primary_range.as_ref().map(|r| *r.end())
4820                {
4821                    Some((entry.range, entry.diagnostic.group_id))
4822                } else {
4823                    None
4824                }
4825            });
4826
4827            if let Some((primary_range, group_id)) = group {
4828                if self.activate_diagnostics(group_id, cx) {
4829                    self.change_selections(Some(Autoscroll::center()), cx, |s| {
4830                        s.select(vec![Selection {
4831                            id: selection.id,
4832                            start: primary_range.start,
4833                            end: primary_range.start,
4834                            reversed: false,
4835                            goal: SelectionGoal::None,
4836                        }]);
4837                    });
4838                }
4839                break;
4840            } else {
4841                // Cycle around to the start of the buffer, potentially moving back to the start of
4842                // the currently active diagnostic.
4843                active_primary_range.take();
4844                if direction == Direction::Prev {
4845                    if search_start == buffer.len() {
4846                        break;
4847                    } else {
4848                        search_start = buffer.len();
4849                    }
4850                } else if search_start == 0 {
4851                    break;
4852                } else {
4853                    search_start = 0;
4854                }
4855            }
4856        }
4857    }
4858
4859    fn go_to_hunk(&mut self, _: &GoToHunk, cx: &mut ViewContext<Self>) {
4860        self.go_to_hunk_impl(Direction::Next, cx)
4861    }
4862
4863    fn go_to_prev_hunk(&mut self, _: &GoToPrevHunk, cx: &mut ViewContext<Self>) {
4864        self.go_to_hunk_impl(Direction::Prev, cx)
4865    }
4866
4867    pub fn go_to_hunk_impl(&mut self, direction: Direction, cx: &mut ViewContext<Self>) {
4868        let snapshot = self
4869            .display_map
4870            .update(cx, |display_map, cx| display_map.snapshot(cx));
4871        let selection = self.selections.newest::<Point>(cx);
4872
4873        fn seek_in_direction(
4874            this: &mut Editor,
4875            snapshot: &DisplaySnapshot,
4876            initial_point: Point,
4877            is_wrapped: bool,
4878            direction: Direction,
4879            cx: &mut ViewContext<Editor>,
4880        ) -> bool {
4881            let hunks = if direction == Direction::Next {
4882                snapshot
4883                    .buffer_snapshot
4884                    .git_diff_hunks_in_range(initial_point.row..u32::MAX, false)
4885            } else {
4886                snapshot
4887                    .buffer_snapshot
4888                    .git_diff_hunks_in_range(0..initial_point.row, true)
4889            };
4890
4891            let display_point = initial_point.to_display_point(snapshot);
4892            let mut hunks = hunks
4893                .map(|hunk| diff_hunk_to_display(hunk, &snapshot))
4894                .skip_while(|hunk| {
4895                    if is_wrapped {
4896                        false
4897                    } else {
4898                        hunk.contains_display_row(display_point.row())
4899                    }
4900                })
4901                .dedup();
4902
4903            if let Some(hunk) = hunks.next() {
4904                this.change_selections(Some(Autoscroll::center()), cx, |s| {
4905                    let row = hunk.start_display_row();
4906                    let point = DisplayPoint::new(row, 0);
4907                    s.select_display_ranges([point..point]);
4908                });
4909
4910                true
4911            } else {
4912                false
4913            }
4914        }
4915
4916        if !seek_in_direction(self, &snapshot, selection.head(), false, direction, cx) {
4917            let wrapped_point = match direction {
4918                Direction::Next => Point::zero(),
4919                Direction::Prev => snapshot.buffer_snapshot.max_point(),
4920            };
4921            seek_in_direction(self, &snapshot, wrapped_point, true, direction, cx);
4922        }
4923    }
4924
4925    pub fn go_to_definition(
4926        workspace: &mut Workspace,
4927        _: &GoToDefinition,
4928        cx: &mut ViewContext<Workspace>,
4929    ) {
4930        Self::go_to_definition_of_kind(GotoDefinitionKind::Symbol, workspace, cx);
4931    }
4932
4933    pub fn go_to_type_definition(
4934        workspace: &mut Workspace,
4935        _: &GoToTypeDefinition,
4936        cx: &mut ViewContext<Workspace>,
4937    ) {
4938        Self::go_to_definition_of_kind(GotoDefinitionKind::Type, workspace, cx);
4939    }
4940
4941    fn go_to_definition_of_kind(
4942        kind: GotoDefinitionKind,
4943        workspace: &mut Workspace,
4944        cx: &mut ViewContext<Workspace>,
4945    ) {
4946        let active_item = workspace.active_item(cx);
4947        let editor_handle = if let Some(editor) = active_item
4948            .as_ref()
4949            .and_then(|item| item.act_as::<Self>(cx))
4950        {
4951            editor
4952        } else {
4953            return;
4954        };
4955
4956        let editor = editor_handle.read(cx);
4957        let buffer = editor.buffer.read(cx);
4958        let head = editor.selections.newest::<usize>(cx).head();
4959        let (buffer, head) = if let Some(text_anchor) = buffer.text_anchor_for_position(head, cx) {
4960            text_anchor
4961        } else {
4962            return;
4963        };
4964
4965        let project = workspace.project().clone();
4966        let definitions = project.update(cx, |project, cx| match kind {
4967            GotoDefinitionKind::Symbol => project.definition(&buffer, head, cx),
4968            GotoDefinitionKind::Type => project.type_definition(&buffer, head, cx),
4969        });
4970
4971        cx.spawn(|workspace, mut cx| async move {
4972            let definitions = definitions.await?;
4973            workspace.update(&mut cx, |workspace, cx| {
4974                Editor::navigate_to_definitions(workspace, editor_handle, definitions, cx);
4975            });
4976
4977            Ok::<(), anyhow::Error>(())
4978        })
4979        .detach_and_log_err(cx);
4980    }
4981
4982    pub fn navigate_to_definitions(
4983        workspace: &mut Workspace,
4984        editor_handle: ViewHandle<Editor>,
4985        definitions: Vec<LocationLink>,
4986        cx: &mut ViewContext<Workspace>,
4987    ) {
4988        let pane = workspace.active_pane().clone();
4989        for definition in definitions {
4990            let range = definition
4991                .target
4992                .range
4993                .to_offset(definition.target.buffer.read(cx));
4994
4995            let target_editor_handle = workspace.open_project_item(definition.target.buffer, cx);
4996            target_editor_handle.update(cx, |target_editor, cx| {
4997                // When selecting a definition in a different buffer, disable the nav history
4998                // to avoid creating a history entry at the previous cursor location.
4999                if editor_handle != target_editor_handle {
5000                    pane.update(cx, |pane, _| pane.disable_history());
5001                }
5002                target_editor.change_selections(Some(Autoscroll::center()), cx, |s| {
5003                    s.select_ranges([range]);
5004                });
5005
5006                pane.update(cx, |pane, _| pane.enable_history());
5007            });
5008        }
5009    }
5010
5011    pub fn find_all_references(
5012        workspace: &mut Workspace,
5013        _: &FindAllReferences,
5014        cx: &mut ViewContext<Workspace>,
5015    ) -> Option<Task<Result<()>>> {
5016        let active_item = workspace.active_item(cx)?;
5017        let editor_handle = active_item.act_as::<Self>(cx)?;
5018
5019        let editor = editor_handle.read(cx);
5020        let buffer = editor.buffer.read(cx);
5021        let head = editor.selections.newest::<usize>(cx).head();
5022        let (buffer, head) = buffer.text_anchor_for_position(head, cx)?;
5023        let replica_id = editor.replica_id(cx);
5024
5025        let project = workspace.project().clone();
5026        let references = project.update(cx, |project, cx| project.references(&buffer, head, cx));
5027        Some(cx.spawn(|workspace, mut cx| async move {
5028            let mut locations = references.await?;
5029            if locations.is_empty() {
5030                return Ok(());
5031            }
5032
5033            locations.sort_by_key(|location| location.buffer.id());
5034            let mut locations = locations.into_iter().peekable();
5035            let mut ranges_to_highlight = Vec::new();
5036
5037            let excerpt_buffer = cx.add_model(|cx| {
5038                let mut symbol_name = None;
5039                let mut multibuffer = MultiBuffer::new(replica_id);
5040                while let Some(location) = locations.next() {
5041                    let buffer = location.buffer.read(cx);
5042                    let mut ranges_for_buffer = Vec::new();
5043                    let range = location.range.to_offset(buffer);
5044                    ranges_for_buffer.push(range.clone());
5045                    if symbol_name.is_none() {
5046                        symbol_name = Some(buffer.text_for_range(range).collect::<String>());
5047                    }
5048
5049                    while let Some(next_location) = locations.peek() {
5050                        if next_location.buffer == location.buffer {
5051                            ranges_for_buffer.push(next_location.range.to_offset(buffer));
5052                            locations.next();
5053                        } else {
5054                            break;
5055                        }
5056                    }
5057
5058                    ranges_for_buffer.sort_by_key(|range| (range.start, Reverse(range.end)));
5059                    ranges_to_highlight.extend(multibuffer.push_excerpts_with_context_lines(
5060                        location.buffer.clone(),
5061                        ranges_for_buffer,
5062                        1,
5063                        cx,
5064                    ));
5065                }
5066                multibuffer.with_title(format!("References to `{}`", symbol_name.unwrap()))
5067            });
5068
5069            workspace.update(&mut cx, |workspace, cx| {
5070                let editor =
5071                    cx.add_view(|cx| Editor::for_multibuffer(excerpt_buffer, Some(project), cx));
5072                editor.update(cx, |editor, cx| {
5073                    editor.highlight_background::<Self>(
5074                        ranges_to_highlight,
5075                        |theme| theme.editor.highlighted_line_background,
5076                        cx,
5077                    );
5078                });
5079                workspace.add_item(Box::new(editor), cx);
5080            });
5081
5082            Ok(())
5083        }))
5084    }
5085
5086    pub fn rename(&mut self, _: &Rename, cx: &mut ViewContext<Self>) -> Option<Task<Result<()>>> {
5087        use language::ToOffset as _;
5088
5089        let project = self.project.clone()?;
5090        let selection = self.selections.newest_anchor().clone();
5091        let (cursor_buffer, cursor_buffer_position) = self
5092            .buffer
5093            .read(cx)
5094            .text_anchor_for_position(selection.head(), cx)?;
5095        let (tail_buffer, _) = self
5096            .buffer
5097            .read(cx)
5098            .text_anchor_for_position(selection.tail(), cx)?;
5099        if tail_buffer != cursor_buffer {
5100            return None;
5101        }
5102
5103        let snapshot = cursor_buffer.read(cx).snapshot();
5104        let cursor_buffer_offset = cursor_buffer_position.to_offset(&snapshot);
5105        let prepare_rename = project.update(cx, |project, cx| {
5106            project.prepare_rename(cursor_buffer, cursor_buffer_offset, cx)
5107        });
5108
5109        Some(cx.spawn(|this, mut cx| async move {
5110            let rename_range = if let Some(range) = prepare_rename.await? {
5111                Some(range)
5112            } else {
5113                this.read_with(&cx, |this, cx| {
5114                    let buffer = this.buffer.read(cx).snapshot(cx);
5115                    let mut buffer_highlights = this
5116                        .document_highlights_for_position(selection.head(), &buffer)
5117                        .filter(|highlight| {
5118                            highlight.start.excerpt_id() == selection.head().excerpt_id()
5119                                && highlight.end.excerpt_id() == selection.head().excerpt_id()
5120                        });
5121                    buffer_highlights
5122                        .next()
5123                        .map(|highlight| highlight.start.text_anchor..highlight.end.text_anchor)
5124                })
5125            };
5126            if let Some(rename_range) = rename_range {
5127                let rename_buffer_range = rename_range.to_offset(&snapshot);
5128                let cursor_offset_in_rename_range =
5129                    cursor_buffer_offset.saturating_sub(rename_buffer_range.start);
5130
5131                this.update(&mut cx, |this, cx| {
5132                    this.take_rename(false, cx);
5133                    let style = this.style(cx);
5134                    let buffer = this.buffer.read(cx).read(cx);
5135                    let cursor_offset = selection.head().to_offset(&buffer);
5136                    let rename_start = cursor_offset.saturating_sub(cursor_offset_in_rename_range);
5137                    let rename_end = rename_start + rename_buffer_range.len();
5138                    let range = buffer.anchor_before(rename_start)..buffer.anchor_after(rename_end);
5139                    let mut old_highlight_id = None;
5140                    let old_name: Arc<str> = buffer
5141                        .chunks(rename_start..rename_end, true)
5142                        .map(|chunk| {
5143                            if old_highlight_id.is_none() {
5144                                old_highlight_id = chunk.syntax_highlight_id;
5145                            }
5146                            chunk.text
5147                        })
5148                        .collect::<String>()
5149                        .into();
5150
5151                    drop(buffer);
5152
5153                    // Position the selection in the rename editor so that it matches the current selection.
5154                    this.show_local_selections = false;
5155                    let rename_editor = cx.add_view(|cx| {
5156                        let mut editor = Editor::single_line(None, cx);
5157                        if let Some(old_highlight_id) = old_highlight_id {
5158                            editor.override_text_style =
5159                                Some(Box::new(move |style| old_highlight_id.style(&style.syntax)));
5160                        }
5161                        editor.buffer.update(cx, |buffer, cx| {
5162                            buffer.edit([(0..0, old_name.clone())], None, cx)
5163                        });
5164                        editor.select_all(&SelectAll, cx);
5165                        editor
5166                    });
5167
5168                    let ranges = this
5169                        .clear_background_highlights::<DocumentHighlightWrite>(cx)
5170                        .into_iter()
5171                        .flat_map(|(_, ranges)| ranges)
5172                        .chain(
5173                            this.clear_background_highlights::<DocumentHighlightRead>(cx)
5174                                .into_iter()
5175                                .flat_map(|(_, ranges)| ranges),
5176                        )
5177                        .collect();
5178
5179                    this.highlight_text::<Rename>(
5180                        ranges,
5181                        HighlightStyle {
5182                            fade_out: Some(style.rename_fade),
5183                            ..Default::default()
5184                        },
5185                        cx,
5186                    );
5187                    cx.focus(&rename_editor);
5188                    let block_id = this.insert_blocks(
5189                        [BlockProperties {
5190                            style: BlockStyle::Flex,
5191                            position: range.start.clone(),
5192                            height: 1,
5193                            render: Arc::new({
5194                                let editor = rename_editor.clone();
5195                                move |cx: &mut BlockContext| {
5196                                    ChildView::new(editor.clone(), cx)
5197                                        .contained()
5198                                        .with_padding_left(cx.anchor_x)
5199                                        .boxed()
5200                                }
5201                            }),
5202                            disposition: BlockDisposition::Below,
5203                        }],
5204                        cx,
5205                    )[0];
5206                    this.pending_rename = Some(RenameState {
5207                        range,
5208                        old_name,
5209                        editor: rename_editor,
5210                        block_id,
5211                    });
5212                });
5213            }
5214
5215            Ok(())
5216        }))
5217    }
5218
5219    pub fn confirm_rename(
5220        workspace: &mut Workspace,
5221        _: &ConfirmRename,
5222        cx: &mut ViewContext<Workspace>,
5223    ) -> Option<Task<Result<()>>> {
5224        let editor = workspace.active_item(cx)?.act_as::<Editor>(cx)?;
5225
5226        let (buffer, range, old_name, new_name) = editor.update(cx, |editor, cx| {
5227            let rename = editor.take_rename(false, cx)?;
5228            let buffer = editor.buffer.read(cx);
5229            let (start_buffer, start) =
5230                buffer.text_anchor_for_position(rename.range.start.clone(), cx)?;
5231            let (end_buffer, end) =
5232                buffer.text_anchor_for_position(rename.range.end.clone(), cx)?;
5233            if start_buffer == end_buffer {
5234                let new_name = rename.editor.read(cx).text(cx);
5235                Some((start_buffer, start..end, rename.old_name, new_name))
5236            } else {
5237                None
5238            }
5239        })?;
5240
5241        let rename = workspace.project().clone().update(cx, |project, cx| {
5242            project.perform_rename(buffer.clone(), range.start, new_name.clone(), true, cx)
5243        });
5244
5245        Some(cx.spawn(|workspace, mut cx| async move {
5246            let project_transaction = rename.await?;
5247            Self::open_project_transaction(
5248                editor.clone(),
5249                workspace,
5250                project_transaction,
5251                format!("Rename: {}{}", old_name, new_name),
5252                cx.clone(),
5253            )
5254            .await?;
5255
5256            editor.update(&mut cx, |editor, cx| {
5257                editor.refresh_document_highlights(cx);
5258            });
5259            Ok(())
5260        }))
5261    }
5262
5263    fn take_rename(
5264        &mut self,
5265        moving_cursor: bool,
5266        cx: &mut ViewContext<Self>,
5267    ) -> Option<RenameState> {
5268        let rename = self.pending_rename.take()?;
5269        self.remove_blocks([rename.block_id].into_iter().collect(), cx);
5270        self.clear_text_highlights::<Rename>(cx);
5271        self.show_local_selections = true;
5272
5273        if moving_cursor {
5274            let rename_editor = rename.editor.read(cx);
5275            let cursor_in_rename_editor = rename_editor.selections.newest::<usize>(cx).head();
5276
5277            // Update the selection to match the position of the selection inside
5278            // the rename editor.
5279            let snapshot = self.buffer.read(cx).read(cx);
5280            let rename_range = rename.range.to_offset(&snapshot);
5281            let cursor_in_editor = snapshot
5282                .clip_offset(rename_range.start + cursor_in_rename_editor, Bias::Left)
5283                .min(rename_range.end);
5284            drop(snapshot);
5285
5286            self.change_selections(None, cx, |s| {
5287                s.select_ranges(vec![cursor_in_editor..cursor_in_editor])
5288            });
5289        } else {
5290            self.refresh_document_highlights(cx);
5291        }
5292
5293        Some(rename)
5294    }
5295
5296    #[cfg(any(test, feature = "test-support"))]
5297    pub fn pending_rename(&self) -> Option<&RenameState> {
5298        self.pending_rename.as_ref()
5299    }
5300
5301    fn format(&mut self, _: &Format, cx: &mut ViewContext<'_, Self>) -> Option<Task<Result<()>>> {
5302        let project = match &self.project {
5303            Some(project) => project.clone(),
5304            None => return None,
5305        };
5306
5307        Some(self.perform_format(project, cx))
5308    }
5309
5310    fn perform_format(
5311        &mut self,
5312        project: ModelHandle<Project>,
5313        cx: &mut ViewContext<'_, Self>,
5314    ) -> Task<Result<()>> {
5315        let buffer = self.buffer().clone();
5316        let buffers = buffer.read(cx).all_buffers();
5317
5318        let mut timeout = cx.background().timer(FORMAT_TIMEOUT).fuse();
5319        let format = project.update(cx, |project, cx| {
5320            project.format(buffers, true, FormatTrigger::Manual, cx)
5321        });
5322
5323        cx.spawn(|_, mut cx| async move {
5324            let transaction = futures::select_biased! {
5325                _ = timeout => {
5326                    log::warn!("timed out waiting for formatting");
5327                    None
5328                }
5329                transaction = format.log_err().fuse() => transaction,
5330            };
5331
5332            buffer.update(&mut cx, |buffer, cx| {
5333                if let Some(transaction) = transaction {
5334                    if !buffer.is_singleton() {
5335                        buffer.push_transaction(&transaction.0);
5336                    }
5337                }
5338
5339                cx.notify();
5340            });
5341
5342            Ok(())
5343        })
5344    }
5345
5346    fn restart_language_server(&mut self, _: &RestartLanguageServer, cx: &mut ViewContext<Self>) {
5347        if let Some(project) = self.project.clone() {
5348            self.buffer.update(cx, |multi_buffer, cx| {
5349                project.update(cx, |project, cx| {
5350                    project.restart_language_servers_for_buffers(multi_buffer.all_buffers(), cx);
5351                });
5352            })
5353        }
5354    }
5355
5356    fn show_character_palette(&mut self, _: &ShowCharacterPalette, cx: &mut ViewContext<Self>) {
5357        cx.show_character_palette();
5358    }
5359
5360    fn refresh_active_diagnostics(&mut self, cx: &mut ViewContext<Editor>) {
5361        if let Some(active_diagnostics) = self.active_diagnostics.as_mut() {
5362            let buffer = self.buffer.read(cx).snapshot(cx);
5363            let primary_range_start = active_diagnostics.primary_range.start.to_offset(&buffer);
5364            let is_valid = buffer
5365                .diagnostics_in_range::<_, usize>(active_diagnostics.primary_range.clone(), false)
5366                .any(|entry| {
5367                    entry.diagnostic.is_primary
5368                        && !entry.range.is_empty()
5369                        && entry.range.start == primary_range_start
5370                        && entry.diagnostic.message == active_diagnostics.primary_message
5371                });
5372
5373            if is_valid != active_diagnostics.is_valid {
5374                active_diagnostics.is_valid = is_valid;
5375                let mut new_styles = HashMap::default();
5376                for (block_id, diagnostic) in &active_diagnostics.blocks {
5377                    new_styles.insert(
5378                        *block_id,
5379                        diagnostic_block_renderer(diagnostic.clone(), is_valid),
5380                    );
5381                }
5382                self.display_map
5383                    .update(cx, |display_map, _| display_map.replace_blocks(new_styles));
5384            }
5385        }
5386    }
5387
5388    fn activate_diagnostics(&mut self, group_id: usize, cx: &mut ViewContext<Self>) -> bool {
5389        self.dismiss_diagnostics(cx);
5390        self.active_diagnostics = self.display_map.update(cx, |display_map, cx| {
5391            let buffer = self.buffer.read(cx).snapshot(cx);
5392
5393            let mut primary_range = None;
5394            let mut primary_message = None;
5395            let mut group_end = Point::zero();
5396            let diagnostic_group = buffer
5397                .diagnostic_group::<Point>(group_id)
5398                .map(|entry| {
5399                    if entry.range.end > group_end {
5400                        group_end = entry.range.end;
5401                    }
5402                    if entry.diagnostic.is_primary {
5403                        primary_range = Some(entry.range.clone());
5404                        primary_message = Some(entry.diagnostic.message.clone());
5405                    }
5406                    entry
5407                })
5408                .collect::<Vec<_>>();
5409            let primary_range = primary_range?;
5410            let primary_message = primary_message?;
5411            let primary_range =
5412                buffer.anchor_after(primary_range.start)..buffer.anchor_before(primary_range.end);
5413
5414            let blocks = display_map
5415                .insert_blocks(
5416                    diagnostic_group.iter().map(|entry| {
5417                        let diagnostic = entry.diagnostic.clone();
5418                        let message_height = diagnostic.message.lines().count() as u8;
5419                        BlockProperties {
5420                            style: BlockStyle::Fixed,
5421                            position: buffer.anchor_after(entry.range.start),
5422                            height: message_height,
5423                            render: diagnostic_block_renderer(diagnostic, true),
5424                            disposition: BlockDisposition::Below,
5425                        }
5426                    }),
5427                    cx,
5428                )
5429                .into_iter()
5430                .zip(diagnostic_group.into_iter().map(|entry| entry.diagnostic))
5431                .collect();
5432
5433            Some(ActiveDiagnosticGroup {
5434                primary_range,
5435                primary_message,
5436                blocks,
5437                is_valid: true,
5438            })
5439        });
5440        self.active_diagnostics.is_some()
5441    }
5442
5443    fn dismiss_diagnostics(&mut self, cx: &mut ViewContext<Self>) {
5444        if let Some(active_diagnostic_group) = self.active_diagnostics.take() {
5445            self.display_map.update(cx, |display_map, cx| {
5446                display_map.remove_blocks(active_diagnostic_group.blocks.into_keys().collect(), cx);
5447            });
5448            cx.notify();
5449        }
5450    }
5451
5452    pub fn set_selections_from_remote(
5453        &mut self,
5454        selections: Vec<Selection<Anchor>>,
5455        cx: &mut ViewContext<Self>,
5456    ) {
5457        let old_cursor_position = self.selections.newest_anchor().head();
5458        self.selections.change_with(cx, |s| {
5459            s.select_anchors(selections);
5460        });
5461        self.selections_did_change(false, &old_cursor_position, cx);
5462    }
5463
5464    fn push_to_selection_history(&mut self) {
5465        self.selection_history.push(SelectionHistoryEntry {
5466            selections: self.selections.disjoint_anchors(),
5467            select_next_state: self.select_next_state.clone(),
5468            add_selections_state: self.add_selections_state.clone(),
5469        });
5470    }
5471
5472    pub fn transact(
5473        &mut self,
5474        cx: &mut ViewContext<Self>,
5475        update: impl FnOnce(&mut Self, &mut ViewContext<Self>),
5476    ) -> Option<TransactionId> {
5477        self.start_transaction_at(Instant::now(), cx);
5478        update(self, cx);
5479        self.end_transaction_at(Instant::now(), cx)
5480    }
5481
5482    fn start_transaction_at(&mut self, now: Instant, cx: &mut ViewContext<Self>) {
5483        self.end_selection(cx);
5484        if let Some(tx_id) = self
5485            .buffer
5486            .update(cx, |buffer, cx| buffer.start_transaction_at(now, cx))
5487        {
5488            self.selection_history
5489                .insert_transaction(tx_id, self.selections.disjoint_anchors());
5490        }
5491    }
5492
5493    fn end_transaction_at(
5494        &mut self,
5495        now: Instant,
5496        cx: &mut ViewContext<Self>,
5497    ) -> Option<TransactionId> {
5498        if let Some(tx_id) = self
5499            .buffer
5500            .update(cx, |buffer, cx| buffer.end_transaction_at(now, cx))
5501        {
5502            if let Some((_, end_selections)) = self.selection_history.transaction_mut(tx_id) {
5503                *end_selections = Some(self.selections.disjoint_anchors());
5504            } else {
5505                log::error!("unexpectedly ended a transaction that wasn't started by this editor");
5506            }
5507
5508            cx.emit(Event::Edited);
5509            Some(tx_id)
5510        } else {
5511            None
5512        }
5513    }
5514
5515    pub fn fold(&mut self, _: &Fold, cx: &mut ViewContext<Self>) {
5516        let mut fold_ranges = Vec::new();
5517
5518        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
5519        let selections = self.selections.all::<Point>(cx);
5520        for selection in selections {
5521            let range = selection.display_range(&display_map).sorted();
5522            let buffer_start_row = range.start.to_point(&display_map).row;
5523
5524            for row in (0..=range.end.row()).rev() {
5525                if self.is_line_foldable(&display_map, row) && !display_map.is_line_folded(row) {
5526                    let fold_range = self.foldable_range_for_line(&display_map, row);
5527                    if fold_range.end.row >= buffer_start_row {
5528                        fold_ranges.push(fold_range);
5529                        if row <= range.start.row() {
5530                            break;
5531                        }
5532                    }
5533                }
5534            }
5535        }
5536
5537        self.fold_ranges(fold_ranges, cx);
5538    }
5539
5540    pub fn unfold_lines(&mut self, _: &UnfoldLines, cx: &mut ViewContext<Self>) {
5541        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
5542        let buffer = &display_map.buffer_snapshot;
5543        let selections = self.selections.all::<Point>(cx);
5544        let ranges = selections
5545            .iter()
5546            .map(|s| {
5547                let range = s.display_range(&display_map).sorted();
5548                let mut start = range.start.to_point(&display_map);
5549                let mut end = range.end.to_point(&display_map);
5550                start.column = 0;
5551                end.column = buffer.line_len(end.row);
5552                start..end
5553            })
5554            .collect::<Vec<_>>();
5555        self.unfold_ranges(ranges, true, cx);
5556    }
5557
5558    fn is_line_foldable(&self, display_map: &DisplaySnapshot, display_row: u32) -> bool {
5559        let max_point = display_map.max_point();
5560        if display_row >= max_point.row() {
5561            false
5562        } else {
5563            let (start_indent, is_blank) = display_map.line_indent(display_row);
5564            if is_blank {
5565                false
5566            } else {
5567                for display_row in display_row + 1..=max_point.row() {
5568                    let (indent, is_blank) = display_map.line_indent(display_row);
5569                    if !is_blank {
5570                        return indent > start_indent;
5571                    }
5572                }
5573                false
5574            }
5575        }
5576    }
5577
5578    fn foldable_range_for_line(
5579        &self,
5580        display_map: &DisplaySnapshot,
5581        start_row: u32,
5582    ) -> Range<Point> {
5583        let max_point = display_map.max_point();
5584
5585        let (start_indent, _) = display_map.line_indent(start_row);
5586        let start = DisplayPoint::new(start_row, display_map.line_len(start_row));
5587        let mut end = None;
5588        for row in start_row + 1..=max_point.row() {
5589            let (indent, is_blank) = display_map.line_indent(row);
5590            if !is_blank && indent <= start_indent {
5591                end = Some(DisplayPoint::new(row - 1, display_map.line_len(row - 1)));
5592                break;
5593            }
5594        }
5595
5596        let end = end.unwrap_or(max_point);
5597        start.to_point(display_map)..end.to_point(display_map)
5598    }
5599
5600    pub fn fold_selected_ranges(&mut self, _: &FoldSelectedRanges, cx: &mut ViewContext<Self>) {
5601        let selections = self.selections.all::<Point>(cx);
5602        let ranges = selections.into_iter().map(|s| s.start..s.end);
5603        self.fold_ranges(ranges, cx);
5604    }
5605
5606    pub fn fold_ranges<T: ToOffset>(
5607        &mut self,
5608        ranges: impl IntoIterator<Item = Range<T>>,
5609        cx: &mut ViewContext<Self>,
5610    ) {
5611        let mut ranges = ranges.into_iter().peekable();
5612        if ranges.peek().is_some() {
5613            self.display_map.update(cx, |map, cx| map.fold(ranges, cx));
5614            self.request_autoscroll(Autoscroll::fit(), cx);
5615            cx.notify();
5616        }
5617    }
5618
5619    pub fn unfold_ranges<T: ToOffset>(
5620        &mut self,
5621        ranges: impl IntoIterator<Item = Range<T>>,
5622        inclusive: bool,
5623        cx: &mut ViewContext<Self>,
5624    ) {
5625        let mut ranges = ranges.into_iter().peekable();
5626        if ranges.peek().is_some() {
5627            self.display_map
5628                .update(cx, |map, cx| map.unfold(ranges, inclusive, cx));
5629            self.request_autoscroll(Autoscroll::fit(), cx);
5630            cx.notify();
5631        }
5632    }
5633
5634    pub fn insert_blocks(
5635        &mut self,
5636        blocks: impl IntoIterator<Item = BlockProperties<Anchor>>,
5637        cx: &mut ViewContext<Self>,
5638    ) -> Vec<BlockId> {
5639        let blocks = self
5640            .display_map
5641            .update(cx, |display_map, cx| display_map.insert_blocks(blocks, cx));
5642        self.request_autoscroll(Autoscroll::fit(), cx);
5643        blocks
5644    }
5645
5646    pub fn replace_blocks(
5647        &mut self,
5648        blocks: HashMap<BlockId, RenderBlock>,
5649        cx: &mut ViewContext<Self>,
5650    ) {
5651        self.display_map
5652            .update(cx, |display_map, _| display_map.replace_blocks(blocks));
5653        self.request_autoscroll(Autoscroll::fit(), cx);
5654    }
5655
5656    pub fn remove_blocks(&mut self, block_ids: HashSet<BlockId>, cx: &mut ViewContext<Self>) {
5657        self.display_map.update(cx, |display_map, cx| {
5658            display_map.remove_blocks(block_ids, cx)
5659        });
5660    }
5661
5662    pub fn longest_row(&self, cx: &mut MutableAppContext) -> u32 {
5663        self.display_map
5664            .update(cx, |map, cx| map.snapshot(cx))
5665            .longest_row()
5666    }
5667
5668    pub fn max_point(&self, cx: &mut MutableAppContext) -> DisplayPoint {
5669        self.display_map
5670            .update(cx, |map, cx| map.snapshot(cx))
5671            .max_point()
5672    }
5673
5674    pub fn text(&self, cx: &AppContext) -> String {
5675        self.buffer.read(cx).read(cx).text()
5676    }
5677
5678    pub fn set_text(&mut self, text: impl Into<Arc<str>>, cx: &mut ViewContext<Self>) {
5679        self.transact(cx, |this, cx| {
5680            this.buffer
5681                .read(cx)
5682                .as_singleton()
5683                .expect("you can only call set_text on editors for singleton buffers")
5684                .update(cx, |buffer, cx| buffer.set_text(text, cx));
5685        });
5686    }
5687
5688    pub fn display_text(&self, cx: &mut MutableAppContext) -> String {
5689        self.display_map
5690            .update(cx, |map, cx| map.snapshot(cx))
5691            .text()
5692    }
5693
5694    pub fn soft_wrap_mode(&self, cx: &AppContext) -> SoftWrap {
5695        let language_name = self
5696            .buffer
5697            .read(cx)
5698            .as_singleton()
5699            .and_then(|singleton_buffer| singleton_buffer.read(cx).language())
5700            .map(|l| l.name());
5701
5702        let settings = cx.global::<Settings>();
5703        let mode = self
5704            .soft_wrap_mode_override
5705            .unwrap_or_else(|| settings.soft_wrap(language_name.as_deref()));
5706        match mode {
5707            settings::SoftWrap::None => SoftWrap::None,
5708            settings::SoftWrap::EditorWidth => SoftWrap::EditorWidth,
5709            settings::SoftWrap::PreferredLineLength => {
5710                SoftWrap::Column(settings.preferred_line_length(language_name.as_deref()))
5711            }
5712        }
5713    }
5714
5715    pub fn set_soft_wrap_mode(&mut self, mode: settings::SoftWrap, cx: &mut ViewContext<Self>) {
5716        self.soft_wrap_mode_override = Some(mode);
5717        cx.notify();
5718    }
5719
5720    pub fn set_wrap_width(&self, width: Option<f32>, cx: &mut MutableAppContext) -> bool {
5721        self.display_map
5722            .update(cx, |map, cx| map.set_wrap_width(width, cx))
5723    }
5724
5725    pub fn highlight_rows(&mut self, rows: Option<Range<u32>>) {
5726        self.highlighted_rows = rows;
5727    }
5728
5729    pub fn highlighted_rows(&self) -> Option<Range<u32>> {
5730        self.highlighted_rows.clone()
5731    }
5732
5733    pub fn highlight_background<T: 'static>(
5734        &mut self,
5735        ranges: Vec<Range<Anchor>>,
5736        color_fetcher: fn(&Theme) -> Color,
5737        cx: &mut ViewContext<Self>,
5738    ) {
5739        self.background_highlights
5740            .insert(TypeId::of::<T>(), (color_fetcher, ranges));
5741        cx.notify();
5742    }
5743
5744    #[allow(clippy::type_complexity)]
5745    pub fn clear_background_highlights<T: 'static>(
5746        &mut self,
5747        cx: &mut ViewContext<Self>,
5748    ) -> Option<(fn(&Theme) -> Color, Vec<Range<Anchor>>)> {
5749        let highlights = self.background_highlights.remove(&TypeId::of::<T>());
5750        if highlights.is_some() {
5751            cx.notify();
5752        }
5753        highlights
5754    }
5755
5756    #[cfg(feature = "test-support")]
5757    pub fn all_background_highlights(
5758        &mut self,
5759        cx: &mut ViewContext<Self>,
5760    ) -> Vec<(Range<DisplayPoint>, Color)> {
5761        let snapshot = self.snapshot(cx);
5762        let buffer = &snapshot.buffer_snapshot;
5763        let start = buffer.anchor_before(0);
5764        let end = buffer.anchor_after(buffer.len());
5765        let theme = cx.global::<Settings>().theme.as_ref();
5766        self.background_highlights_in_range(start..end, &snapshot, theme)
5767    }
5768
5769    fn document_highlights_for_position<'a>(
5770        &'a self,
5771        position: Anchor,
5772        buffer: &'a MultiBufferSnapshot,
5773    ) -> impl 'a + Iterator<Item = &Range<Anchor>> {
5774        let read_highlights = self
5775            .background_highlights
5776            .get(&TypeId::of::<DocumentHighlightRead>())
5777            .map(|h| &h.1);
5778        let write_highlights = self
5779            .background_highlights
5780            .get(&TypeId::of::<DocumentHighlightWrite>())
5781            .map(|h| &h.1);
5782        let left_position = position.bias_left(buffer);
5783        let right_position = position.bias_right(buffer);
5784        read_highlights
5785            .into_iter()
5786            .chain(write_highlights)
5787            .flat_map(move |ranges| {
5788                let start_ix = match ranges.binary_search_by(|probe| {
5789                    let cmp = probe.end.cmp(&left_position, buffer);
5790                    if cmp.is_ge() {
5791                        Ordering::Greater
5792                    } else {
5793                        Ordering::Less
5794                    }
5795                }) {
5796                    Ok(i) | Err(i) => i,
5797                };
5798
5799                let right_position = right_position.clone();
5800                ranges[start_ix..]
5801                    .iter()
5802                    .take_while(move |range| range.start.cmp(&right_position, buffer).is_le())
5803            })
5804    }
5805
5806    pub fn background_highlights_in_range(
5807        &self,
5808        search_range: Range<Anchor>,
5809        display_snapshot: &DisplaySnapshot,
5810        theme: &Theme,
5811    ) -> Vec<(Range<DisplayPoint>, Color)> {
5812        let mut results = Vec::new();
5813        let buffer = &display_snapshot.buffer_snapshot;
5814        for (color_fetcher, ranges) in self.background_highlights.values() {
5815            let color = color_fetcher(theme);
5816            let start_ix = match ranges.binary_search_by(|probe| {
5817                let cmp = probe.end.cmp(&search_range.start, buffer);
5818                if cmp.is_gt() {
5819                    Ordering::Greater
5820                } else {
5821                    Ordering::Less
5822                }
5823            }) {
5824                Ok(i) | Err(i) => i,
5825            };
5826            for range in &ranges[start_ix..] {
5827                if range.start.cmp(&search_range.end, buffer).is_ge() {
5828                    break;
5829                }
5830                let start = range
5831                    .start
5832                    .to_point(buffer)
5833                    .to_display_point(display_snapshot);
5834                let end = range
5835                    .end
5836                    .to_point(buffer)
5837                    .to_display_point(display_snapshot);
5838                results.push((start..end, color))
5839            }
5840        }
5841        results
5842    }
5843
5844    pub fn highlight_text<T: 'static>(
5845        &mut self,
5846        ranges: Vec<Range<Anchor>>,
5847        style: HighlightStyle,
5848        cx: &mut ViewContext<Self>,
5849    ) {
5850        self.display_map.update(cx, |map, _| {
5851            map.highlight_text(TypeId::of::<T>(), ranges, style)
5852        });
5853        cx.notify();
5854    }
5855
5856    pub fn text_highlights<'a, T: 'static>(
5857        &'a self,
5858        cx: &'a AppContext,
5859    ) -> Option<(HighlightStyle, &'a [Range<Anchor>])> {
5860        self.display_map.read(cx).text_highlights(TypeId::of::<T>())
5861    }
5862
5863    pub fn clear_text_highlights<T: 'static>(
5864        &mut self,
5865        cx: &mut ViewContext<Self>,
5866    ) -> Option<Arc<(HighlightStyle, Vec<Range<Anchor>>)>> {
5867        let highlights = self
5868            .display_map
5869            .update(cx, |map, _| map.clear_text_highlights(TypeId::of::<T>()));
5870        if highlights.is_some() {
5871            cx.notify();
5872        }
5873        highlights
5874    }
5875
5876    pub fn show_local_cursors(&self, cx: &AppContext) -> bool {
5877        self.blink_manager.read(cx).visible() && self.focused
5878    }
5879
5880    fn on_buffer_changed(&mut self, _: ModelHandle<MultiBuffer>, cx: &mut ViewContext<Self>) {
5881        cx.notify();
5882    }
5883
5884    fn on_buffer_event(
5885        &mut self,
5886        _: ModelHandle<MultiBuffer>,
5887        event: &language::Event,
5888        cx: &mut ViewContext<Self>,
5889    ) {
5890        match event {
5891            language::Event::Edited => {
5892                self.refresh_active_diagnostics(cx);
5893                self.refresh_code_actions(cx);
5894                cx.emit(Event::BufferEdited);
5895            }
5896            language::Event::Reparsed => cx.emit(Event::Reparsed),
5897            language::Event::DirtyChanged => cx.emit(Event::DirtyChanged),
5898            language::Event::Saved => cx.emit(Event::Saved),
5899            language::Event::FileHandleChanged => cx.emit(Event::TitleChanged),
5900            language::Event::Reloaded => cx.emit(Event::TitleChanged),
5901            language::Event::Closed => cx.emit(Event::Closed),
5902            language::Event::DiagnosticsUpdated => {
5903                self.refresh_active_diagnostics(cx);
5904            }
5905            _ => {}
5906        }
5907    }
5908
5909    fn on_display_map_changed(&mut self, _: ModelHandle<DisplayMap>, cx: &mut ViewContext<Self>) {
5910        cx.notify();
5911    }
5912
5913    pub fn set_searchable(&mut self, searchable: bool) {
5914        self.searchable = searchable;
5915    }
5916
5917    pub fn searchable(&self) -> bool {
5918        self.searchable
5919    }
5920
5921    fn open_excerpts(workspace: &mut Workspace, _: &OpenExcerpts, cx: &mut ViewContext<Workspace>) {
5922        let active_item = workspace.active_item(cx);
5923        let editor_handle = if let Some(editor) = active_item
5924            .as_ref()
5925            .and_then(|item| item.act_as::<Self>(cx))
5926        {
5927            editor
5928        } else {
5929            cx.propagate_action();
5930            return;
5931        };
5932
5933        let editor = editor_handle.read(cx);
5934        let buffer = editor.buffer.read(cx);
5935        if buffer.is_singleton() {
5936            cx.propagate_action();
5937            return;
5938        }
5939
5940        let mut new_selections_by_buffer = HashMap::default();
5941        for selection in editor.selections.all::<usize>(cx) {
5942            for (buffer, mut range) in
5943                buffer.range_to_buffer_ranges(selection.start..selection.end, cx)
5944            {
5945                if selection.reversed {
5946                    mem::swap(&mut range.start, &mut range.end);
5947                }
5948                new_selections_by_buffer
5949                    .entry(buffer)
5950                    .or_insert(Vec::new())
5951                    .push(range)
5952            }
5953        }
5954
5955        editor_handle.update(cx, |editor, cx| {
5956            editor.push_to_nav_history(editor.selections.newest_anchor().head(), None, cx);
5957        });
5958        let pane = workspace.active_pane().clone();
5959        pane.update(cx, |pane, _| pane.disable_history());
5960
5961        // We defer the pane interaction because we ourselves are a workspace item
5962        // and activating a new item causes the pane to call a method on us reentrantly,
5963        // which panics if we're on the stack.
5964        cx.defer(move |workspace, cx| {
5965            for (buffer, ranges) in new_selections_by_buffer.into_iter() {
5966                let editor = workspace.open_project_item::<Self>(buffer, cx);
5967                editor.update(cx, |editor, cx| {
5968                    editor.change_selections(Some(Autoscroll::newest()), cx, |s| {
5969                        s.select_ranges(ranges);
5970                    });
5971                });
5972            }
5973
5974            pane.update(cx, |pane, _| pane.enable_history());
5975        });
5976    }
5977
5978    fn jump(workspace: &mut Workspace, action: &Jump, cx: &mut ViewContext<Workspace>) {
5979        let editor = workspace.open_path(action.path.clone(), None, true, cx);
5980        let position = action.position;
5981        let anchor = action.anchor;
5982        cx.spawn_weak(|_, mut cx| async move {
5983            let editor = editor.await.log_err()?.downcast::<Editor>()?;
5984            editor.update(&mut cx, |editor, cx| {
5985                let buffer = editor.buffer().read(cx).as_singleton()?;
5986                let buffer = buffer.read(cx);
5987                let cursor = if buffer.can_resolve(&anchor) {
5988                    language::ToPoint::to_point(&anchor, buffer)
5989                } else {
5990                    buffer.clip_point(position, Bias::Left)
5991                };
5992
5993                let nav_history = editor.nav_history.take();
5994                editor.change_selections(Some(Autoscroll::newest()), cx, |s| {
5995                    s.select_ranges([cursor..cursor]);
5996                });
5997                editor.nav_history = nav_history;
5998
5999                Some(())
6000            })?;
6001            Some(())
6002        })
6003        .detach()
6004    }
6005
6006    fn marked_text_ranges(&self, cx: &AppContext) -> Option<Vec<Range<OffsetUtf16>>> {
6007        let snapshot = self.buffer.read(cx).read(cx);
6008        let (_, ranges) = self.text_highlights::<InputComposition>(cx)?;
6009        Some(
6010            ranges
6011                .iter()
6012                .map(move |range| {
6013                    range.start.to_offset_utf16(&snapshot)..range.end.to_offset_utf16(&snapshot)
6014                })
6015                .collect(),
6016        )
6017    }
6018
6019    fn selection_replacement_ranges(
6020        &self,
6021        range: Range<OffsetUtf16>,
6022        cx: &AppContext,
6023    ) -> Vec<Range<OffsetUtf16>> {
6024        let selections = self.selections.all::<OffsetUtf16>(cx);
6025        let newest_selection = selections
6026            .iter()
6027            .max_by_key(|selection| selection.id)
6028            .unwrap();
6029        let start_delta = range.start.0 as isize - newest_selection.start.0 as isize;
6030        let end_delta = range.end.0 as isize - newest_selection.end.0 as isize;
6031        let snapshot = self.buffer.read(cx).read(cx);
6032        selections
6033            .into_iter()
6034            .map(|mut selection| {
6035                selection.start.0 =
6036                    (selection.start.0 as isize).saturating_add(start_delta) as usize;
6037                selection.end.0 = (selection.end.0 as isize).saturating_add(end_delta) as usize;
6038                snapshot.clip_offset_utf16(selection.start, Bias::Left)
6039                    ..snapshot.clip_offset_utf16(selection.end, Bias::Right)
6040            })
6041            .collect()
6042    }
6043
6044    fn report_event(&self, name: &str, cx: &AppContext) {
6045        if let Some((project, file)) = self.project.as_ref().zip(
6046            self.buffer
6047                .read(cx)
6048                .as_singleton()
6049                .and_then(|b| b.read(cx).file()),
6050        ) {
6051            let extension = Path::new(file.file_name(cx))
6052                .extension()
6053                .and_then(|e| e.to_str());
6054            project
6055                .read(cx)
6056                .client()
6057                .report_event(name, json!({ "File Extension": extension }));
6058        }
6059    }
6060}
6061
6062impl EditorSnapshot {
6063    pub fn language_at<T: ToOffset>(&self, position: T) -> Option<&Arc<Language>> {
6064        self.display_snapshot.buffer_snapshot.language_at(position)
6065    }
6066
6067    pub fn is_focused(&self) -> bool {
6068        self.is_focused
6069    }
6070
6071    pub fn placeholder_text(&self) -> Option<&Arc<str>> {
6072        self.placeholder_text.as_ref()
6073    }
6074
6075    pub fn scroll_position(&self) -> Vector2F {
6076        self.scroll_anchor.scroll_position(&self.display_snapshot)
6077    }
6078}
6079
6080impl Deref for EditorSnapshot {
6081    type Target = DisplaySnapshot;
6082
6083    fn deref(&self) -> &Self::Target {
6084        &self.display_snapshot
6085    }
6086}
6087
6088#[derive(Copy, Clone, Debug, PartialEq, Eq)]
6089pub enum Event {
6090    BufferEdited,
6091    Edited,
6092    Reparsed,
6093    Blurred,
6094    DirtyChanged,
6095    Saved,
6096    TitleChanged,
6097    SelectionsChanged { local: bool },
6098    ScrollPositionChanged { local: bool },
6099    Closed,
6100}
6101
6102pub struct EditorFocused(pub ViewHandle<Editor>);
6103pub struct EditorBlurred(pub ViewHandle<Editor>);
6104pub struct EditorReleased(pub WeakViewHandle<Editor>);
6105
6106impl Entity for Editor {
6107    type Event = Event;
6108
6109    fn release(&mut self, cx: &mut MutableAppContext) {
6110        cx.emit_global(EditorReleased(self.handle.clone()));
6111    }
6112}
6113
6114impl View for Editor {
6115    fn render(&mut self, cx: &mut RenderContext<Self>) -> ElementBox {
6116        let style = self.style(cx);
6117        let font_changed = self.display_map.update(cx, |map, cx| {
6118            map.set_font(style.text.font_id, style.text.font_size, cx)
6119        });
6120
6121        if font_changed {
6122            let handle = self.handle.clone();
6123            cx.defer(move |cx| {
6124                if let Some(editor) = handle.upgrade(cx) {
6125                    editor.update(cx, |editor, cx| {
6126                        hide_hover(editor, cx);
6127                        hide_link_definition(editor, cx);
6128                    })
6129                }
6130            });
6131        }
6132
6133        Stack::new()
6134            .with_child(EditorElement::new(self.handle.clone(), style.clone()).boxed())
6135            .with_child(ChildView::new(&self.mouse_context_menu, cx).boxed())
6136            .boxed()
6137    }
6138
6139    fn ui_name() -> &'static str {
6140        "Editor"
6141    }
6142
6143    fn focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext<Self>) {
6144        let focused_event = EditorFocused(cx.handle());
6145        cx.emit_global(focused_event);
6146        if let Some(rename) = self.pending_rename.as_ref() {
6147            cx.focus(&rename.editor);
6148        } else {
6149            if !self.focused {
6150                self.blink_manager.update(cx, BlinkManager::enable);
6151            }
6152            self.focused = true;
6153            self.buffer.update(cx, |buffer, cx| {
6154                buffer.finalize_last_transaction(cx);
6155                if self.leader_replica_id.is_none() {
6156                    buffer.set_active_selections(
6157                        &self.selections.disjoint_anchors(),
6158                        self.selections.line_mode,
6159                        self.cursor_shape,
6160                        cx,
6161                    );
6162                }
6163            });
6164        }
6165    }
6166
6167    fn focus_out(&mut self, _: AnyViewHandle, cx: &mut ViewContext<Self>) {
6168        let blurred_event = EditorBlurred(cx.handle());
6169        cx.emit_global(blurred_event);
6170        self.focused = false;
6171        self.blink_manager.update(cx, BlinkManager::disable);
6172        self.buffer
6173            .update(cx, |buffer, cx| buffer.remove_active_selections(cx));
6174        self.hide_context_menu(cx);
6175        hide_hover(self, cx);
6176        cx.emit(Event::Blurred);
6177        cx.notify();
6178    }
6179
6180    fn modifiers_changed(
6181        &mut self,
6182        event: &gpui::ModifiersChangedEvent,
6183        cx: &mut ViewContext<Self>,
6184    ) -> bool {
6185        let pending_selection = self.has_pending_selection();
6186
6187        if let Some(point) = self.link_go_to_definition_state.last_mouse_location.clone() {
6188            if event.cmd && !pending_selection {
6189                let snapshot = self.snapshot(cx);
6190                let kind = if event.shift {
6191                    LinkDefinitionKind::Type
6192                } else {
6193                    LinkDefinitionKind::Symbol
6194                };
6195
6196                show_link_definition(kind, self, point, snapshot, cx);
6197                return false;
6198            }
6199        }
6200
6201        {
6202            if self.link_go_to_definition_state.symbol_range.is_some()
6203                || !self.link_go_to_definition_state.definitions.is_empty()
6204            {
6205                self.link_go_to_definition_state.symbol_range.take();
6206                self.link_go_to_definition_state.definitions.clear();
6207                cx.notify();
6208            }
6209
6210            self.link_go_to_definition_state.task = None;
6211
6212            self.clear_text_highlights::<LinkGoToDefinitionState>(cx);
6213        }
6214
6215        false
6216    }
6217
6218    fn keymap_context(&self, _: &AppContext) -> gpui::keymap::Context {
6219        let mut context = Self::default_keymap_context();
6220        let mode = match self.mode {
6221            EditorMode::SingleLine => "single_line",
6222            EditorMode::AutoHeight { .. } => "auto_height",
6223            EditorMode::Full => "full",
6224        };
6225        context.map.insert("mode".into(), mode.into());
6226        if self.pending_rename.is_some() {
6227            context.set.insert("renaming".into());
6228        }
6229        match self.context_menu.as_ref() {
6230            Some(ContextMenu::Completions(_)) => {
6231                context.set.insert("showing_completions".into());
6232            }
6233            Some(ContextMenu::CodeActions(_)) => {
6234                context.set.insert("showing_code_actions".into());
6235            }
6236            None => {}
6237        }
6238
6239        for layer in self.keymap_context_layers.values() {
6240            context.extend(layer);
6241        }
6242
6243        context
6244    }
6245
6246    fn text_for_range(&self, range_utf16: Range<usize>, cx: &AppContext) -> Option<String> {
6247        Some(
6248            self.buffer
6249                .read(cx)
6250                .read(cx)
6251                .text_for_range(OffsetUtf16(range_utf16.start)..OffsetUtf16(range_utf16.end))
6252                .collect(),
6253        )
6254    }
6255
6256    fn selected_text_range(&self, cx: &AppContext) -> Option<Range<usize>> {
6257        // Prevent the IME menu from appearing when holding down an alphabetic key
6258        // while input is disabled.
6259        if !self.input_enabled {
6260            return None;
6261        }
6262
6263        let range = self.selections.newest::<OffsetUtf16>(cx).range();
6264        Some(range.start.0..range.end.0)
6265    }
6266
6267    fn marked_text_range(&self, cx: &AppContext) -> Option<Range<usize>> {
6268        let snapshot = self.buffer.read(cx).read(cx);
6269        let range = self.text_highlights::<InputComposition>(cx)?.1.get(0)?;
6270        Some(range.start.to_offset_utf16(&snapshot).0..range.end.to_offset_utf16(&snapshot).0)
6271    }
6272
6273    fn unmark_text(&mut self, cx: &mut ViewContext<Self>) {
6274        self.clear_text_highlights::<InputComposition>(cx);
6275        self.ime_transaction.take();
6276    }
6277
6278    fn replace_text_in_range(
6279        &mut self,
6280        range_utf16: Option<Range<usize>>,
6281        text: &str,
6282        cx: &mut ViewContext<Self>,
6283    ) {
6284        if !self.input_enabled {
6285            return;
6286        }
6287
6288        self.transact(cx, |this, cx| {
6289            let new_selected_ranges = if let Some(range_utf16) = range_utf16 {
6290                let range_utf16 = OffsetUtf16(range_utf16.start)..OffsetUtf16(range_utf16.end);
6291                Some(this.selection_replacement_ranges(range_utf16, cx))
6292            } else {
6293                this.marked_text_ranges(cx)
6294            };
6295
6296            if let Some(new_selected_ranges) = new_selected_ranges {
6297                this.change_selections(None, cx, |selections| {
6298                    selections.select_ranges(new_selected_ranges)
6299                });
6300            }
6301            this.handle_input(text, cx);
6302        });
6303
6304        if let Some(transaction) = self.ime_transaction {
6305            self.buffer.update(cx, |buffer, cx| {
6306                buffer.group_until_transaction(transaction, cx);
6307            });
6308        }
6309
6310        self.unmark_text(cx);
6311    }
6312
6313    fn replace_and_mark_text_in_range(
6314        &mut self,
6315        range_utf16: Option<Range<usize>>,
6316        text: &str,
6317        new_selected_range_utf16: Option<Range<usize>>,
6318        cx: &mut ViewContext<Self>,
6319    ) {
6320        if !self.input_enabled {
6321            return;
6322        }
6323
6324        let transaction = self.transact(cx, |this, cx| {
6325            let ranges_to_replace = if let Some(mut marked_ranges) = this.marked_text_ranges(cx) {
6326                let snapshot = this.buffer.read(cx).read(cx);
6327                if let Some(relative_range_utf16) = range_utf16.as_ref() {
6328                    for marked_range in &mut marked_ranges {
6329                        marked_range.end.0 = marked_range.start.0 + relative_range_utf16.end;
6330                        marked_range.start.0 += relative_range_utf16.start;
6331                        marked_range.start =
6332                            snapshot.clip_offset_utf16(marked_range.start, Bias::Left);
6333                        marked_range.end =
6334                            snapshot.clip_offset_utf16(marked_range.end, Bias::Right);
6335                    }
6336                }
6337                Some(marked_ranges)
6338            } else if let Some(range_utf16) = range_utf16 {
6339                let range_utf16 = OffsetUtf16(range_utf16.start)..OffsetUtf16(range_utf16.end);
6340                Some(this.selection_replacement_ranges(range_utf16, cx))
6341            } else {
6342                None
6343            };
6344
6345            if let Some(ranges) = ranges_to_replace {
6346                this.change_selections(None, cx, |s| s.select_ranges(ranges));
6347            }
6348
6349            let marked_ranges = {
6350                let snapshot = this.buffer.read(cx).read(cx);
6351                this.selections
6352                    .disjoint_anchors()
6353                    .iter()
6354                    .map(|selection| {
6355                        selection.start.bias_left(&*snapshot)..selection.end.bias_right(&*snapshot)
6356                    })
6357                    .collect::<Vec<_>>()
6358            };
6359
6360            if text.is_empty() {
6361                this.unmark_text(cx);
6362            } else {
6363                this.highlight_text::<InputComposition>(
6364                    marked_ranges.clone(),
6365                    this.style(cx).composition_mark,
6366                    cx,
6367                );
6368            }
6369
6370            this.handle_input(text, cx);
6371
6372            if let Some(new_selected_range) = new_selected_range_utf16 {
6373                let snapshot = this.buffer.read(cx).read(cx);
6374                let new_selected_ranges = marked_ranges
6375                    .into_iter()
6376                    .map(|marked_range| {
6377                        let insertion_start = marked_range.start.to_offset_utf16(&snapshot).0;
6378                        let new_start = OffsetUtf16(new_selected_range.start + insertion_start);
6379                        let new_end = OffsetUtf16(new_selected_range.end + insertion_start);
6380                        snapshot.clip_offset_utf16(new_start, Bias::Left)
6381                            ..snapshot.clip_offset_utf16(new_end, Bias::Right)
6382                    })
6383                    .collect::<Vec<_>>();
6384
6385                drop(snapshot);
6386                this.change_selections(None, cx, |selections| {
6387                    selections.select_ranges(new_selected_ranges)
6388                });
6389            }
6390        });
6391
6392        self.ime_transaction = self.ime_transaction.or(transaction);
6393        if let Some(transaction) = self.ime_transaction {
6394            self.buffer.update(cx, |buffer, cx| {
6395                buffer.group_until_transaction(transaction, cx);
6396            });
6397        }
6398
6399        if self.text_highlights::<InputComposition>(cx).is_none() {
6400            self.ime_transaction.take();
6401        }
6402    }
6403}
6404
6405fn build_style(
6406    settings: &Settings,
6407    get_field_editor_theme: Option<&GetFieldEditorTheme>,
6408    override_text_style: Option<&OverrideTextStyle>,
6409    cx: &AppContext,
6410) -> EditorStyle {
6411    let font_cache = cx.font_cache();
6412
6413    let mut theme = settings.theme.editor.clone();
6414    let mut style = if let Some(get_field_editor_theme) = get_field_editor_theme {
6415        let field_editor_theme = get_field_editor_theme(&settings.theme);
6416        theme.text_color = field_editor_theme.text.color;
6417        theme.selection = field_editor_theme.selection;
6418        theme.background = field_editor_theme
6419            .container
6420            .background_color
6421            .unwrap_or_default();
6422        EditorStyle {
6423            text: field_editor_theme.text,
6424            placeholder_text: field_editor_theme.placeholder_text,
6425            theme,
6426        }
6427    } else {
6428        let font_family_id = settings.buffer_font_family;
6429        let font_family_name = cx.font_cache().family_name(font_family_id).unwrap();
6430        let font_properties = Default::default();
6431        let font_id = font_cache
6432            .select_font(font_family_id, &font_properties)
6433            .unwrap();
6434        let font_size = settings.buffer_font_size;
6435        EditorStyle {
6436            text: TextStyle {
6437                color: settings.theme.editor.text_color,
6438                font_family_name,
6439                font_family_id,
6440                font_id,
6441                font_size,
6442                font_properties,
6443                underline: Default::default(),
6444            },
6445            placeholder_text: None,
6446            theme,
6447        }
6448    };
6449
6450    if let Some(highlight_style) = override_text_style.and_then(|build_style| build_style(&style)) {
6451        if let Some(highlighted) = style
6452            .text
6453            .clone()
6454            .highlight(highlight_style, font_cache)
6455            .log_err()
6456        {
6457            style.text = highlighted;
6458        }
6459    }
6460
6461    style
6462}
6463
6464trait SelectionExt {
6465    fn offset_range(&self, buffer: &MultiBufferSnapshot) -> Range<usize>;
6466    fn point_range(&self, buffer: &MultiBufferSnapshot) -> Range<Point>;
6467    fn display_range(&self, map: &DisplaySnapshot) -> Range<DisplayPoint>;
6468    fn spanned_rows(&self, include_end_if_at_line_start: bool, map: &DisplaySnapshot)
6469        -> Range<u32>;
6470}
6471
6472impl<T: ToPoint + ToOffset> SelectionExt for Selection<T> {
6473    fn point_range(&self, buffer: &MultiBufferSnapshot) -> Range<Point> {
6474        let start = self.start.to_point(buffer);
6475        let end = self.end.to_point(buffer);
6476        if self.reversed {
6477            end..start
6478        } else {
6479            start..end
6480        }
6481    }
6482
6483    fn offset_range(&self, buffer: &MultiBufferSnapshot) -> Range<usize> {
6484        let start = self.start.to_offset(buffer);
6485        let end = self.end.to_offset(buffer);
6486        if self.reversed {
6487            end..start
6488        } else {
6489            start..end
6490        }
6491    }
6492
6493    fn display_range(&self, map: &DisplaySnapshot) -> Range<DisplayPoint> {
6494        let start = self
6495            .start
6496            .to_point(&map.buffer_snapshot)
6497            .to_display_point(map);
6498        let end = self
6499            .end
6500            .to_point(&map.buffer_snapshot)
6501            .to_display_point(map);
6502        if self.reversed {
6503            end..start
6504        } else {
6505            start..end
6506        }
6507    }
6508
6509    fn spanned_rows(
6510        &self,
6511        include_end_if_at_line_start: bool,
6512        map: &DisplaySnapshot,
6513    ) -> Range<u32> {
6514        let start = self.start.to_point(&map.buffer_snapshot);
6515        let mut end = self.end.to_point(&map.buffer_snapshot);
6516        if !include_end_if_at_line_start && start.row != end.row && end.column == 0 {
6517            end.row -= 1;
6518        }
6519
6520        let buffer_start = map.prev_line_boundary(start).0;
6521        let buffer_end = map.next_line_boundary(end).0;
6522        buffer_start.row..buffer_end.row + 1
6523    }
6524}
6525
6526impl<T: InvalidationRegion> InvalidationStack<T> {
6527    fn invalidate<S>(&mut self, selections: &[Selection<S>], buffer: &MultiBufferSnapshot)
6528    where
6529        S: Clone + ToOffset,
6530    {
6531        while let Some(region) = self.last() {
6532            let all_selections_inside_invalidation_ranges =
6533                if selections.len() == region.ranges().len() {
6534                    selections
6535                        .iter()
6536                        .zip(region.ranges().iter().map(|r| r.to_offset(buffer)))
6537                        .all(|(selection, invalidation_range)| {
6538                            let head = selection.head().to_offset(buffer);
6539                            invalidation_range.start <= head && invalidation_range.end >= head
6540                        })
6541                } else {
6542                    false
6543                };
6544
6545            if all_selections_inside_invalidation_ranges {
6546                break;
6547            } else {
6548                self.pop();
6549            }
6550        }
6551    }
6552}
6553
6554impl<T> Default for InvalidationStack<T> {
6555    fn default() -> Self {
6556        Self(Default::default())
6557    }
6558}
6559
6560impl<T> Deref for InvalidationStack<T> {
6561    type Target = Vec<T>;
6562
6563    fn deref(&self) -> &Self::Target {
6564        &self.0
6565    }
6566}
6567
6568impl<T> DerefMut for InvalidationStack<T> {
6569    fn deref_mut(&mut self) -> &mut Self::Target {
6570        &mut self.0
6571    }
6572}
6573
6574impl InvalidationRegion for SnippetState {
6575    fn ranges(&self) -> &[Range<Anchor>] {
6576        &self.ranges[self.active_index]
6577    }
6578}
6579
6580impl Deref for EditorStyle {
6581    type Target = theme::Editor;
6582
6583    fn deref(&self) -> &Self::Target {
6584        &self.theme
6585    }
6586}
6587
6588pub fn diagnostic_block_renderer(diagnostic: Diagnostic, is_valid: bool) -> RenderBlock {
6589    let mut highlighted_lines = Vec::new();
6590    for line in diagnostic.message.lines() {
6591        highlighted_lines.push(highlight_diagnostic_message(line));
6592    }
6593
6594    Arc::new(move |cx: &mut BlockContext| {
6595        let settings = cx.global::<Settings>();
6596        let theme = &settings.theme.editor;
6597        let style = diagnostic_style(diagnostic.severity, is_valid, theme);
6598        let font_size = (style.text_scale_factor * settings.buffer_font_size).round();
6599        Flex::column()
6600            .with_children(highlighted_lines.iter().map(|(line, highlights)| {
6601                Label::new(
6602                    line.clone(),
6603                    style.message.clone().with_font_size(font_size),
6604                )
6605                .with_highlights(highlights.clone())
6606                .contained()
6607                .with_margin_left(cx.anchor_x)
6608                .boxed()
6609            }))
6610            .aligned()
6611            .left()
6612            .boxed()
6613    })
6614}
6615
6616pub fn highlight_diagnostic_message(message: &str) -> (String, Vec<usize>) {
6617    let mut message_without_backticks = String::new();
6618    let mut prev_offset = 0;
6619    let mut inside_block = false;
6620    let mut highlights = Vec::new();
6621    for (match_ix, (offset, _)) in message
6622        .match_indices('`')
6623        .chain([(message.len(), "")])
6624        .enumerate()
6625    {
6626        message_without_backticks.push_str(&message[prev_offset..offset]);
6627        if inside_block {
6628            highlights.extend(prev_offset - match_ix..offset - match_ix);
6629        }
6630
6631        inside_block = !inside_block;
6632        prev_offset = offset + 1;
6633    }
6634
6635    (message_without_backticks, highlights)
6636}
6637
6638pub fn diagnostic_style(
6639    severity: DiagnosticSeverity,
6640    valid: bool,
6641    theme: &theme::Editor,
6642) -> DiagnosticStyle {
6643    match (severity, valid) {
6644        (DiagnosticSeverity::ERROR, true) => theme.error_diagnostic.clone(),
6645        (DiagnosticSeverity::ERROR, false) => theme.invalid_error_diagnostic.clone(),
6646        (DiagnosticSeverity::WARNING, true) => theme.warning_diagnostic.clone(),
6647        (DiagnosticSeverity::WARNING, false) => theme.invalid_warning_diagnostic.clone(),
6648        (DiagnosticSeverity::INFORMATION, true) => theme.information_diagnostic.clone(),
6649        (DiagnosticSeverity::INFORMATION, false) => theme.invalid_information_diagnostic.clone(),
6650        (DiagnosticSeverity::HINT, true) => theme.hint_diagnostic.clone(),
6651        (DiagnosticSeverity::HINT, false) => theme.invalid_hint_diagnostic.clone(),
6652        _ => theme.invalid_hint_diagnostic.clone(),
6653    }
6654}
6655
6656pub fn combine_syntax_and_fuzzy_match_highlights(
6657    text: &str,
6658    default_style: HighlightStyle,
6659    syntax_ranges: impl Iterator<Item = (Range<usize>, HighlightStyle)>,
6660    match_indices: &[usize],
6661) -> Vec<(Range<usize>, HighlightStyle)> {
6662    let mut result = Vec::new();
6663    let mut match_indices = match_indices.iter().copied().peekable();
6664
6665    for (range, mut syntax_highlight) in syntax_ranges.chain([(usize::MAX..0, Default::default())])
6666    {
6667        syntax_highlight.weight = None;
6668
6669        // Add highlights for any fuzzy match characters before the next
6670        // syntax highlight range.
6671        while let Some(&match_index) = match_indices.peek() {
6672            if match_index >= range.start {
6673                break;
6674            }
6675            match_indices.next();
6676            let end_index = char_ix_after(match_index, text);
6677            let mut match_style = default_style;
6678            match_style.weight = Some(fonts::Weight::BOLD);
6679            result.push((match_index..end_index, match_style));
6680        }
6681
6682        if range.start == usize::MAX {
6683            break;
6684        }
6685
6686        // Add highlights for any fuzzy match characters within the
6687        // syntax highlight range.
6688        let mut offset = range.start;
6689        while let Some(&match_index) = match_indices.peek() {
6690            if match_index >= range.end {
6691                break;
6692            }
6693
6694            match_indices.next();
6695            if match_index > offset {
6696                result.push((offset..match_index, syntax_highlight));
6697            }
6698
6699            let mut end_index = char_ix_after(match_index, text);
6700            while let Some(&next_match_index) = match_indices.peek() {
6701                if next_match_index == end_index && next_match_index < range.end {
6702                    end_index = char_ix_after(next_match_index, text);
6703                    match_indices.next();
6704                } else {
6705                    break;
6706                }
6707            }
6708
6709            let mut match_style = syntax_highlight;
6710            match_style.weight = Some(fonts::Weight::BOLD);
6711            result.push((match_index..end_index, match_style));
6712            offset = end_index;
6713        }
6714
6715        if offset < range.end {
6716            result.push((offset..range.end, syntax_highlight));
6717        }
6718    }
6719
6720    fn char_ix_after(ix: usize, text: &str) -> usize {
6721        ix + text[ix..].chars().next().unwrap().len_utf8()
6722    }
6723
6724    result
6725}
6726
6727pub fn styled_runs_for_code_label<'a>(
6728    label: &'a CodeLabel,
6729    syntax_theme: &'a theme::SyntaxTheme,
6730) -> impl 'a + Iterator<Item = (Range<usize>, HighlightStyle)> {
6731    let fade_out = HighlightStyle {
6732        fade_out: Some(0.35),
6733        ..Default::default()
6734    };
6735
6736    let mut prev_end = label.filter_range.end;
6737    label
6738        .runs
6739        .iter()
6740        .enumerate()
6741        .flat_map(move |(ix, (range, highlight_id))| {
6742            let style = if let Some(style) = highlight_id.style(syntax_theme) {
6743                style
6744            } else {
6745                return Default::default();
6746            };
6747            let mut muted_style = style;
6748            muted_style.highlight(fade_out);
6749
6750            let mut runs = SmallVec::<[(Range<usize>, HighlightStyle); 3]>::new();
6751            if range.start >= label.filter_range.end {
6752                if range.start > prev_end {
6753                    runs.push((prev_end..range.start, fade_out));
6754                }
6755                runs.push((range.clone(), muted_style));
6756            } else if range.end <= label.filter_range.end {
6757                runs.push((range.clone(), style));
6758            } else {
6759                runs.push((range.start..label.filter_range.end, style));
6760                runs.push((label.filter_range.end..range.end, muted_style));
6761            }
6762            prev_end = cmp::max(prev_end, range.end);
6763
6764            if ix + 1 == label.runs.len() && label.text.len() > prev_end {
6765                runs.push((prev_end..label.text.len(), fade_out));
6766            }
6767
6768            runs
6769        })
6770}
6771
6772trait RangeExt<T> {
6773    fn sorted(&self) -> Range<T>;
6774    fn to_inclusive(&self) -> RangeInclusive<T>;
6775}
6776
6777impl<T: Ord + Clone> RangeExt<T> for Range<T> {
6778    fn sorted(&self) -> Self {
6779        cmp::min(&self.start, &self.end).clone()..cmp::max(&self.start, &self.end).clone()
6780    }
6781
6782    fn to_inclusive(&self) -> RangeInclusive<T> {
6783        self.start.clone()..=self.end.clone()
6784    }
6785}
6786
6787trait RangeToAnchorExt {
6788    fn to_anchors(self, snapshot: &MultiBufferSnapshot) -> Range<Anchor>;
6789}
6790
6791impl<T: ToOffset> RangeToAnchorExt for Range<T> {
6792    fn to_anchors(self, snapshot: &MultiBufferSnapshot) -> Range<Anchor> {
6793        snapshot.anchor_after(self.start)..snapshot.anchor_before(self.end)
6794    }
6795}