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