editor.rs

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