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