editor.rs

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