editor.rs

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