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