editor.rs

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