editor.rs

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