editor.rs

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