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