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