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