editor.rs

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