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