editor.rs

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