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