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