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