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