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            return;
2838        }
2839
2840        let snapshot = self.buffer.read(cx).snapshot(cx);
2841
2842        self.copilot_state.active_completion_index =
2843            (self.copilot_state.active_completion_index + 1) % self.copilot_state.completions.len();
2844        if let Some(text) = self
2845            .copilot_state
2846            .text_for_active_completion(self.copilot_state.position, &snapshot)
2847        {
2848            self.display_map.update(cx, |map, cx| {
2849                map.replace_suggestion(
2850                    Some(Suggestion {
2851                        position: self.copilot_state.position,
2852                        text: text.into(),
2853                    }),
2854                    cx,
2855                )
2856            });
2857            cx.notify();
2858        }
2859    }
2860
2861    fn accept_copilot_suggestion(&mut self, cx: &mut ViewContext<Self>) -> bool {
2862        let snapshot = self.buffer.read(cx).snapshot(cx);
2863        if let Some(text) = self
2864            .copilot_state
2865            .text_for_active_completion(self.copilot_state.position, &snapshot)
2866            .map(|text| text.to_string())
2867        {
2868            self.copilot_state = Default::default();
2869            self.insert(&text, cx);
2870            true
2871        } else {
2872            false
2873        }
2874    }
2875
2876    fn clear_copilot_suggestions(&mut self, cx: &mut ViewContext<Self>) -> bool {
2877        self.display_map
2878            .update(cx, |map, cx| map.replace_suggestion::<usize>(None, cx));
2879        let was_empty = self.copilot_state.completions.is_empty();
2880        self.copilot_state.completions.clear();
2881        self.copilot_state.active_completion_index = 0;
2882        self.copilot_state.pending_refresh = Task::ready(None);
2883        self.copilot_state.position = Anchor::min();
2884        cx.notify();
2885        !was_empty
2886    }
2887
2888    pub fn render_code_actions_indicator(
2889        &self,
2890        style: &EditorStyle,
2891        active: bool,
2892        cx: &mut RenderContext<Self>,
2893    ) -> Option<ElementBox> {
2894        if self.available_code_actions.is_some() {
2895            enum CodeActions {}
2896            Some(
2897                MouseEventHandler::<CodeActions>::new(0, cx, |state, _| {
2898                    Svg::new("icons/bolt_8.svg")
2899                        .with_color(style.code_actions.indicator.style_for(state, active).color)
2900                        .boxed()
2901                })
2902                .with_cursor_style(CursorStyle::PointingHand)
2903                .with_padding(Padding::uniform(3.))
2904                .on_down(MouseButton::Left, |_, cx| {
2905                    cx.dispatch_action(ToggleCodeActions {
2906                        deployed_from_indicator: true,
2907                    });
2908                })
2909                .boxed(),
2910            )
2911        } else {
2912            None
2913        }
2914    }
2915
2916    pub fn render_fold_indicators(
2917        &self,
2918        fold_data: Vec<Option<(FoldStatus, u32, bool)>>,
2919        style: &EditorStyle,
2920        gutter_hovered: bool,
2921        line_height: f32,
2922        gutter_margin: f32,
2923        cx: &mut RenderContext<Self>,
2924    ) -> Vec<Option<ElementBox>> {
2925        enum FoldIndicators {}
2926
2927        let style = style.folds.clone();
2928
2929        fold_data
2930            .iter()
2931            .enumerate()
2932            .map(|(ix, fold_data)| {
2933                fold_data
2934                    .map(|(fold_status, buffer_row, active)| {
2935                        (active || gutter_hovered || fold_status == FoldStatus::Folded).then(|| {
2936                            MouseEventHandler::<FoldIndicators>::new(
2937                                ix as usize,
2938                                cx,
2939                                |mouse_state, _| -> ElementBox {
2940                                    Svg::new(match fold_status {
2941                                        FoldStatus::Folded => style.folded_icon.clone(),
2942                                        FoldStatus::Foldable => style.foldable_icon.clone(),
2943                                    })
2944                                    .with_color(
2945                                        style
2946                                            .indicator
2947                                            .style_for(
2948                                                mouse_state,
2949                                                fold_status == FoldStatus::Folded,
2950                                            )
2951                                            .color,
2952                                    )
2953                                    .constrained()
2954                                    .with_width(gutter_margin * style.icon_margin_scale)
2955                                    .aligned()
2956                                    .constrained()
2957                                    .with_height(line_height)
2958                                    .with_width(gutter_margin)
2959                                    .aligned()
2960                                    .boxed()
2961                                },
2962                            )
2963                            .with_cursor_style(CursorStyle::PointingHand)
2964                            .with_padding(Padding::uniform(3.))
2965                            .on_click(MouseButton::Left, {
2966                                move |_, cx| {
2967                                    cx.dispatch_any_action(match fold_status {
2968                                        FoldStatus::Folded => Box::new(UnfoldAt { buffer_row }),
2969                                        FoldStatus::Foldable => Box::new(FoldAt { buffer_row }),
2970                                    });
2971                                }
2972                            })
2973                            .boxed()
2974                        })
2975                    })
2976                    .flatten()
2977            })
2978            .collect()
2979    }
2980
2981    pub fn context_menu_visible(&self) -> bool {
2982        self.context_menu
2983            .as_ref()
2984            .map_or(false, |menu| menu.visible())
2985    }
2986
2987    pub fn render_context_menu(
2988        &self,
2989        cursor_position: DisplayPoint,
2990        style: EditorStyle,
2991        cx: &mut RenderContext<Editor>,
2992    ) -> Option<(DisplayPoint, ElementBox)> {
2993        self.context_menu
2994            .as_ref()
2995            .map(|menu| menu.render(cursor_position, style, cx))
2996    }
2997
2998    fn show_context_menu(&mut self, menu: ContextMenu, cx: &mut ViewContext<Self>) {
2999        if !matches!(menu, ContextMenu::Completions(_)) {
3000            self.completion_tasks.clear();
3001        }
3002        self.context_menu = Some(menu);
3003        cx.notify();
3004    }
3005
3006    fn hide_context_menu(&mut self, cx: &mut ViewContext<Self>) -> Option<ContextMenu> {
3007        cx.notify();
3008        self.completion_tasks.clear();
3009        self.context_menu.take()
3010    }
3011
3012    pub fn insert_snippet(
3013        &mut self,
3014        insertion_ranges: &[Range<usize>],
3015        snippet: Snippet,
3016        cx: &mut ViewContext<Self>,
3017    ) -> Result<()> {
3018        let tabstops = self.buffer.update(cx, |buffer, cx| {
3019            let snippet_text: Arc<str> = snippet.text.clone().into();
3020            buffer.edit(
3021                insertion_ranges
3022                    .iter()
3023                    .cloned()
3024                    .map(|range| (range, snippet_text.clone())),
3025                Some(AutoindentMode::EachLine),
3026                cx,
3027            );
3028
3029            let snapshot = &*buffer.read(cx);
3030            let snippet = &snippet;
3031            snippet
3032                .tabstops
3033                .iter()
3034                .map(|tabstop| {
3035                    let mut tabstop_ranges = tabstop
3036                        .iter()
3037                        .flat_map(|tabstop_range| {
3038                            let mut delta = 0_isize;
3039                            insertion_ranges.iter().map(move |insertion_range| {
3040                                let insertion_start = insertion_range.start as isize + delta;
3041                                delta +=
3042                                    snippet.text.len() as isize - insertion_range.len() as isize;
3043
3044                                let start = snapshot.anchor_before(
3045                                    (insertion_start + tabstop_range.start) as usize,
3046                                );
3047                                let end = snapshot
3048                                    .anchor_after((insertion_start + tabstop_range.end) as usize);
3049                                start..end
3050                            })
3051                        })
3052                        .collect::<Vec<_>>();
3053                    tabstop_ranges.sort_unstable_by(|a, b| a.start.cmp(&b.start, snapshot));
3054                    tabstop_ranges
3055                })
3056                .collect::<Vec<_>>()
3057        });
3058
3059        if let Some(tabstop) = tabstops.first() {
3060            self.change_selections(Some(Autoscroll::fit()), cx, |s| {
3061                s.select_ranges(tabstop.iter().cloned());
3062            });
3063            self.snippet_stack.push(SnippetState {
3064                active_index: 0,
3065                ranges: tabstops,
3066            });
3067        }
3068
3069        Ok(())
3070    }
3071
3072    pub fn move_to_next_snippet_tabstop(&mut self, cx: &mut ViewContext<Self>) -> bool {
3073        self.move_to_snippet_tabstop(Bias::Right, cx)
3074    }
3075
3076    pub fn move_to_prev_snippet_tabstop(&mut self, cx: &mut ViewContext<Self>) -> bool {
3077        self.move_to_snippet_tabstop(Bias::Left, cx)
3078    }
3079
3080    pub fn move_to_snippet_tabstop(&mut self, bias: Bias, cx: &mut ViewContext<Self>) -> bool {
3081        if let Some(mut snippet) = self.snippet_stack.pop() {
3082            match bias {
3083                Bias::Left => {
3084                    if snippet.active_index > 0 {
3085                        snippet.active_index -= 1;
3086                    } else {
3087                        self.snippet_stack.push(snippet);
3088                        return false;
3089                    }
3090                }
3091                Bias::Right => {
3092                    if snippet.active_index + 1 < snippet.ranges.len() {
3093                        snippet.active_index += 1;
3094                    } else {
3095                        self.snippet_stack.push(snippet);
3096                        return false;
3097                    }
3098                }
3099            }
3100            if let Some(current_ranges) = snippet.ranges.get(snippet.active_index) {
3101                self.change_selections(Some(Autoscroll::fit()), cx, |s| {
3102                    s.select_anchor_ranges(current_ranges.iter().cloned())
3103                });
3104                // If snippet state is not at the last tabstop, push it back on the stack
3105                if snippet.active_index + 1 < snippet.ranges.len() {
3106                    self.snippet_stack.push(snippet);
3107                }
3108                return true;
3109            }
3110        }
3111
3112        false
3113    }
3114
3115    pub fn clear(&mut self, cx: &mut ViewContext<Self>) {
3116        self.transact(cx, |this, cx| {
3117            this.select_all(&SelectAll, cx);
3118            this.insert("", cx);
3119        });
3120    }
3121
3122    pub fn backspace(&mut self, _: &Backspace, cx: &mut ViewContext<Self>) {
3123        self.transact(cx, |this, cx| {
3124            this.select_autoclose_pair(cx);
3125            let mut selections = this.selections.all::<Point>(cx);
3126            if !this.selections.line_mode {
3127                let display_map = this.display_map.update(cx, |map, cx| map.snapshot(cx));
3128                for selection in &mut selections {
3129                    if selection.is_empty() {
3130                        let old_head = selection.head();
3131                        let mut new_head =
3132                            movement::left(&display_map, old_head.to_display_point(&display_map))
3133                                .to_point(&display_map);
3134                        if let Some((buffer, line_buffer_range)) = display_map
3135                            .buffer_snapshot
3136                            .buffer_line_for_row(old_head.row)
3137                        {
3138                            let indent_size =
3139                                buffer.indent_size_for_line(line_buffer_range.start.row);
3140                            let language_name = buffer
3141                                .language_at(line_buffer_range.start)
3142                                .map(|language| language.name());
3143                            let indent_len = match indent_size.kind {
3144                                IndentKind::Space => {
3145                                    cx.global::<Settings>().tab_size(language_name.as_deref())
3146                                }
3147                                IndentKind::Tab => NonZeroU32::new(1).unwrap(),
3148                            };
3149                            if old_head.column <= indent_size.len && old_head.column > 0 {
3150                                let indent_len = indent_len.get();
3151                                new_head = cmp::min(
3152                                    new_head,
3153                                    Point::new(
3154                                        old_head.row,
3155                                        ((old_head.column - 1) / indent_len) * indent_len,
3156                                    ),
3157                                );
3158                            }
3159                        }
3160
3161                        selection.set_head(new_head, SelectionGoal::None);
3162                    }
3163                }
3164            }
3165
3166            this.change_selections(Some(Autoscroll::fit()), cx, |s| s.select(selections));
3167            this.insert("", cx);
3168        });
3169    }
3170
3171    pub fn delete(&mut self, _: &Delete, cx: &mut ViewContext<Self>) {
3172        self.transact(cx, |this, cx| {
3173            this.change_selections(Some(Autoscroll::fit()), cx, |s| {
3174                let line_mode = s.line_mode;
3175                s.move_with(|map, selection| {
3176                    if selection.is_empty() && !line_mode {
3177                        let cursor = movement::right(map, selection.head());
3178                        selection.set_head(cursor, SelectionGoal::None);
3179                    }
3180                })
3181            });
3182            this.insert("", cx);
3183        });
3184    }
3185
3186    pub fn tab_prev(&mut self, _: &TabPrev, cx: &mut ViewContext<Self>) {
3187        if self.move_to_prev_snippet_tabstop(cx) {
3188            return;
3189        }
3190
3191        self.outdent(&Outdent, cx);
3192    }
3193
3194    pub fn tab(&mut self, _: &Tab, cx: &mut ViewContext<Self>) {
3195        if self.accept_copilot_suggestion(cx) {
3196            return;
3197        }
3198
3199        if self.move_to_next_snippet_tabstop(cx) {
3200            return;
3201        }
3202
3203        let mut selections = self.selections.all_adjusted(cx);
3204        let buffer = self.buffer.read(cx);
3205        let snapshot = buffer.snapshot(cx);
3206        let rows_iter = selections.iter().map(|s| s.head().row);
3207        let suggested_indents = snapshot.suggested_indents(rows_iter, cx);
3208
3209        let mut edits = Vec::new();
3210        let mut prev_edited_row = 0;
3211        let mut row_delta = 0;
3212        for selection in &mut selections {
3213            if selection.start.row != prev_edited_row {
3214                row_delta = 0;
3215            }
3216            prev_edited_row = selection.end.row;
3217
3218            // If the selection is non-empty, then increase the indentation of the selected lines.
3219            if !selection.is_empty() {
3220                row_delta =
3221                    Self::indent_selection(buffer, &snapshot, selection, &mut edits, row_delta, cx);
3222                continue;
3223            }
3224
3225            // If the selection is empty and the cursor is in the leading whitespace before the
3226            // suggested indentation, then auto-indent the line.
3227            let cursor = selection.head();
3228            if let Some(suggested_indent) = suggested_indents.get(&cursor.row).copied() {
3229                let current_indent = snapshot.indent_size_for_line(cursor.row);
3230                if cursor.column < suggested_indent.len
3231                    && cursor.column <= current_indent.len
3232                    && current_indent.len <= suggested_indent.len
3233                {
3234                    selection.start = Point::new(cursor.row, suggested_indent.len);
3235                    selection.end = selection.start;
3236                    if row_delta == 0 {
3237                        edits.extend(Buffer::edit_for_indent_size_adjustment(
3238                            cursor.row,
3239                            current_indent,
3240                            suggested_indent,
3241                        ));
3242                        row_delta = suggested_indent.len - current_indent.len;
3243                    }
3244                    continue;
3245                }
3246            }
3247
3248            // Otherwise, insert a hard or soft tab.
3249            let settings = cx.global::<Settings>();
3250            let language_name = buffer.language_at(cursor, cx).map(|l| l.name());
3251            let tab_size = if settings.hard_tabs(language_name.as_deref()) {
3252                IndentSize::tab()
3253            } else {
3254                let tab_size = settings.tab_size(language_name.as_deref()).get();
3255                let char_column = snapshot
3256                    .text_for_range(Point::new(cursor.row, 0)..cursor)
3257                    .flat_map(str::chars)
3258                    .count()
3259                    + row_delta as usize;
3260                let chars_to_next_tab_stop = tab_size - (char_column as u32 % tab_size);
3261                IndentSize::spaces(chars_to_next_tab_stop)
3262            };
3263            selection.start = Point::new(cursor.row, cursor.column + row_delta + tab_size.len);
3264            selection.end = selection.start;
3265            edits.push((cursor..cursor, tab_size.chars().collect::<String>()));
3266            row_delta += tab_size.len;
3267        }
3268
3269        self.transact(cx, |this, cx| {
3270            this.buffer.update(cx, |b, cx| b.edit(edits, None, cx));
3271            this.change_selections(Some(Autoscroll::fit()), cx, |s| s.select(selections))
3272        });
3273    }
3274
3275    pub fn indent(&mut self, _: &Indent, cx: &mut ViewContext<Self>) {
3276        let mut selections = self.selections.all::<Point>(cx);
3277        let mut prev_edited_row = 0;
3278        let mut row_delta = 0;
3279        let mut edits = Vec::new();
3280        let buffer = self.buffer.read(cx);
3281        let snapshot = buffer.snapshot(cx);
3282        for selection in &mut selections {
3283            if selection.start.row != prev_edited_row {
3284                row_delta = 0;
3285            }
3286            prev_edited_row = selection.end.row;
3287
3288            row_delta =
3289                Self::indent_selection(buffer, &snapshot, selection, &mut edits, row_delta, cx);
3290        }
3291
3292        self.transact(cx, |this, cx| {
3293            this.buffer.update(cx, |b, cx| b.edit(edits, None, cx));
3294            this.change_selections(Some(Autoscroll::fit()), cx, |s| s.select(selections));
3295        });
3296    }
3297
3298    fn indent_selection(
3299        buffer: &MultiBuffer,
3300        snapshot: &MultiBufferSnapshot,
3301        selection: &mut Selection<Point>,
3302        edits: &mut Vec<(Range<Point>, String)>,
3303        delta_for_start_row: u32,
3304        cx: &AppContext,
3305    ) -> u32 {
3306        let language_name = buffer.language_at(selection.start, cx).map(|l| l.name());
3307        let settings = cx.global::<Settings>();
3308        let tab_size = settings.tab_size(language_name.as_deref()).get();
3309        let indent_kind = if settings.hard_tabs(language_name.as_deref()) {
3310            IndentKind::Tab
3311        } else {
3312            IndentKind::Space
3313        };
3314        let mut start_row = selection.start.row;
3315        let mut end_row = selection.end.row + 1;
3316
3317        // If a selection ends at the beginning of a line, don't indent
3318        // that last line.
3319        if selection.end.column == 0 {
3320            end_row -= 1;
3321        }
3322
3323        // Avoid re-indenting a row that has already been indented by a
3324        // previous selection, but still update this selection's column
3325        // to reflect that indentation.
3326        if delta_for_start_row > 0 {
3327            start_row += 1;
3328            selection.start.column += delta_for_start_row;
3329            if selection.end.row == selection.start.row {
3330                selection.end.column += delta_for_start_row;
3331            }
3332        }
3333
3334        let mut delta_for_end_row = 0;
3335        for row in start_row..end_row {
3336            let current_indent = snapshot.indent_size_for_line(row);
3337            let indent_delta = match (current_indent.kind, indent_kind) {
3338                (IndentKind::Space, IndentKind::Space) => {
3339                    let columns_to_next_tab_stop = tab_size - (current_indent.len % tab_size);
3340                    IndentSize::spaces(columns_to_next_tab_stop)
3341                }
3342                (IndentKind::Tab, IndentKind::Space) => IndentSize::spaces(tab_size),
3343                (_, IndentKind::Tab) => IndentSize::tab(),
3344            };
3345
3346            let row_start = Point::new(row, 0);
3347            edits.push((
3348                row_start..row_start,
3349                indent_delta.chars().collect::<String>(),
3350            ));
3351
3352            // Update this selection's endpoints to reflect the indentation.
3353            if row == selection.start.row {
3354                selection.start.column += indent_delta.len;
3355            }
3356            if row == selection.end.row {
3357                selection.end.column += indent_delta.len;
3358                delta_for_end_row = indent_delta.len;
3359            }
3360        }
3361
3362        if selection.start.row == selection.end.row {
3363            delta_for_start_row + delta_for_end_row
3364        } else {
3365            delta_for_end_row
3366        }
3367    }
3368
3369    pub fn outdent(&mut self, _: &Outdent, cx: &mut ViewContext<Self>) {
3370        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
3371        let selections = self.selections.all::<Point>(cx);
3372        let mut deletion_ranges = Vec::new();
3373        let mut last_outdent = None;
3374        {
3375            let buffer = self.buffer.read(cx);
3376            let snapshot = buffer.snapshot(cx);
3377            for selection in &selections {
3378                let language_name = buffer.language_at(selection.start, cx).map(|l| l.name());
3379                let tab_size = cx
3380                    .global::<Settings>()
3381                    .tab_size(language_name.as_deref())
3382                    .get();
3383                let mut rows = selection.spanned_rows(false, &display_map);
3384
3385                // Avoid re-outdenting a row that has already been outdented by a
3386                // previous selection.
3387                if let Some(last_row) = last_outdent {
3388                    if last_row == rows.start {
3389                        rows.start += 1;
3390                    }
3391                }
3392
3393                for row in rows {
3394                    let indent_size = snapshot.indent_size_for_line(row);
3395                    if indent_size.len > 0 {
3396                        let deletion_len = match indent_size.kind {
3397                            IndentKind::Space => {
3398                                let columns_to_prev_tab_stop = indent_size.len % tab_size;
3399                                if columns_to_prev_tab_stop == 0 {
3400                                    tab_size
3401                                } else {
3402                                    columns_to_prev_tab_stop
3403                                }
3404                            }
3405                            IndentKind::Tab => 1,
3406                        };
3407                        deletion_ranges.push(Point::new(row, 0)..Point::new(row, deletion_len));
3408                        last_outdent = Some(row);
3409                    }
3410                }
3411            }
3412        }
3413
3414        self.transact(cx, |this, cx| {
3415            this.buffer.update(cx, |buffer, cx| {
3416                let empty_str: Arc<str> = "".into();
3417                buffer.edit(
3418                    deletion_ranges
3419                        .into_iter()
3420                        .map(|range| (range, empty_str.clone())),
3421                    None,
3422                    cx,
3423                );
3424            });
3425            let selections = this.selections.all::<usize>(cx);
3426            this.change_selections(Some(Autoscroll::fit()), cx, |s| s.select(selections));
3427        });
3428    }
3429
3430    pub fn delete_line(&mut self, _: &DeleteLine, cx: &mut ViewContext<Self>) {
3431        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
3432        let selections = self.selections.all::<Point>(cx);
3433
3434        let mut new_cursors = Vec::new();
3435        let mut edit_ranges = Vec::new();
3436        let mut selections = selections.iter().peekable();
3437        while let Some(selection) = selections.next() {
3438            let mut rows = selection.spanned_rows(false, &display_map);
3439            let goal_display_column = selection.head().to_display_point(&display_map).column();
3440
3441            // Accumulate contiguous regions of rows that we want to delete.
3442            while let Some(next_selection) = selections.peek() {
3443                let next_rows = next_selection.spanned_rows(false, &display_map);
3444                if next_rows.start <= rows.end {
3445                    rows.end = next_rows.end;
3446                    selections.next().unwrap();
3447                } else {
3448                    break;
3449                }
3450            }
3451
3452            let buffer = &display_map.buffer_snapshot;
3453            let mut edit_start = Point::new(rows.start, 0).to_offset(buffer);
3454            let edit_end;
3455            let cursor_buffer_row;
3456            if buffer.max_point().row >= rows.end {
3457                // If there's a line after the range, delete the \n from the end of the row range
3458                // and position the cursor on the next line.
3459                edit_end = Point::new(rows.end, 0).to_offset(buffer);
3460                cursor_buffer_row = rows.end;
3461            } else {
3462                // If there isn't a line after the range, delete the \n from the line before the
3463                // start of the row range and position the cursor there.
3464                edit_start = edit_start.saturating_sub(1);
3465                edit_end = buffer.len();
3466                cursor_buffer_row = rows.start.saturating_sub(1);
3467            }
3468
3469            let mut cursor = Point::new(cursor_buffer_row, 0).to_display_point(&display_map);
3470            *cursor.column_mut() =
3471                cmp::min(goal_display_column, display_map.line_len(cursor.row()));
3472
3473            new_cursors.push((
3474                selection.id,
3475                buffer.anchor_after(cursor.to_point(&display_map)),
3476            ));
3477            edit_ranges.push(edit_start..edit_end);
3478        }
3479
3480        self.transact(cx, |this, cx| {
3481            let buffer = this.buffer.update(cx, |buffer, cx| {
3482                let empty_str: Arc<str> = "".into();
3483                buffer.edit(
3484                    edit_ranges
3485                        .into_iter()
3486                        .map(|range| (range, empty_str.clone())),
3487                    None,
3488                    cx,
3489                );
3490                buffer.snapshot(cx)
3491            });
3492            let new_selections = new_cursors
3493                .into_iter()
3494                .map(|(id, cursor)| {
3495                    let cursor = cursor.to_point(&buffer);
3496                    Selection {
3497                        id,
3498                        start: cursor,
3499                        end: cursor,
3500                        reversed: false,
3501                        goal: SelectionGoal::None,
3502                    }
3503                })
3504                .collect();
3505
3506            this.change_selections(Some(Autoscroll::fit()), cx, |s| {
3507                s.select(new_selections);
3508            });
3509        });
3510    }
3511
3512    pub fn duplicate_line(&mut self, _: &DuplicateLine, cx: &mut ViewContext<Self>) {
3513        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
3514        let buffer = &display_map.buffer_snapshot;
3515        let selections = self.selections.all::<Point>(cx);
3516
3517        let mut edits = Vec::new();
3518        let mut selections_iter = selections.iter().peekable();
3519        while let Some(selection) = selections_iter.next() {
3520            // Avoid duplicating the same lines twice.
3521            let mut rows = selection.spanned_rows(false, &display_map);
3522
3523            while let Some(next_selection) = selections_iter.peek() {
3524                let next_rows = next_selection.spanned_rows(false, &display_map);
3525                if next_rows.start < rows.end {
3526                    rows.end = next_rows.end;
3527                    selections_iter.next().unwrap();
3528                } else {
3529                    break;
3530                }
3531            }
3532
3533            // Copy the text from the selected row region and splice it at the start of the region.
3534            let start = Point::new(rows.start, 0);
3535            let end = Point::new(rows.end - 1, buffer.line_len(rows.end - 1));
3536            let text = buffer
3537                .text_for_range(start..end)
3538                .chain(Some("\n"))
3539                .collect::<String>();
3540            edits.push((start..start, text));
3541        }
3542
3543        self.transact(cx, |this, cx| {
3544            this.buffer.update(cx, |buffer, cx| {
3545                buffer.edit(edits, None, cx);
3546            });
3547
3548            this.request_autoscroll(Autoscroll::fit(), cx);
3549        });
3550    }
3551
3552    pub fn move_line_up(&mut self, _: &MoveLineUp, cx: &mut ViewContext<Self>) {
3553        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
3554        let buffer = self.buffer.read(cx).snapshot(cx);
3555
3556        let mut edits = Vec::new();
3557        let mut unfold_ranges = Vec::new();
3558        let mut refold_ranges = Vec::new();
3559
3560        let selections = self.selections.all::<Point>(cx);
3561        let mut selections = selections.iter().peekable();
3562        let mut contiguous_row_selections = Vec::new();
3563        let mut new_selections = Vec::new();
3564
3565        while let Some(selection) = selections.next() {
3566            // Find all the selections that span a contiguous row range
3567            let (start_row, end_row) = consume_contiguous_rows(
3568                &mut contiguous_row_selections,
3569                selection,
3570                &display_map,
3571                &mut selections,
3572            );
3573
3574            // Move the text spanned by the row range to be before the line preceding the row range
3575            if start_row > 0 {
3576                let range_to_move = Point::new(start_row - 1, buffer.line_len(start_row - 1))
3577                    ..Point::new(end_row - 1, buffer.line_len(end_row - 1));
3578                let insertion_point = display_map
3579                    .prev_line_boundary(Point::new(start_row - 1, 0))
3580                    .0;
3581
3582                // Don't move lines across excerpts
3583                if buffer
3584                    .excerpt_boundaries_in_range((
3585                        Bound::Excluded(insertion_point),
3586                        Bound::Included(range_to_move.end),
3587                    ))
3588                    .next()
3589                    .is_none()
3590                {
3591                    let text = buffer
3592                        .text_for_range(range_to_move.clone())
3593                        .flat_map(|s| s.chars())
3594                        .skip(1)
3595                        .chain(['\n'])
3596                        .collect::<String>();
3597
3598                    edits.push((
3599                        buffer.anchor_after(range_to_move.start)
3600                            ..buffer.anchor_before(range_to_move.end),
3601                        String::new(),
3602                    ));
3603                    let insertion_anchor = buffer.anchor_after(insertion_point);
3604                    edits.push((insertion_anchor..insertion_anchor, text));
3605
3606                    let row_delta = range_to_move.start.row - insertion_point.row + 1;
3607
3608                    // Move selections up
3609                    new_selections.extend(contiguous_row_selections.drain(..).map(
3610                        |mut selection| {
3611                            selection.start.row -= row_delta;
3612                            selection.end.row -= row_delta;
3613                            selection
3614                        },
3615                    ));
3616
3617                    // Move folds up
3618                    unfold_ranges.push(range_to_move.clone());
3619                    for fold in display_map.folds_in_range(
3620                        buffer.anchor_before(range_to_move.start)
3621                            ..buffer.anchor_after(range_to_move.end),
3622                    ) {
3623                        let mut start = fold.start.to_point(&buffer);
3624                        let mut end = fold.end.to_point(&buffer);
3625                        start.row -= row_delta;
3626                        end.row -= row_delta;
3627                        refold_ranges.push(start..end);
3628                    }
3629                }
3630            }
3631
3632            // If we didn't move line(s), preserve the existing selections
3633            new_selections.append(&mut contiguous_row_selections);
3634        }
3635
3636        self.transact(cx, |this, cx| {
3637            this.unfold_ranges(unfold_ranges, true, true, cx);
3638            this.buffer.update(cx, |buffer, cx| {
3639                for (range, text) in edits {
3640                    buffer.edit([(range, text)], None, cx);
3641                }
3642            });
3643            this.fold_ranges(refold_ranges, true, cx);
3644            this.change_selections(Some(Autoscroll::fit()), cx, |s| {
3645                s.select(new_selections);
3646            })
3647        });
3648    }
3649
3650    pub fn move_line_down(&mut self, _: &MoveLineDown, cx: &mut ViewContext<Self>) {
3651        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
3652        let buffer = self.buffer.read(cx).snapshot(cx);
3653
3654        let mut edits = Vec::new();
3655        let mut unfold_ranges = Vec::new();
3656        let mut refold_ranges = Vec::new();
3657
3658        let selections = self.selections.all::<Point>(cx);
3659        let mut selections = selections.iter().peekable();
3660        let mut contiguous_row_selections = Vec::new();
3661        let mut new_selections = Vec::new();
3662
3663        while let Some(selection) = selections.next() {
3664            // Find all the selections that span a contiguous row range
3665            let (start_row, end_row) = consume_contiguous_rows(
3666                &mut contiguous_row_selections,
3667                selection,
3668                &display_map,
3669                &mut selections,
3670            );
3671
3672            // Move the text spanned by the row range to be after the last line of the row range
3673            if end_row <= buffer.max_point().row {
3674                let range_to_move = Point::new(start_row, 0)..Point::new(end_row, 0);
3675                let insertion_point = display_map.next_line_boundary(Point::new(end_row, 0)).0;
3676
3677                // Don't move lines across excerpt boundaries
3678                if buffer
3679                    .excerpt_boundaries_in_range((
3680                        Bound::Excluded(range_to_move.start),
3681                        Bound::Included(insertion_point),
3682                    ))
3683                    .next()
3684                    .is_none()
3685                {
3686                    let mut text = String::from("\n");
3687                    text.extend(buffer.text_for_range(range_to_move.clone()));
3688                    text.pop(); // Drop trailing newline
3689                    edits.push((
3690                        buffer.anchor_after(range_to_move.start)
3691                            ..buffer.anchor_before(range_to_move.end),
3692                        String::new(),
3693                    ));
3694                    let insertion_anchor = buffer.anchor_after(insertion_point);
3695                    edits.push((insertion_anchor..insertion_anchor, text));
3696
3697                    let row_delta = insertion_point.row - range_to_move.end.row + 1;
3698
3699                    // Move selections down
3700                    new_selections.extend(contiguous_row_selections.drain(..).map(
3701                        |mut selection| {
3702                            selection.start.row += row_delta;
3703                            selection.end.row += row_delta;
3704                            selection
3705                        },
3706                    ));
3707
3708                    // Move folds down
3709                    unfold_ranges.push(range_to_move.clone());
3710                    for fold in display_map.folds_in_range(
3711                        buffer.anchor_before(range_to_move.start)
3712                            ..buffer.anchor_after(range_to_move.end),
3713                    ) {
3714                        let mut start = fold.start.to_point(&buffer);
3715                        let mut end = fold.end.to_point(&buffer);
3716                        start.row += row_delta;
3717                        end.row += row_delta;
3718                        refold_ranges.push(start..end);
3719                    }
3720                }
3721            }
3722
3723            // If we didn't move line(s), preserve the existing selections
3724            new_selections.append(&mut contiguous_row_selections);
3725        }
3726
3727        self.transact(cx, |this, cx| {
3728            this.unfold_ranges(unfold_ranges, true, true, cx);
3729            this.buffer.update(cx, |buffer, cx| {
3730                for (range, text) in edits {
3731                    buffer.edit([(range, text)], None, cx);
3732                }
3733            });
3734            this.fold_ranges(refold_ranges, true, cx);
3735            this.change_selections(Some(Autoscroll::fit()), cx, |s| s.select(new_selections));
3736        });
3737    }
3738
3739    pub fn transpose(&mut self, _: &Transpose, cx: &mut ViewContext<Self>) {
3740        self.transact(cx, |this, cx| {
3741            let edits = this.change_selections(Some(Autoscroll::fit()), cx, |s| {
3742                let mut edits: Vec<(Range<usize>, String)> = Default::default();
3743                let line_mode = s.line_mode;
3744                s.move_with(|display_map, selection| {
3745                    if !selection.is_empty() || line_mode {
3746                        return;
3747                    }
3748
3749                    let mut head = selection.head();
3750                    let mut transpose_offset = head.to_offset(display_map, Bias::Right);
3751                    if head.column() == display_map.line_len(head.row()) {
3752                        transpose_offset = display_map
3753                            .buffer_snapshot
3754                            .clip_offset(transpose_offset.saturating_sub(1), Bias::Left);
3755                    }
3756
3757                    if transpose_offset == 0 {
3758                        return;
3759                    }
3760
3761                    *head.column_mut() += 1;
3762                    head = display_map.clip_point(head, Bias::Right);
3763                    selection.collapse_to(head, SelectionGoal::Column(head.column()));
3764
3765                    let transpose_start = display_map
3766                        .buffer_snapshot
3767                        .clip_offset(transpose_offset.saturating_sub(1), Bias::Left);
3768                    if edits.last().map_or(true, |e| e.0.end <= transpose_start) {
3769                        let transpose_end = display_map
3770                            .buffer_snapshot
3771                            .clip_offset(transpose_offset + 1, Bias::Right);
3772                        if let Some(ch) =
3773                            display_map.buffer_snapshot.chars_at(transpose_start).next()
3774                        {
3775                            edits.push((transpose_start..transpose_offset, String::new()));
3776                            edits.push((transpose_end..transpose_end, ch.to_string()));
3777                        }
3778                    }
3779                });
3780                edits
3781            });
3782            this.buffer
3783                .update(cx, |buffer, cx| buffer.edit(edits, None, cx));
3784            let selections = this.selections.all::<usize>(cx);
3785            this.change_selections(Some(Autoscroll::fit()), cx, |s| {
3786                s.select(selections);
3787            });
3788        });
3789    }
3790
3791    pub fn cut(&mut self, _: &Cut, cx: &mut ViewContext<Self>) {
3792        let mut text = String::new();
3793        let buffer = self.buffer.read(cx).snapshot(cx);
3794        let mut selections = self.selections.all::<Point>(cx);
3795        let mut clipboard_selections = Vec::with_capacity(selections.len());
3796        {
3797            let max_point = buffer.max_point();
3798            for selection in &mut selections {
3799                let is_entire_line = selection.is_empty() || self.selections.line_mode;
3800                if is_entire_line {
3801                    selection.start = Point::new(selection.start.row, 0);
3802                    selection.end = cmp::min(max_point, Point::new(selection.end.row + 1, 0));
3803                    selection.goal = SelectionGoal::None;
3804                }
3805                let mut len = 0;
3806                for chunk in buffer.text_for_range(selection.start..selection.end) {
3807                    text.push_str(chunk);
3808                    len += chunk.len();
3809                }
3810                clipboard_selections.push(ClipboardSelection {
3811                    len,
3812                    is_entire_line,
3813                    first_line_indent: buffer.indent_size_for_line(selection.start.row).len,
3814                });
3815            }
3816        }
3817
3818        self.transact(cx, |this, cx| {
3819            this.change_selections(Some(Autoscroll::fit()), cx, |s| {
3820                s.select(selections);
3821            });
3822            this.insert("", cx);
3823            cx.write_to_clipboard(ClipboardItem::new(text).with_metadata(clipboard_selections));
3824        });
3825    }
3826
3827    pub fn copy(&mut self, _: &Copy, cx: &mut ViewContext<Self>) {
3828        let selections = self.selections.all::<Point>(cx);
3829        let buffer = self.buffer.read(cx).read(cx);
3830        let mut text = String::new();
3831
3832        let mut clipboard_selections = Vec::with_capacity(selections.len());
3833        {
3834            let max_point = buffer.max_point();
3835            for selection in selections.iter() {
3836                let mut start = selection.start;
3837                let mut end = selection.end;
3838                let is_entire_line = selection.is_empty() || self.selections.line_mode;
3839                if is_entire_line {
3840                    start = Point::new(start.row, 0);
3841                    end = cmp::min(max_point, Point::new(end.row + 1, 0));
3842                }
3843                let mut len = 0;
3844                for chunk in buffer.text_for_range(start..end) {
3845                    text.push_str(chunk);
3846                    len += chunk.len();
3847                }
3848                clipboard_selections.push(ClipboardSelection {
3849                    len,
3850                    is_entire_line,
3851                    first_line_indent: buffer.indent_size_for_line(start.row).len,
3852                });
3853            }
3854        }
3855
3856        cx.write_to_clipboard(ClipboardItem::new(text).with_metadata(clipboard_selections));
3857    }
3858
3859    pub fn paste(&mut self, _: &Paste, cx: &mut ViewContext<Self>) {
3860        self.transact(cx, |this, cx| {
3861            if let Some(item) = cx.as_mut().read_from_clipboard() {
3862                let mut clipboard_text = Cow::Borrowed(item.text());
3863                if let Some(mut clipboard_selections) = item.metadata::<Vec<ClipboardSelection>>() {
3864                    let old_selections = this.selections.all::<usize>(cx);
3865                    let all_selections_were_entire_line =
3866                        clipboard_selections.iter().all(|s| s.is_entire_line);
3867                    let first_selection_indent_column =
3868                        clipboard_selections.first().map(|s| s.first_line_indent);
3869                    if clipboard_selections.len() != old_selections.len() {
3870                        let mut newline_separated_text = String::new();
3871                        let mut clipboard_selections = clipboard_selections.drain(..).peekable();
3872                        let mut ix = 0;
3873                        while let Some(clipboard_selection) = clipboard_selections.next() {
3874                            newline_separated_text
3875                                .push_str(&clipboard_text[ix..ix + clipboard_selection.len]);
3876                            ix += clipboard_selection.len;
3877                            if clipboard_selections.peek().is_some() {
3878                                newline_separated_text.push('\n');
3879                            }
3880                        }
3881                        clipboard_text = Cow::Owned(newline_separated_text);
3882                    }
3883
3884                    this.buffer.update(cx, |buffer, cx| {
3885                        let snapshot = buffer.read(cx);
3886                        let mut start_offset = 0;
3887                        let mut edits = Vec::new();
3888                        let mut original_indent_columns = Vec::new();
3889                        let line_mode = this.selections.line_mode;
3890                        for (ix, selection) in old_selections.iter().enumerate() {
3891                            let to_insert;
3892                            let entire_line;
3893                            let original_indent_column;
3894                            if let Some(clipboard_selection) = clipboard_selections.get(ix) {
3895                                let end_offset = start_offset + clipboard_selection.len;
3896                                to_insert = &clipboard_text[start_offset..end_offset];
3897                                entire_line = clipboard_selection.is_entire_line;
3898                                start_offset = end_offset;
3899                                original_indent_column =
3900                                    Some(clipboard_selection.first_line_indent);
3901                            } else {
3902                                to_insert = clipboard_text.as_str();
3903                                entire_line = all_selections_were_entire_line;
3904                                original_indent_column = first_selection_indent_column
3905                            }
3906
3907                            // If the corresponding selection was empty when this slice of the
3908                            // clipboard text was written, then the entire line containing the
3909                            // selection was copied. If this selection is also currently empty,
3910                            // then paste the line before the current line of the buffer.
3911                            let range = if selection.is_empty() && !line_mode && entire_line {
3912                                let column = selection.start.to_point(&snapshot).column as usize;
3913                                let line_start = selection.start - column;
3914                                line_start..line_start
3915                            } else {
3916                                selection.range()
3917                            };
3918
3919                            edits.push((range, to_insert));
3920                            original_indent_columns.extend(original_indent_column);
3921                        }
3922                        drop(snapshot);
3923
3924                        buffer.edit(
3925                            edits,
3926                            Some(AutoindentMode::Block {
3927                                original_indent_columns,
3928                            }),
3929                            cx,
3930                        );
3931                    });
3932
3933                    let selections = this.selections.all::<usize>(cx);
3934                    this.change_selections(Some(Autoscroll::fit()), cx, |s| s.select(selections));
3935                } else {
3936                    this.insert(&clipboard_text, cx);
3937                }
3938            }
3939        });
3940    }
3941
3942    pub fn undo(&mut self, _: &Undo, cx: &mut ViewContext<Self>) {
3943        if let Some(tx_id) = self.buffer.update(cx, |buffer, cx| buffer.undo(cx)) {
3944            if let Some((selections, _)) = self.selection_history.transaction(tx_id).cloned() {
3945                self.change_selections(None, cx, |s| {
3946                    s.select_anchors(selections.to_vec());
3947                });
3948            }
3949            self.request_autoscroll(Autoscroll::fit(), cx);
3950            self.unmark_text(cx);
3951            cx.emit(Event::Edited);
3952        }
3953    }
3954
3955    pub fn redo(&mut self, _: &Redo, cx: &mut ViewContext<Self>) {
3956        if let Some(tx_id) = self.buffer.update(cx, |buffer, cx| buffer.redo(cx)) {
3957            if let Some((_, Some(selections))) = self.selection_history.transaction(tx_id).cloned()
3958            {
3959                self.change_selections(None, cx, |s| {
3960                    s.select_anchors(selections.to_vec());
3961                });
3962            }
3963            self.request_autoscroll(Autoscroll::fit(), cx);
3964            self.unmark_text(cx);
3965            cx.emit(Event::Edited);
3966        }
3967    }
3968
3969    pub fn finalize_last_transaction(&mut self, cx: &mut ViewContext<Self>) {
3970        self.buffer
3971            .update(cx, |buffer, cx| buffer.finalize_last_transaction(cx));
3972    }
3973
3974    pub fn move_left(&mut self, _: &MoveLeft, cx: &mut ViewContext<Self>) {
3975        self.change_selections(Some(Autoscroll::fit()), cx, |s| {
3976            let line_mode = s.line_mode;
3977            s.move_with(|map, selection| {
3978                let cursor = if selection.is_empty() && !line_mode {
3979                    movement::left(map, selection.start)
3980                } else {
3981                    selection.start
3982                };
3983                selection.collapse_to(cursor, SelectionGoal::None);
3984            });
3985        })
3986    }
3987
3988    pub fn select_left(&mut self, _: &SelectLeft, cx: &mut ViewContext<Self>) {
3989        self.change_selections(Some(Autoscroll::fit()), cx, |s| {
3990            s.move_heads_with(|map, head, _| (movement::left(map, head), SelectionGoal::None));
3991        })
3992    }
3993
3994    pub fn move_right(&mut self, _: &MoveRight, cx: &mut ViewContext<Self>) {
3995        self.change_selections(Some(Autoscroll::fit()), cx, |s| {
3996            let line_mode = s.line_mode;
3997            s.move_with(|map, selection| {
3998                let cursor = if selection.is_empty() && !line_mode {
3999                    movement::right(map, selection.end)
4000                } else {
4001                    selection.end
4002                };
4003                selection.collapse_to(cursor, SelectionGoal::None)
4004            });
4005        })
4006    }
4007
4008    pub fn select_right(&mut self, _: &SelectRight, cx: &mut ViewContext<Self>) {
4009        self.change_selections(Some(Autoscroll::fit()), cx, |s| {
4010            s.move_heads_with(|map, head, _| (movement::right(map, head), SelectionGoal::None));
4011        })
4012    }
4013
4014    pub fn move_up(&mut self, _: &MoveUp, cx: &mut ViewContext<Self>) {
4015        if self.take_rename(true, cx).is_some() {
4016            return;
4017        }
4018
4019        if let Some(context_menu) = self.context_menu.as_mut() {
4020            if context_menu.select_prev(cx) {
4021                return;
4022            }
4023        }
4024
4025        if matches!(self.mode, EditorMode::SingleLine) {
4026            cx.propagate_action();
4027            return;
4028        }
4029
4030        self.change_selections(Some(Autoscroll::fit()), cx, |s| {
4031            let line_mode = s.line_mode;
4032            s.move_with(|map, selection| {
4033                if !selection.is_empty() && !line_mode {
4034                    selection.goal = SelectionGoal::None;
4035                }
4036                let (cursor, goal) = movement::up(map, selection.start, selection.goal, false);
4037                selection.collapse_to(cursor, goal);
4038            });
4039        })
4040    }
4041
4042    pub fn move_page_up(&mut self, action: &MovePageUp, cx: &mut ViewContext<Self>) {
4043        if self.take_rename(true, cx).is_some() {
4044            return;
4045        }
4046
4047        if self
4048            .context_menu
4049            .as_mut()
4050            .map(|menu| menu.select_first(cx))
4051            .unwrap_or(false)
4052        {
4053            return;
4054        }
4055
4056        if matches!(self.mode, EditorMode::SingleLine) {
4057            cx.propagate_action();
4058            return;
4059        }
4060
4061        let row_count = if let Some(row_count) = self.visible_line_count() {
4062            row_count as u32 - 1
4063        } else {
4064            return;
4065        };
4066
4067        let autoscroll = if action.center_cursor {
4068            Autoscroll::center()
4069        } else {
4070            Autoscroll::fit()
4071        };
4072
4073        self.change_selections(Some(autoscroll), cx, |s| {
4074            let line_mode = s.line_mode;
4075            s.move_with(|map, selection| {
4076                if !selection.is_empty() && !line_mode {
4077                    selection.goal = SelectionGoal::None;
4078                }
4079                let (cursor, goal) =
4080                    movement::up_by_rows(map, selection.end, row_count, selection.goal, false);
4081                selection.collapse_to(cursor, goal);
4082            });
4083        });
4084    }
4085
4086    pub fn select_up(&mut self, _: &SelectUp, cx: &mut ViewContext<Self>) {
4087        self.change_selections(Some(Autoscroll::fit()), cx, |s| {
4088            s.move_heads_with(|map, head, goal| movement::up(map, head, goal, false))
4089        })
4090    }
4091
4092    pub fn move_down(&mut self, _: &MoveDown, cx: &mut ViewContext<Self>) {
4093        self.take_rename(true, cx);
4094
4095        if let Some(context_menu) = self.context_menu.as_mut() {
4096            if context_menu.select_next(cx) {
4097                return;
4098            }
4099        }
4100
4101        if self.mode == EditorMode::SingleLine {
4102            cx.propagate_action();
4103            return;
4104        }
4105
4106        self.change_selections(Some(Autoscroll::fit()), cx, |s| {
4107            let line_mode = s.line_mode;
4108            s.move_with(|map, selection| {
4109                if !selection.is_empty() && !line_mode {
4110                    selection.goal = SelectionGoal::None;
4111                }
4112                let (cursor, goal) = movement::down(map, selection.end, selection.goal, false);
4113                selection.collapse_to(cursor, goal);
4114            });
4115        });
4116    }
4117
4118    pub fn move_page_down(&mut self, action: &MovePageDown, cx: &mut ViewContext<Self>) {
4119        if self.take_rename(true, cx).is_some() {
4120            return;
4121        }
4122
4123        if self
4124            .context_menu
4125            .as_mut()
4126            .map(|menu| menu.select_last(cx))
4127            .unwrap_or(false)
4128        {
4129            return;
4130        }
4131
4132        if matches!(self.mode, EditorMode::SingleLine) {
4133            cx.propagate_action();
4134            return;
4135        }
4136
4137        let row_count = if let Some(row_count) = self.visible_line_count() {
4138            row_count as u32 - 1
4139        } else {
4140            return;
4141        };
4142
4143        let autoscroll = if action.center_cursor {
4144            Autoscroll::center()
4145        } else {
4146            Autoscroll::fit()
4147        };
4148
4149        self.change_selections(Some(autoscroll), cx, |s| {
4150            let line_mode = s.line_mode;
4151            s.move_with(|map, selection| {
4152                if !selection.is_empty() && !line_mode {
4153                    selection.goal = SelectionGoal::None;
4154                }
4155                let (cursor, goal) =
4156                    movement::down_by_rows(map, selection.end, row_count, selection.goal, false);
4157                selection.collapse_to(cursor, goal);
4158            });
4159        });
4160    }
4161
4162    pub fn select_down(&mut self, _: &SelectDown, cx: &mut ViewContext<Self>) {
4163        self.change_selections(Some(Autoscroll::fit()), cx, |s| {
4164            s.move_heads_with(|map, head, goal| movement::down(map, head, goal, false))
4165        });
4166    }
4167
4168    pub fn move_to_previous_word_start(
4169        &mut self,
4170        _: &MoveToPreviousWordStart,
4171        cx: &mut ViewContext<Self>,
4172    ) {
4173        self.change_selections(Some(Autoscroll::fit()), cx, |s| {
4174            s.move_cursors_with(|map, head, _| {
4175                (
4176                    movement::previous_word_start(map, head),
4177                    SelectionGoal::None,
4178                )
4179            });
4180        })
4181    }
4182
4183    pub fn move_to_previous_subword_start(
4184        &mut self,
4185        _: &MoveToPreviousSubwordStart,
4186        cx: &mut ViewContext<Self>,
4187    ) {
4188        self.change_selections(Some(Autoscroll::fit()), cx, |s| {
4189            s.move_cursors_with(|map, head, _| {
4190                (
4191                    movement::previous_subword_start(map, head),
4192                    SelectionGoal::None,
4193                )
4194            });
4195        })
4196    }
4197
4198    pub fn select_to_previous_word_start(
4199        &mut self,
4200        _: &SelectToPreviousWordStart,
4201        cx: &mut ViewContext<Self>,
4202    ) {
4203        self.change_selections(Some(Autoscroll::fit()), cx, |s| {
4204            s.move_heads_with(|map, head, _| {
4205                (
4206                    movement::previous_word_start(map, head),
4207                    SelectionGoal::None,
4208                )
4209            });
4210        })
4211    }
4212
4213    pub fn select_to_previous_subword_start(
4214        &mut self,
4215        _: &SelectToPreviousSubwordStart,
4216        cx: &mut ViewContext<Self>,
4217    ) {
4218        self.change_selections(Some(Autoscroll::fit()), cx, |s| {
4219            s.move_heads_with(|map, head, _| {
4220                (
4221                    movement::previous_subword_start(map, head),
4222                    SelectionGoal::None,
4223                )
4224            });
4225        })
4226    }
4227
4228    pub fn delete_to_previous_word_start(
4229        &mut self,
4230        _: &DeleteToPreviousWordStart,
4231        cx: &mut ViewContext<Self>,
4232    ) {
4233        self.transact(cx, |this, cx| {
4234            this.select_autoclose_pair(cx);
4235            this.change_selections(Some(Autoscroll::fit()), cx, |s| {
4236                let line_mode = s.line_mode;
4237                s.move_with(|map, selection| {
4238                    if selection.is_empty() && !line_mode {
4239                        let cursor = movement::previous_word_start(map, selection.head());
4240                        selection.set_head(cursor, SelectionGoal::None);
4241                    }
4242                });
4243            });
4244            this.insert("", cx);
4245        });
4246    }
4247
4248    pub fn delete_to_previous_subword_start(
4249        &mut self,
4250        _: &DeleteToPreviousSubwordStart,
4251        cx: &mut ViewContext<Self>,
4252    ) {
4253        self.transact(cx, |this, cx| {
4254            this.select_autoclose_pair(cx);
4255            this.change_selections(Some(Autoscroll::fit()), cx, |s| {
4256                let line_mode = s.line_mode;
4257                s.move_with(|map, selection| {
4258                    if selection.is_empty() && !line_mode {
4259                        let cursor = movement::previous_subword_start(map, selection.head());
4260                        selection.set_head(cursor, SelectionGoal::None);
4261                    }
4262                });
4263            });
4264            this.insert("", cx);
4265        });
4266    }
4267
4268    pub fn move_to_next_word_end(&mut self, _: &MoveToNextWordEnd, cx: &mut ViewContext<Self>) {
4269        self.change_selections(Some(Autoscroll::fit()), cx, |s| {
4270            s.move_cursors_with(|map, head, _| {
4271                (movement::next_word_end(map, head), SelectionGoal::None)
4272            });
4273        })
4274    }
4275
4276    pub fn move_to_next_subword_end(
4277        &mut self,
4278        _: &MoveToNextSubwordEnd,
4279        cx: &mut ViewContext<Self>,
4280    ) {
4281        self.change_selections(Some(Autoscroll::fit()), cx, |s| {
4282            s.move_cursors_with(|map, head, _| {
4283                (movement::next_subword_end(map, head), SelectionGoal::None)
4284            });
4285        })
4286    }
4287
4288    pub fn select_to_next_word_end(&mut self, _: &SelectToNextWordEnd, cx: &mut ViewContext<Self>) {
4289        self.change_selections(Some(Autoscroll::fit()), cx, |s| {
4290            s.move_heads_with(|map, head, _| {
4291                (movement::next_word_end(map, head), SelectionGoal::None)
4292            });
4293        })
4294    }
4295
4296    pub fn select_to_next_subword_end(
4297        &mut self,
4298        _: &SelectToNextSubwordEnd,
4299        cx: &mut ViewContext<Self>,
4300    ) {
4301        self.change_selections(Some(Autoscroll::fit()), cx, |s| {
4302            s.move_heads_with(|map, head, _| {
4303                (movement::next_subword_end(map, head), SelectionGoal::None)
4304            });
4305        })
4306    }
4307
4308    pub fn delete_to_next_word_end(&mut self, _: &DeleteToNextWordEnd, cx: &mut ViewContext<Self>) {
4309        self.transact(cx, |this, cx| {
4310            this.change_selections(Some(Autoscroll::fit()), cx, |s| {
4311                let line_mode = s.line_mode;
4312                s.move_with(|map, selection| {
4313                    if selection.is_empty() && !line_mode {
4314                        let cursor = movement::next_word_end(map, selection.head());
4315                        selection.set_head(cursor, SelectionGoal::None);
4316                    }
4317                });
4318            });
4319            this.insert("", cx);
4320        });
4321    }
4322
4323    pub fn delete_to_next_subword_end(
4324        &mut self,
4325        _: &DeleteToNextSubwordEnd,
4326        cx: &mut ViewContext<Self>,
4327    ) {
4328        self.transact(cx, |this, cx| {
4329            this.change_selections(Some(Autoscroll::fit()), cx, |s| {
4330                s.move_with(|map, selection| {
4331                    if selection.is_empty() {
4332                        let cursor = movement::next_subword_end(map, selection.head());
4333                        selection.set_head(cursor, SelectionGoal::None);
4334                    }
4335                });
4336            });
4337            this.insert("", cx);
4338        });
4339    }
4340
4341    pub fn move_to_beginning_of_line(
4342        &mut self,
4343        _: &MoveToBeginningOfLine,
4344        cx: &mut ViewContext<Self>,
4345    ) {
4346        self.change_selections(Some(Autoscroll::fit()), cx, |s| {
4347            s.move_cursors_with(|map, head, _| {
4348                (
4349                    movement::indented_line_beginning(map, head, true),
4350                    SelectionGoal::None,
4351                )
4352            });
4353        })
4354    }
4355
4356    pub fn select_to_beginning_of_line(
4357        &mut self,
4358        action: &SelectToBeginningOfLine,
4359        cx: &mut ViewContext<Self>,
4360    ) {
4361        self.change_selections(Some(Autoscroll::fit()), cx, |s| {
4362            s.move_heads_with(|map, head, _| {
4363                (
4364                    movement::indented_line_beginning(map, head, action.stop_at_soft_wraps),
4365                    SelectionGoal::None,
4366                )
4367            });
4368        });
4369    }
4370
4371    pub fn delete_to_beginning_of_line(
4372        &mut self,
4373        _: &DeleteToBeginningOfLine,
4374        cx: &mut ViewContext<Self>,
4375    ) {
4376        self.transact(cx, |this, cx| {
4377            this.change_selections(Some(Autoscroll::fit()), cx, |s| {
4378                s.move_with(|_, selection| {
4379                    selection.reversed = true;
4380                });
4381            });
4382
4383            this.select_to_beginning_of_line(
4384                &SelectToBeginningOfLine {
4385                    stop_at_soft_wraps: false,
4386                },
4387                cx,
4388            );
4389            this.backspace(&Backspace, cx);
4390        });
4391    }
4392
4393    pub fn move_to_end_of_line(&mut self, _: &MoveToEndOfLine, cx: &mut ViewContext<Self>) {
4394        self.change_selections(Some(Autoscroll::fit()), cx, |s| {
4395            s.move_cursors_with(|map, head, _| {
4396                (movement::line_end(map, head, true), SelectionGoal::None)
4397            });
4398        })
4399    }
4400
4401    pub fn select_to_end_of_line(
4402        &mut self,
4403        action: &SelectToEndOfLine,
4404        cx: &mut ViewContext<Self>,
4405    ) {
4406        self.change_selections(Some(Autoscroll::fit()), cx, |s| {
4407            s.move_heads_with(|map, head, _| {
4408                (
4409                    movement::line_end(map, head, action.stop_at_soft_wraps),
4410                    SelectionGoal::None,
4411                )
4412            });
4413        })
4414    }
4415
4416    pub fn delete_to_end_of_line(&mut self, _: &DeleteToEndOfLine, cx: &mut ViewContext<Self>) {
4417        self.transact(cx, |this, cx| {
4418            this.select_to_end_of_line(
4419                &SelectToEndOfLine {
4420                    stop_at_soft_wraps: false,
4421                },
4422                cx,
4423            );
4424            this.delete(&Delete, cx);
4425        });
4426    }
4427
4428    pub fn cut_to_end_of_line(&mut self, _: &CutToEndOfLine, cx: &mut ViewContext<Self>) {
4429        self.transact(cx, |this, cx| {
4430            this.select_to_end_of_line(
4431                &SelectToEndOfLine {
4432                    stop_at_soft_wraps: false,
4433                },
4434                cx,
4435            );
4436            this.cut(&Cut, cx);
4437        });
4438    }
4439
4440    pub fn move_to_beginning(&mut self, _: &MoveToBeginning, cx: &mut ViewContext<Self>) {
4441        if matches!(self.mode, EditorMode::SingleLine) {
4442            cx.propagate_action();
4443            return;
4444        }
4445
4446        self.change_selections(Some(Autoscroll::fit()), cx, |s| {
4447            s.select_ranges(vec![0..0]);
4448        });
4449    }
4450
4451    pub fn select_to_beginning(&mut self, _: &SelectToBeginning, cx: &mut ViewContext<Self>) {
4452        let mut selection = self.selections.last::<Point>(cx);
4453        selection.set_head(Point::zero(), SelectionGoal::None);
4454
4455        self.change_selections(Some(Autoscroll::fit()), cx, |s| {
4456            s.select(vec![selection]);
4457        });
4458    }
4459
4460    pub fn move_to_end(&mut self, _: &MoveToEnd, cx: &mut ViewContext<Self>) {
4461        if matches!(self.mode, EditorMode::SingleLine) {
4462            cx.propagate_action();
4463            return;
4464        }
4465
4466        let cursor = self.buffer.read(cx).read(cx).len();
4467        self.change_selections(Some(Autoscroll::fit()), cx, |s| {
4468            s.select_ranges(vec![cursor..cursor])
4469        });
4470    }
4471
4472    pub fn set_nav_history(&mut self, nav_history: Option<ItemNavHistory>) {
4473        self.nav_history = nav_history;
4474    }
4475
4476    pub fn nav_history(&self) -> Option<&ItemNavHistory> {
4477        self.nav_history.as_ref()
4478    }
4479
4480    fn push_to_nav_history(
4481        &self,
4482        cursor_anchor: Anchor,
4483        new_position: Option<Point>,
4484        cx: &mut ViewContext<Self>,
4485    ) {
4486        if let Some(nav_history) = &self.nav_history {
4487            let buffer = self.buffer.read(cx).read(cx);
4488            let cursor_position = cursor_anchor.to_point(&buffer);
4489            let scroll_state = self.scroll_manager.anchor();
4490            let scroll_top_row = scroll_state.top_row(&buffer);
4491            drop(buffer);
4492
4493            if let Some(new_position) = new_position {
4494                let row_delta = (new_position.row as i64 - cursor_position.row as i64).abs();
4495                if row_delta < MIN_NAVIGATION_HISTORY_ROW_DELTA {
4496                    return;
4497                }
4498            }
4499
4500            nav_history.push(
4501                Some(NavigationData {
4502                    cursor_anchor,
4503                    cursor_position,
4504                    scroll_anchor: scroll_state,
4505                    scroll_top_row,
4506                }),
4507                cx,
4508            );
4509        }
4510    }
4511
4512    pub fn select_to_end(&mut self, _: &SelectToEnd, cx: &mut ViewContext<Self>) {
4513        let buffer = self.buffer.read(cx).snapshot(cx);
4514        let mut selection = self.selections.first::<usize>(cx);
4515        selection.set_head(buffer.len(), SelectionGoal::None);
4516        self.change_selections(Some(Autoscroll::fit()), cx, |s| {
4517            s.select(vec![selection]);
4518        });
4519    }
4520
4521    pub fn select_all(&mut self, _: &SelectAll, cx: &mut ViewContext<Self>) {
4522        let end = self.buffer.read(cx).read(cx).len();
4523        self.change_selections(Some(Autoscroll::fit()), cx, |s| {
4524            s.select_ranges(vec![0..end]);
4525        });
4526    }
4527
4528    pub fn select_line(&mut self, _: &SelectLine, cx: &mut ViewContext<Self>) {
4529        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
4530        let mut selections = self.selections.all::<Point>(cx);
4531        let max_point = display_map.buffer_snapshot.max_point();
4532        for selection in &mut selections {
4533            let rows = selection.spanned_rows(true, &display_map);
4534            selection.start = Point::new(rows.start, 0);
4535            selection.end = cmp::min(max_point, Point::new(rows.end, 0));
4536            selection.reversed = false;
4537        }
4538        self.change_selections(Some(Autoscroll::fit()), cx, |s| {
4539            s.select(selections);
4540        });
4541    }
4542
4543    pub fn split_selection_into_lines(
4544        &mut self,
4545        _: &SplitSelectionIntoLines,
4546        cx: &mut ViewContext<Self>,
4547    ) {
4548        let mut to_unfold = Vec::new();
4549        let mut new_selection_ranges = Vec::new();
4550        {
4551            let selections = self.selections.all::<Point>(cx);
4552            let buffer = self.buffer.read(cx).read(cx);
4553            for selection in selections {
4554                for row in selection.start.row..selection.end.row {
4555                    let cursor = Point::new(row, buffer.line_len(row));
4556                    new_selection_ranges.push(cursor..cursor);
4557                }
4558                new_selection_ranges.push(selection.end..selection.end);
4559                to_unfold.push(selection.start..selection.end);
4560            }
4561        }
4562        self.unfold_ranges(to_unfold, true, true, cx);
4563        self.change_selections(Some(Autoscroll::fit()), cx, |s| {
4564            s.select_ranges(new_selection_ranges);
4565        });
4566    }
4567
4568    pub fn add_selection_above(&mut self, _: &AddSelectionAbove, cx: &mut ViewContext<Self>) {
4569        self.add_selection(true, cx);
4570    }
4571
4572    pub fn add_selection_below(&mut self, _: &AddSelectionBelow, cx: &mut ViewContext<Self>) {
4573        self.add_selection(false, cx);
4574    }
4575
4576    fn add_selection(&mut self, above: bool, cx: &mut ViewContext<Self>) {
4577        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
4578        let mut selections = self.selections.all::<Point>(cx);
4579        let mut state = self.add_selections_state.take().unwrap_or_else(|| {
4580            let oldest_selection = selections.iter().min_by_key(|s| s.id).unwrap().clone();
4581            let range = oldest_selection.display_range(&display_map).sorted();
4582            let columns = cmp::min(range.start.column(), range.end.column())
4583                ..cmp::max(range.start.column(), range.end.column());
4584
4585            selections.clear();
4586            let mut stack = Vec::new();
4587            for row in range.start.row()..=range.end.row() {
4588                if let Some(selection) = self.selections.build_columnar_selection(
4589                    &display_map,
4590                    row,
4591                    &columns,
4592                    oldest_selection.reversed,
4593                ) {
4594                    stack.push(selection.id);
4595                    selections.push(selection);
4596                }
4597            }
4598
4599            if above {
4600                stack.reverse();
4601            }
4602
4603            AddSelectionsState { above, stack }
4604        });
4605
4606        let last_added_selection = *state.stack.last().unwrap();
4607        let mut new_selections = Vec::new();
4608        if above == state.above {
4609            let end_row = if above {
4610                0
4611            } else {
4612                display_map.max_point().row()
4613            };
4614
4615            'outer: for selection in selections {
4616                if selection.id == last_added_selection {
4617                    let range = selection.display_range(&display_map).sorted();
4618                    debug_assert_eq!(range.start.row(), range.end.row());
4619                    let mut row = range.start.row();
4620                    let columns = if let SelectionGoal::ColumnRange { start, end } = selection.goal
4621                    {
4622                        start..end
4623                    } else {
4624                        cmp::min(range.start.column(), range.end.column())
4625                            ..cmp::max(range.start.column(), range.end.column())
4626                    };
4627
4628                    while row != end_row {
4629                        if above {
4630                            row -= 1;
4631                        } else {
4632                            row += 1;
4633                        }
4634
4635                        if let Some(new_selection) = self.selections.build_columnar_selection(
4636                            &display_map,
4637                            row,
4638                            &columns,
4639                            selection.reversed,
4640                        ) {
4641                            state.stack.push(new_selection.id);
4642                            if above {
4643                                new_selections.push(new_selection);
4644                                new_selections.push(selection);
4645                            } else {
4646                                new_selections.push(selection);
4647                                new_selections.push(new_selection);
4648                            }
4649
4650                            continue 'outer;
4651                        }
4652                    }
4653                }
4654
4655                new_selections.push(selection);
4656            }
4657        } else {
4658            new_selections = selections;
4659            new_selections.retain(|s| s.id != last_added_selection);
4660            state.stack.pop();
4661        }
4662
4663        self.change_selections(Some(Autoscroll::fit()), cx, |s| {
4664            s.select(new_selections);
4665        });
4666        if state.stack.len() > 1 {
4667            self.add_selections_state = Some(state);
4668        }
4669    }
4670
4671    pub fn select_next(&mut self, action: &SelectNext, cx: &mut ViewContext<Self>) {
4672        self.push_to_selection_history();
4673        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
4674        let buffer = &display_map.buffer_snapshot;
4675        let mut selections = self.selections.all::<usize>(cx);
4676        if let Some(mut select_next_state) = self.select_next_state.take() {
4677            let query = &select_next_state.query;
4678            if !select_next_state.done {
4679                let first_selection = selections.iter().min_by_key(|s| s.id).unwrap();
4680                let last_selection = selections.iter().max_by_key(|s| s.id).unwrap();
4681                let mut next_selected_range = None;
4682
4683                let bytes_after_last_selection =
4684                    buffer.bytes_in_range(last_selection.end..buffer.len());
4685                let bytes_before_first_selection = buffer.bytes_in_range(0..first_selection.start);
4686                let query_matches = query
4687                    .stream_find_iter(bytes_after_last_selection)
4688                    .map(|result| (last_selection.end, result))
4689                    .chain(
4690                        query
4691                            .stream_find_iter(bytes_before_first_selection)
4692                            .map(|result| (0, result)),
4693                    );
4694                for (start_offset, query_match) in query_matches {
4695                    let query_match = query_match.unwrap(); // can only fail due to I/O
4696                    let offset_range =
4697                        start_offset + query_match.start()..start_offset + query_match.end();
4698                    let display_range = offset_range.start.to_display_point(&display_map)
4699                        ..offset_range.end.to_display_point(&display_map);
4700
4701                    if !select_next_state.wordwise
4702                        || (!movement::is_inside_word(&display_map, display_range.start)
4703                            && !movement::is_inside_word(&display_map, display_range.end))
4704                    {
4705                        next_selected_range = Some(offset_range);
4706                        break;
4707                    }
4708                }
4709
4710                if let Some(next_selected_range) = next_selected_range {
4711                    self.unfold_ranges([next_selected_range.clone()], false, true, cx);
4712                    self.change_selections(Some(Autoscroll::newest()), cx, |s| {
4713                        if action.replace_newest {
4714                            s.delete(s.newest_anchor().id);
4715                        }
4716                        s.insert_range(next_selected_range);
4717                    });
4718                } else {
4719                    select_next_state.done = true;
4720                }
4721            }
4722
4723            self.select_next_state = Some(select_next_state);
4724        } else if selections.len() == 1 {
4725            let selection = selections.last_mut().unwrap();
4726            if selection.start == selection.end {
4727                let word_range = movement::surrounding_word(
4728                    &display_map,
4729                    selection.start.to_display_point(&display_map),
4730                );
4731                selection.start = word_range.start.to_offset(&display_map, Bias::Left);
4732                selection.end = word_range.end.to_offset(&display_map, Bias::Left);
4733                selection.goal = SelectionGoal::None;
4734                selection.reversed = false;
4735
4736                let query = buffer
4737                    .text_for_range(selection.start..selection.end)
4738                    .collect::<String>();
4739                let select_state = SelectNextState {
4740                    query: AhoCorasick::new_auto_configured(&[query]),
4741                    wordwise: true,
4742                    done: false,
4743                };
4744                self.unfold_ranges([selection.start..selection.end], false, true, cx);
4745                self.change_selections(Some(Autoscroll::newest()), cx, |s| {
4746                    s.select(selections);
4747                });
4748                self.select_next_state = Some(select_state);
4749            } else {
4750                let query = buffer
4751                    .text_for_range(selection.start..selection.end)
4752                    .collect::<String>();
4753                self.select_next_state = Some(SelectNextState {
4754                    query: AhoCorasick::new_auto_configured(&[query]),
4755                    wordwise: false,
4756                    done: false,
4757                });
4758                self.select_next(action, cx);
4759            }
4760        }
4761    }
4762
4763    pub fn toggle_comments(&mut self, action: &ToggleComments, cx: &mut ViewContext<Self>) {
4764        self.transact(cx, |this, cx| {
4765            let mut selections = this.selections.all::<Point>(cx);
4766            let mut edits = Vec::new();
4767            let mut selection_edit_ranges = Vec::new();
4768            let mut last_toggled_row = None;
4769            let snapshot = this.buffer.read(cx).read(cx);
4770            let empty_str: Arc<str> = "".into();
4771            let mut suffixes_inserted = Vec::new();
4772
4773            fn comment_prefix_range(
4774                snapshot: &MultiBufferSnapshot,
4775                row: u32,
4776                comment_prefix: &str,
4777                comment_prefix_whitespace: &str,
4778            ) -> Range<Point> {
4779                let start = Point::new(row, snapshot.indent_size_for_line(row).len);
4780
4781                let mut line_bytes = snapshot
4782                    .bytes_in_range(start..snapshot.max_point())
4783                    .flatten()
4784                    .copied();
4785
4786                // If this line currently begins with the line comment prefix, then record
4787                // the range containing the prefix.
4788                if line_bytes
4789                    .by_ref()
4790                    .take(comment_prefix.len())
4791                    .eq(comment_prefix.bytes())
4792                {
4793                    // Include any whitespace that matches the comment prefix.
4794                    let matching_whitespace_len = line_bytes
4795                        .zip(comment_prefix_whitespace.bytes())
4796                        .take_while(|(a, b)| a == b)
4797                        .count() as u32;
4798                    let end = Point::new(
4799                        start.row,
4800                        start.column + comment_prefix.len() as u32 + matching_whitespace_len,
4801                    );
4802                    start..end
4803                } else {
4804                    start..start
4805                }
4806            }
4807
4808            fn comment_suffix_range(
4809                snapshot: &MultiBufferSnapshot,
4810                row: u32,
4811                comment_suffix: &str,
4812                comment_suffix_has_leading_space: bool,
4813            ) -> Range<Point> {
4814                let end = Point::new(row, snapshot.line_len(row));
4815                let suffix_start_column = end.column.saturating_sub(comment_suffix.len() as u32);
4816
4817                let mut line_end_bytes = snapshot
4818                    .bytes_in_range(Point::new(end.row, suffix_start_column.saturating_sub(1))..end)
4819                    .flatten()
4820                    .copied();
4821
4822                let leading_space_len = if suffix_start_column > 0
4823                    && line_end_bytes.next() == Some(b' ')
4824                    && comment_suffix_has_leading_space
4825                {
4826                    1
4827                } else {
4828                    0
4829                };
4830
4831                // If this line currently begins with the line comment prefix, then record
4832                // the range containing the prefix.
4833                if line_end_bytes.by_ref().eq(comment_suffix.bytes()) {
4834                    let start = Point::new(end.row, suffix_start_column - leading_space_len);
4835                    start..end
4836                } else {
4837                    end..end
4838                }
4839            }
4840
4841            // TODO: Handle selections that cross excerpts
4842            for selection in &mut selections {
4843                let start_column = snapshot.indent_size_for_line(selection.start.row).len;
4844                let language = if let Some(language) =
4845                    snapshot.language_scope_at(Point::new(selection.start.row, start_column))
4846                {
4847                    language
4848                } else {
4849                    continue;
4850                };
4851
4852                selection_edit_ranges.clear();
4853
4854                // If multiple selections contain a given row, avoid processing that
4855                // row more than once.
4856                let mut start_row = selection.start.row;
4857                if last_toggled_row == Some(start_row) {
4858                    start_row += 1;
4859                }
4860                let end_row =
4861                    if selection.end.row > selection.start.row && selection.end.column == 0 {
4862                        selection.end.row - 1
4863                    } else {
4864                        selection.end.row
4865                    };
4866                last_toggled_row = Some(end_row);
4867
4868                if start_row > end_row {
4869                    continue;
4870                }
4871
4872                // If the language has line comments, toggle those.
4873                if let Some(full_comment_prefix) = language.line_comment_prefix() {
4874                    // Split the comment prefix's trailing whitespace into a separate string,
4875                    // as that portion won't be used for detecting if a line is a comment.
4876                    let comment_prefix = full_comment_prefix.trim_end_matches(' ');
4877                    let comment_prefix_whitespace = &full_comment_prefix[comment_prefix.len()..];
4878                    let mut all_selection_lines_are_comments = true;
4879
4880                    for row in start_row..=end_row {
4881                        if snapshot.is_line_blank(row) {
4882                            continue;
4883                        }
4884
4885                        let prefix_range = comment_prefix_range(
4886                            snapshot.deref(),
4887                            row,
4888                            comment_prefix,
4889                            comment_prefix_whitespace,
4890                        );
4891                        if prefix_range.is_empty() {
4892                            all_selection_lines_are_comments = false;
4893                        }
4894                        selection_edit_ranges.push(prefix_range);
4895                    }
4896
4897                    if all_selection_lines_are_comments {
4898                        edits.extend(
4899                            selection_edit_ranges
4900                                .iter()
4901                                .cloned()
4902                                .map(|range| (range, empty_str.clone())),
4903                        );
4904                    } else {
4905                        let min_column = selection_edit_ranges
4906                            .iter()
4907                            .map(|r| r.start.column)
4908                            .min()
4909                            .unwrap_or(0);
4910                        edits.extend(selection_edit_ranges.iter().map(|range| {
4911                            let position = Point::new(range.start.row, min_column);
4912                            (position..position, full_comment_prefix.clone())
4913                        }));
4914                    }
4915                } else if let Some((full_comment_prefix, comment_suffix)) =
4916                    language.block_comment_delimiters()
4917                {
4918                    let comment_prefix = full_comment_prefix.trim_end_matches(' ');
4919                    let comment_prefix_whitespace = &full_comment_prefix[comment_prefix.len()..];
4920                    let prefix_range = comment_prefix_range(
4921                        snapshot.deref(),
4922                        start_row,
4923                        comment_prefix,
4924                        comment_prefix_whitespace,
4925                    );
4926                    let suffix_range = comment_suffix_range(
4927                        snapshot.deref(),
4928                        end_row,
4929                        comment_suffix.trim_start_matches(' '),
4930                        comment_suffix.starts_with(' '),
4931                    );
4932
4933                    if prefix_range.is_empty() || suffix_range.is_empty() {
4934                        edits.push((
4935                            prefix_range.start..prefix_range.start,
4936                            full_comment_prefix.clone(),
4937                        ));
4938                        edits.push((suffix_range.end..suffix_range.end, comment_suffix.clone()));
4939                        suffixes_inserted.push((end_row, comment_suffix.len()));
4940                    } else {
4941                        edits.push((prefix_range, empty_str.clone()));
4942                        edits.push((suffix_range, empty_str.clone()));
4943                    }
4944                } else {
4945                    continue;
4946                }
4947            }
4948
4949            drop(snapshot);
4950            this.buffer.update(cx, |buffer, cx| {
4951                buffer.edit(edits, None, cx);
4952            });
4953
4954            // Adjust selections so that they end before any comment suffixes that
4955            // were inserted.
4956            let mut suffixes_inserted = suffixes_inserted.into_iter().peekable();
4957            let mut selections = this.selections.all::<Point>(cx);
4958            let snapshot = this.buffer.read(cx).read(cx);
4959            for selection in &mut selections {
4960                while let Some((row, suffix_len)) = suffixes_inserted.peek().copied() {
4961                    match row.cmp(&selection.end.row) {
4962                        Ordering::Less => {
4963                            suffixes_inserted.next();
4964                            continue;
4965                        }
4966                        Ordering::Greater => break,
4967                        Ordering::Equal => {
4968                            if selection.end.column == snapshot.line_len(row) {
4969                                if selection.is_empty() {
4970                                    selection.start.column -= suffix_len as u32;
4971                                }
4972                                selection.end.column -= suffix_len as u32;
4973                            }
4974                            break;
4975                        }
4976                    }
4977                }
4978            }
4979
4980            drop(snapshot);
4981            this.change_selections(Some(Autoscroll::fit()), cx, |s| s.select(selections));
4982
4983            let selections = this.selections.all::<Point>(cx);
4984            let selections_on_single_row = selections.windows(2).all(|selections| {
4985                selections[0].start.row == selections[1].start.row
4986                    && selections[0].end.row == selections[1].end.row
4987                    && selections[0].start.row == selections[0].end.row
4988            });
4989            let selections_selecting = selections
4990                .iter()
4991                .any(|selection| selection.start != selection.end);
4992            let advance_downwards = action.advance_downwards
4993                && selections_on_single_row
4994                && !selections_selecting
4995                && this.mode != EditorMode::SingleLine;
4996
4997            if advance_downwards {
4998                let snapshot = this.buffer.read(cx).snapshot(cx);
4999
5000                this.change_selections(Some(Autoscroll::fit()), cx, |s| {
5001                    s.move_cursors_with(|display_snapshot, display_point, _| {
5002                        let mut point = display_point.to_point(display_snapshot);
5003                        point.row += 1;
5004                        point = snapshot.clip_point(point, Bias::Left);
5005                        let display_point = point.to_display_point(display_snapshot);
5006                        (display_point, SelectionGoal::Column(display_point.column()))
5007                    })
5008                });
5009            }
5010        });
5011    }
5012
5013    pub fn select_larger_syntax_node(
5014        &mut self,
5015        _: &SelectLargerSyntaxNode,
5016        cx: &mut ViewContext<Self>,
5017    ) {
5018        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
5019        let buffer = self.buffer.read(cx).snapshot(cx);
5020        let old_selections = self.selections.all::<usize>(cx).into_boxed_slice();
5021
5022        let mut stack = mem::take(&mut self.select_larger_syntax_node_stack);
5023        let mut selected_larger_node = false;
5024        let new_selections = old_selections
5025            .iter()
5026            .map(|selection| {
5027                let old_range = selection.start..selection.end;
5028                let mut new_range = old_range.clone();
5029                while let Some(containing_range) =
5030                    buffer.range_for_syntax_ancestor(new_range.clone())
5031                {
5032                    new_range = containing_range;
5033                    if !display_map.intersects_fold(new_range.start)
5034                        && !display_map.intersects_fold(new_range.end)
5035                    {
5036                        break;
5037                    }
5038                }
5039
5040                selected_larger_node |= new_range != old_range;
5041                Selection {
5042                    id: selection.id,
5043                    start: new_range.start,
5044                    end: new_range.end,
5045                    goal: SelectionGoal::None,
5046                    reversed: selection.reversed,
5047                }
5048            })
5049            .collect::<Vec<_>>();
5050
5051        if selected_larger_node {
5052            stack.push(old_selections);
5053            self.change_selections(Some(Autoscroll::fit()), cx, |s| {
5054                s.select(new_selections);
5055            });
5056        }
5057        self.select_larger_syntax_node_stack = stack;
5058    }
5059
5060    pub fn select_smaller_syntax_node(
5061        &mut self,
5062        _: &SelectSmallerSyntaxNode,
5063        cx: &mut ViewContext<Self>,
5064    ) {
5065        let mut stack = mem::take(&mut self.select_larger_syntax_node_stack);
5066        if let Some(selections) = stack.pop() {
5067            self.change_selections(Some(Autoscroll::fit()), cx, |s| {
5068                s.select(selections.to_vec());
5069            });
5070        }
5071        self.select_larger_syntax_node_stack = stack;
5072    }
5073
5074    pub fn move_to_enclosing_bracket(
5075        &mut self,
5076        _: &MoveToEnclosingBracket,
5077        cx: &mut ViewContext<Self>,
5078    ) {
5079        self.change_selections(Some(Autoscroll::fit()), cx, |s| {
5080            s.move_offsets_with(|snapshot, selection| {
5081                let Some(enclosing_bracket_ranges) = snapshot.enclosing_bracket_ranges(selection.start..selection.end) else {
5082                    return;
5083                };
5084
5085                let mut best_length = usize::MAX;
5086                let mut best_inside = false;
5087                let mut best_in_bracket_range = false;
5088                let mut best_destination = None;
5089                for (open, close) in enclosing_bracket_ranges {
5090                    let close = close.to_inclusive();
5091                    let length = close.end() - open.start;
5092                    let inside = selection.start >= open.end && selection.end <= *close.start();
5093                    let in_bracket_range = open.to_inclusive().contains(&selection.head()) || close.contains(&selection.head());
5094
5095                    // If best is next to a bracket and current isn't, skip
5096                    if !in_bracket_range && best_in_bracket_range {
5097                        continue;
5098                    }
5099
5100                    // Prefer smaller lengths unless best is inside and current isn't
5101                    if length > best_length && (best_inside || !inside) {
5102                        continue;
5103                    }
5104
5105                    best_length = length;
5106                    best_inside = inside;
5107                    best_in_bracket_range = in_bracket_range;
5108                    best_destination = Some(if close.contains(&selection.start) && close.contains(&selection.end) {
5109                        if inside {
5110                            open.end
5111                        } else {
5112                            open.start
5113                        }
5114                    } else {
5115                        if inside {
5116                            *close.start()
5117                        } else {
5118                            *close.end()
5119                        }
5120                    });
5121                }
5122
5123                if let Some(destination) = best_destination {
5124                    selection.collapse_to(destination, SelectionGoal::None);
5125                }
5126            })
5127        });
5128    }
5129
5130    pub fn undo_selection(&mut self, _: &UndoSelection, cx: &mut ViewContext<Self>) {
5131        self.end_selection(cx);
5132        self.selection_history.mode = SelectionHistoryMode::Undoing;
5133        if let Some(entry) = self.selection_history.undo_stack.pop_back() {
5134            self.change_selections(None, cx, |s| s.select_anchors(entry.selections.to_vec()));
5135            self.select_next_state = entry.select_next_state;
5136            self.add_selections_state = entry.add_selections_state;
5137            self.request_autoscroll(Autoscroll::newest(), cx);
5138        }
5139        self.selection_history.mode = SelectionHistoryMode::Normal;
5140    }
5141
5142    pub fn redo_selection(&mut self, _: &RedoSelection, cx: &mut ViewContext<Self>) {
5143        self.end_selection(cx);
5144        self.selection_history.mode = SelectionHistoryMode::Redoing;
5145        if let Some(entry) = self.selection_history.redo_stack.pop_back() {
5146            self.change_selections(None, cx, |s| s.select_anchors(entry.selections.to_vec()));
5147            self.select_next_state = entry.select_next_state;
5148            self.add_selections_state = entry.add_selections_state;
5149            self.request_autoscroll(Autoscroll::newest(), cx);
5150        }
5151        self.selection_history.mode = SelectionHistoryMode::Normal;
5152    }
5153
5154    fn go_to_diagnostic(&mut self, _: &GoToDiagnostic, cx: &mut ViewContext<Self>) {
5155        self.go_to_diagnostic_impl(Direction::Next, cx)
5156    }
5157
5158    fn go_to_prev_diagnostic(&mut self, _: &GoToPrevDiagnostic, cx: &mut ViewContext<Self>) {
5159        self.go_to_diagnostic_impl(Direction::Prev, cx)
5160    }
5161
5162    pub fn go_to_diagnostic_impl(&mut self, direction: Direction, cx: &mut ViewContext<Self>) {
5163        let buffer = self.buffer.read(cx).snapshot(cx);
5164        let selection = self.selections.newest::<usize>(cx);
5165
5166        // If there is an active Diagnostic Popover. Jump to it's diagnostic instead.
5167        if direction == Direction::Next {
5168            if let Some(popover) = self.hover_state.diagnostic_popover.as_ref() {
5169                let (group_id, jump_to) = popover.activation_info();
5170                if self.activate_diagnostics(group_id, cx) {
5171                    self.change_selections(Some(Autoscroll::fit()), cx, |s| {
5172                        let mut new_selection = s.newest_anchor().clone();
5173                        new_selection.collapse_to(jump_to, SelectionGoal::None);
5174                        s.select_anchors(vec![new_selection.clone()]);
5175                    });
5176                }
5177                return;
5178            }
5179        }
5180
5181        let mut active_primary_range = self.active_diagnostics.as_ref().map(|active_diagnostics| {
5182            active_diagnostics
5183                .primary_range
5184                .to_offset(&buffer)
5185                .to_inclusive()
5186        });
5187        let mut search_start = if let Some(active_primary_range) = active_primary_range.as_ref() {
5188            if active_primary_range.contains(&selection.head()) {
5189                *active_primary_range.end()
5190            } else {
5191                selection.head()
5192            }
5193        } else {
5194            selection.head()
5195        };
5196
5197        loop {
5198            let mut diagnostics = if direction == Direction::Prev {
5199                buffer.diagnostics_in_range::<_, usize>(0..search_start, true)
5200            } else {
5201                buffer.diagnostics_in_range::<_, usize>(search_start..buffer.len(), false)
5202            };
5203            let group = diagnostics.find_map(|entry| {
5204                if entry.diagnostic.is_primary
5205                    && entry.diagnostic.severity <= DiagnosticSeverity::WARNING
5206                    && !entry.range.is_empty()
5207                    && Some(entry.range.end) != active_primary_range.as_ref().map(|r| *r.end())
5208                {
5209                    Some((entry.range, entry.diagnostic.group_id))
5210                } else {
5211                    None
5212                }
5213            });
5214
5215            if let Some((primary_range, group_id)) = group {
5216                if self.activate_diagnostics(group_id, cx) {
5217                    self.change_selections(Some(Autoscroll::fit()), cx, |s| {
5218                        s.select(vec![Selection {
5219                            id: selection.id,
5220                            start: primary_range.start,
5221                            end: primary_range.start,
5222                            reversed: false,
5223                            goal: SelectionGoal::None,
5224                        }]);
5225                    });
5226                }
5227                break;
5228            } else {
5229                // Cycle around to the start of the buffer, potentially moving back to the start of
5230                // the currently active diagnostic.
5231                active_primary_range.take();
5232                if direction == Direction::Prev {
5233                    if search_start == buffer.len() {
5234                        break;
5235                    } else {
5236                        search_start = buffer.len();
5237                    }
5238                } else if search_start == 0 {
5239                    break;
5240                } else {
5241                    search_start = 0;
5242                }
5243            }
5244        }
5245    }
5246
5247    fn go_to_hunk(&mut self, _: &GoToHunk, cx: &mut ViewContext<Self>) {
5248        self.go_to_hunk_impl(Direction::Next, cx)
5249    }
5250
5251    fn go_to_prev_hunk(&mut self, _: &GoToPrevHunk, cx: &mut ViewContext<Self>) {
5252        self.go_to_hunk_impl(Direction::Prev, cx)
5253    }
5254
5255    pub fn go_to_hunk_impl(&mut self, direction: Direction, cx: &mut ViewContext<Self>) {
5256        let snapshot = self
5257            .display_map
5258            .update(cx, |display_map, cx| display_map.snapshot(cx));
5259        let selection = self.selections.newest::<Point>(cx);
5260
5261        fn seek_in_direction(
5262            this: &mut Editor,
5263            snapshot: &DisplaySnapshot,
5264            initial_point: Point,
5265            is_wrapped: bool,
5266            direction: Direction,
5267            cx: &mut ViewContext<Editor>,
5268        ) -> bool {
5269            let hunks = if direction == Direction::Next {
5270                snapshot
5271                    .buffer_snapshot
5272                    .git_diff_hunks_in_range(initial_point.row..u32::MAX, false)
5273            } else {
5274                snapshot
5275                    .buffer_snapshot
5276                    .git_diff_hunks_in_range(0..initial_point.row, true)
5277            };
5278
5279            let display_point = initial_point.to_display_point(snapshot);
5280            let mut hunks = hunks
5281                .map(|hunk| diff_hunk_to_display(hunk, &snapshot))
5282                .skip_while(|hunk| {
5283                    if is_wrapped {
5284                        false
5285                    } else {
5286                        hunk.contains_display_row(display_point.row())
5287                    }
5288                })
5289                .dedup();
5290
5291            if let Some(hunk) = hunks.next() {
5292                this.change_selections(Some(Autoscroll::fit()), cx, |s| {
5293                    let row = hunk.start_display_row();
5294                    let point = DisplayPoint::new(row, 0);
5295                    s.select_display_ranges([point..point]);
5296                });
5297
5298                true
5299            } else {
5300                false
5301            }
5302        }
5303
5304        if !seek_in_direction(self, &snapshot, selection.head(), false, direction, cx) {
5305            let wrapped_point = match direction {
5306                Direction::Next => Point::zero(),
5307                Direction::Prev => snapshot.buffer_snapshot.max_point(),
5308            };
5309            seek_in_direction(self, &snapshot, wrapped_point, true, direction, cx);
5310        }
5311    }
5312
5313    pub fn go_to_definition(
5314        workspace: &mut Workspace,
5315        _: &GoToDefinition,
5316        cx: &mut ViewContext<Workspace>,
5317    ) {
5318        Self::go_to_definition_of_kind(GotoDefinitionKind::Symbol, workspace, cx);
5319    }
5320
5321    pub fn go_to_type_definition(
5322        workspace: &mut Workspace,
5323        _: &GoToTypeDefinition,
5324        cx: &mut ViewContext<Workspace>,
5325    ) {
5326        Self::go_to_definition_of_kind(GotoDefinitionKind::Type, workspace, cx);
5327    }
5328
5329    fn go_to_definition_of_kind(
5330        kind: GotoDefinitionKind,
5331        workspace: &mut Workspace,
5332        cx: &mut ViewContext<Workspace>,
5333    ) {
5334        let active_item = workspace.active_item(cx);
5335        let editor_handle = if let Some(editor) = active_item
5336            .as_ref()
5337            .and_then(|item| item.act_as::<Self>(cx))
5338        {
5339            editor
5340        } else {
5341            return;
5342        };
5343
5344        let editor = editor_handle.read(cx);
5345        let buffer = editor.buffer.read(cx);
5346        let head = editor.selections.newest::<usize>(cx).head();
5347        let (buffer, head) = if let Some(text_anchor) = buffer.text_anchor_for_position(head, cx) {
5348            text_anchor
5349        } else {
5350            return;
5351        };
5352
5353        let project = workspace.project().clone();
5354        let definitions = project.update(cx, |project, cx| match kind {
5355            GotoDefinitionKind::Symbol => project.definition(&buffer, head, cx),
5356            GotoDefinitionKind::Type => project.type_definition(&buffer, head, cx),
5357        });
5358
5359        cx.spawn_labeled("Fetching Definition...", |workspace, mut cx| async move {
5360            let definitions = definitions.await?;
5361            workspace.update(&mut cx, |workspace, cx| {
5362                Editor::navigate_to_definitions(workspace, editor_handle, definitions, cx);
5363            });
5364
5365            Ok::<(), anyhow::Error>(())
5366        })
5367        .detach_and_log_err(cx);
5368    }
5369
5370    pub fn navigate_to_definitions(
5371        workspace: &mut Workspace,
5372        editor_handle: ViewHandle<Editor>,
5373        definitions: Vec<LocationLink>,
5374        cx: &mut ViewContext<Workspace>,
5375    ) {
5376        let pane = workspace.active_pane().clone();
5377        // If there is one definition, just open it directly
5378        if let [definition] = definitions.as_slice() {
5379            let range = definition
5380                .target
5381                .range
5382                .to_offset(definition.target.buffer.read(cx));
5383
5384            let target_editor_handle =
5385                workspace.open_project_item(definition.target.buffer.clone(), cx);
5386            target_editor_handle.update(cx, |target_editor, cx| {
5387                // When selecting a definition in a different buffer, disable the nav history
5388                // to avoid creating a history entry at the previous cursor location.
5389                if editor_handle != target_editor_handle {
5390                    pane.update(cx, |pane, _| pane.disable_history());
5391                }
5392                target_editor.change_selections(Some(Autoscroll::fit()), cx, |s| {
5393                    s.select_ranges([range]);
5394                });
5395
5396                pane.update(cx, |pane, _| pane.enable_history());
5397            });
5398        } else if !definitions.is_empty() {
5399            let replica_id = editor_handle.read(cx).replica_id(cx);
5400            let title = definitions
5401                .iter()
5402                .find(|definition| definition.origin.is_some())
5403                .and_then(|definition| {
5404                    definition.origin.as_ref().map(|origin| {
5405                        let buffer = origin.buffer.read(cx);
5406                        format!(
5407                            "Definitions for {}",
5408                            buffer
5409                                .text_for_range(origin.range.clone())
5410                                .collect::<String>()
5411                        )
5412                    })
5413                })
5414                .unwrap_or("Definitions".to_owned());
5415            let locations = definitions
5416                .into_iter()
5417                .map(|definition| definition.target)
5418                .collect();
5419            Self::open_locations_in_multibuffer(workspace, locations, replica_id, title, cx)
5420        }
5421    }
5422
5423    pub fn find_all_references(
5424        workspace: &mut Workspace,
5425        _: &FindAllReferences,
5426        cx: &mut ViewContext<Workspace>,
5427    ) -> Option<Task<Result<()>>> {
5428        let active_item = workspace.active_item(cx)?;
5429        let editor_handle = active_item.act_as::<Self>(cx)?;
5430
5431        let editor = editor_handle.read(cx);
5432        let buffer = editor.buffer.read(cx);
5433        let head = editor.selections.newest::<usize>(cx).head();
5434        let (buffer, head) = buffer.text_anchor_for_position(head, cx)?;
5435        let replica_id = editor.replica_id(cx);
5436
5437        let project = workspace.project().clone();
5438        let references = project.update(cx, |project, cx| project.references(&buffer, head, cx));
5439        Some(cx.spawn_labeled(
5440            "Finding All References...",
5441            |workspace, mut cx| async move {
5442                let locations = references.await?;
5443                if locations.is_empty() {
5444                    return Ok(());
5445                }
5446
5447                workspace.update(&mut cx, |workspace, cx| {
5448                    let title = locations
5449                        .first()
5450                        .as_ref()
5451                        .map(|location| {
5452                            let buffer = location.buffer.read(cx);
5453                            format!(
5454                                "References to `{}`",
5455                                buffer
5456                                    .text_for_range(location.range.clone())
5457                                    .collect::<String>()
5458                            )
5459                        })
5460                        .unwrap();
5461                    Self::open_locations_in_multibuffer(
5462                        workspace, locations, replica_id, title, cx,
5463                    );
5464                });
5465
5466                Ok(())
5467            },
5468        ))
5469    }
5470
5471    /// Opens a multibuffer with the given project locations in it
5472    pub fn open_locations_in_multibuffer(
5473        workspace: &mut Workspace,
5474        mut locations: Vec<Location>,
5475        replica_id: ReplicaId,
5476        title: String,
5477        cx: &mut ViewContext<Workspace>,
5478    ) {
5479        // If there are multiple definitions, open them in a multibuffer
5480        locations.sort_by_key(|location| location.buffer.id());
5481        let mut locations = locations.into_iter().peekable();
5482        let mut ranges_to_highlight = Vec::new();
5483
5484        let excerpt_buffer = cx.add_model(|cx| {
5485            let mut multibuffer = MultiBuffer::new(replica_id);
5486            while let Some(location) = locations.next() {
5487                let buffer = location.buffer.read(cx);
5488                let mut ranges_for_buffer = Vec::new();
5489                let range = location.range.to_offset(buffer);
5490                ranges_for_buffer.push(range.clone());
5491
5492                while let Some(next_location) = locations.peek() {
5493                    if next_location.buffer == location.buffer {
5494                        ranges_for_buffer.push(next_location.range.to_offset(buffer));
5495                        locations.next();
5496                    } else {
5497                        break;
5498                    }
5499                }
5500
5501                ranges_for_buffer.sort_by_key(|range| (range.start, Reverse(range.end)));
5502                ranges_to_highlight.extend(multibuffer.push_excerpts_with_context_lines(
5503                    location.buffer.clone(),
5504                    ranges_for_buffer,
5505                    1,
5506                    cx,
5507                ))
5508            }
5509
5510            multibuffer.with_title(title)
5511        });
5512
5513        let editor = cx.add_view(|cx| {
5514            Editor::for_multibuffer(excerpt_buffer, Some(workspace.project().clone()), cx)
5515        });
5516        editor.update(cx, |editor, cx| {
5517            editor.highlight_background::<Self>(
5518                ranges_to_highlight,
5519                |theme| theme.editor.highlighted_line_background,
5520                cx,
5521            );
5522        });
5523        workspace.add_item(Box::new(editor), cx);
5524    }
5525
5526    pub fn rename(&mut self, _: &Rename, cx: &mut ViewContext<Self>) -> Option<Task<Result<()>>> {
5527        use language::ToOffset as _;
5528
5529        let project = self.project.clone()?;
5530        let selection = self.selections.newest_anchor().clone();
5531        let (cursor_buffer, cursor_buffer_position) = self
5532            .buffer
5533            .read(cx)
5534            .text_anchor_for_position(selection.head(), cx)?;
5535        let (tail_buffer, _) = self
5536            .buffer
5537            .read(cx)
5538            .text_anchor_for_position(selection.tail(), cx)?;
5539        if tail_buffer != cursor_buffer {
5540            return None;
5541        }
5542
5543        let snapshot = cursor_buffer.read(cx).snapshot();
5544        let cursor_buffer_offset = cursor_buffer_position.to_offset(&snapshot);
5545        let prepare_rename = project.update(cx, |project, cx| {
5546            project.prepare_rename(cursor_buffer, cursor_buffer_offset, cx)
5547        });
5548
5549        Some(cx.spawn(|this, mut cx| async move {
5550            let rename_range = if let Some(range) = prepare_rename.await? {
5551                Some(range)
5552            } else {
5553                this.read_with(&cx, |this, cx| {
5554                    let buffer = this.buffer.read(cx).snapshot(cx);
5555                    let mut buffer_highlights = this
5556                        .document_highlights_for_position(selection.head(), &buffer)
5557                        .filter(|highlight| {
5558                            highlight.start.excerpt_id() == selection.head().excerpt_id()
5559                                && highlight.end.excerpt_id() == selection.head().excerpt_id()
5560                        });
5561                    buffer_highlights
5562                        .next()
5563                        .map(|highlight| highlight.start.text_anchor..highlight.end.text_anchor)
5564                })
5565            };
5566            if let Some(rename_range) = rename_range {
5567                let rename_buffer_range = rename_range.to_offset(&snapshot);
5568                let cursor_offset_in_rename_range =
5569                    cursor_buffer_offset.saturating_sub(rename_buffer_range.start);
5570
5571                this.update(&mut cx, |this, cx| {
5572                    this.take_rename(false, cx);
5573                    let style = this.style(cx);
5574                    let buffer = this.buffer.read(cx).read(cx);
5575                    let cursor_offset = selection.head().to_offset(&buffer);
5576                    let rename_start = cursor_offset.saturating_sub(cursor_offset_in_rename_range);
5577                    let rename_end = rename_start + rename_buffer_range.len();
5578                    let range = buffer.anchor_before(rename_start)..buffer.anchor_after(rename_end);
5579                    let mut old_highlight_id = None;
5580                    let old_name: Arc<str> = buffer
5581                        .chunks(rename_start..rename_end, true)
5582                        .map(|chunk| {
5583                            if old_highlight_id.is_none() {
5584                                old_highlight_id = chunk.syntax_highlight_id;
5585                            }
5586                            chunk.text
5587                        })
5588                        .collect::<String>()
5589                        .into();
5590
5591                    drop(buffer);
5592
5593                    // Position the selection in the rename editor so that it matches the current selection.
5594                    this.show_local_selections = false;
5595                    let rename_editor = cx.add_view(|cx| {
5596                        let mut editor = Editor::single_line(None, cx);
5597                        if let Some(old_highlight_id) = old_highlight_id {
5598                            editor.override_text_style =
5599                                Some(Box::new(move |style| old_highlight_id.style(&style.syntax)));
5600                        }
5601                        editor.buffer.update(cx, |buffer, cx| {
5602                            buffer.edit([(0..0, old_name.clone())], None, cx)
5603                        });
5604                        editor.select_all(&SelectAll, cx);
5605                        editor
5606                    });
5607
5608                    let ranges = this
5609                        .clear_background_highlights::<DocumentHighlightWrite>(cx)
5610                        .into_iter()
5611                        .flat_map(|(_, ranges)| ranges)
5612                        .chain(
5613                            this.clear_background_highlights::<DocumentHighlightRead>(cx)
5614                                .into_iter()
5615                                .flat_map(|(_, ranges)| ranges),
5616                        )
5617                        .collect();
5618
5619                    this.highlight_text::<Rename>(
5620                        ranges,
5621                        HighlightStyle {
5622                            fade_out: Some(style.rename_fade),
5623                            ..Default::default()
5624                        },
5625                        cx,
5626                    );
5627                    cx.focus(&rename_editor);
5628                    let block_id = this.insert_blocks(
5629                        [BlockProperties {
5630                            style: BlockStyle::Flex,
5631                            position: range.start.clone(),
5632                            height: 1,
5633                            render: Arc::new({
5634                                let editor = rename_editor.clone();
5635                                move |cx: &mut BlockContext| {
5636                                    ChildView::new(editor.clone(), cx)
5637                                        .contained()
5638                                        .with_padding_left(cx.anchor_x)
5639                                        .boxed()
5640                                }
5641                            }),
5642                            disposition: BlockDisposition::Below,
5643                        }],
5644                        cx,
5645                    )[0];
5646                    this.pending_rename = Some(RenameState {
5647                        range,
5648                        old_name,
5649                        editor: rename_editor,
5650                        block_id,
5651                    });
5652                });
5653            }
5654
5655            Ok(())
5656        }))
5657    }
5658
5659    pub fn confirm_rename(
5660        workspace: &mut Workspace,
5661        _: &ConfirmRename,
5662        cx: &mut ViewContext<Workspace>,
5663    ) -> Option<Task<Result<()>>> {
5664        let editor = workspace.active_item(cx)?.act_as::<Editor>(cx)?;
5665
5666        let (buffer, range, old_name, new_name) = editor.update(cx, |editor, cx| {
5667            let rename = editor.take_rename(false, cx)?;
5668            let buffer = editor.buffer.read(cx);
5669            let (start_buffer, start) =
5670                buffer.text_anchor_for_position(rename.range.start.clone(), cx)?;
5671            let (end_buffer, end) =
5672                buffer.text_anchor_for_position(rename.range.end.clone(), cx)?;
5673            if start_buffer == end_buffer {
5674                let new_name = rename.editor.read(cx).text(cx);
5675                Some((start_buffer, start..end, rename.old_name, new_name))
5676            } else {
5677                None
5678            }
5679        })?;
5680
5681        let rename = workspace.project().clone().update(cx, |project, cx| {
5682            project.perform_rename(buffer.clone(), range.start, new_name.clone(), true, cx)
5683        });
5684
5685        Some(cx.spawn(|workspace, mut cx| async move {
5686            let project_transaction = rename.await?;
5687            Self::open_project_transaction(
5688                editor.clone(),
5689                workspace,
5690                project_transaction,
5691                format!("Rename: {}{}", old_name, new_name),
5692                cx.clone(),
5693            )
5694            .await?;
5695
5696            editor.update(&mut cx, |editor, cx| {
5697                editor.refresh_document_highlights(cx);
5698            });
5699            Ok(())
5700        }))
5701    }
5702
5703    fn take_rename(
5704        &mut self,
5705        moving_cursor: bool,
5706        cx: &mut ViewContext<Self>,
5707    ) -> Option<RenameState> {
5708        let rename = self.pending_rename.take()?;
5709        self.remove_blocks([rename.block_id].into_iter().collect(), cx);
5710        self.clear_text_highlights::<Rename>(cx);
5711        self.show_local_selections = true;
5712
5713        if moving_cursor {
5714            let rename_editor = rename.editor.read(cx);
5715            let cursor_in_rename_editor = rename_editor.selections.newest::<usize>(cx).head();
5716
5717            // Update the selection to match the position of the selection inside
5718            // the rename editor.
5719            let snapshot = self.buffer.read(cx).read(cx);
5720            let rename_range = rename.range.to_offset(&snapshot);
5721            let cursor_in_editor = snapshot
5722                .clip_offset(rename_range.start + cursor_in_rename_editor, Bias::Left)
5723                .min(rename_range.end);
5724            drop(snapshot);
5725
5726            self.change_selections(None, cx, |s| {
5727                s.select_ranges(vec![cursor_in_editor..cursor_in_editor])
5728            });
5729        } else {
5730            self.refresh_document_highlights(cx);
5731        }
5732
5733        Some(rename)
5734    }
5735
5736    #[cfg(any(test, feature = "test-support"))]
5737    pub fn pending_rename(&self) -> Option<&RenameState> {
5738        self.pending_rename.as_ref()
5739    }
5740
5741    fn format(&mut self, _: &Format, cx: &mut ViewContext<'_, Self>) -> Option<Task<Result<()>>> {
5742        let project = match &self.project {
5743            Some(project) => project.clone(),
5744            None => return None,
5745        };
5746
5747        Some(self.perform_format(project, FormatTrigger::Manual, cx))
5748    }
5749
5750    fn perform_format(
5751        &mut self,
5752        project: ModelHandle<Project>,
5753        trigger: FormatTrigger,
5754        cx: &mut ViewContext<'_, Self>,
5755    ) -> Task<Result<()>> {
5756        let buffer = self.buffer().clone();
5757        let buffers = buffer.read(cx).all_buffers();
5758
5759        let mut timeout = cx.background().timer(FORMAT_TIMEOUT).fuse();
5760        let format = project.update(cx, |project, cx| project.format(buffers, true, trigger, cx));
5761
5762        cx.spawn(|_, mut cx| async move {
5763            let transaction = futures::select_biased! {
5764                _ = timeout => {
5765                    log::warn!("timed out waiting for formatting");
5766                    None
5767                }
5768                transaction = format.log_err().fuse() => transaction,
5769            };
5770
5771            buffer.update(&mut cx, |buffer, cx| {
5772                if let Some(transaction) = transaction {
5773                    if !buffer.is_singleton() {
5774                        buffer.push_transaction(&transaction.0);
5775                    }
5776                }
5777
5778                cx.notify();
5779            });
5780
5781            Ok(())
5782        })
5783    }
5784
5785    fn restart_language_server(&mut self, _: &RestartLanguageServer, cx: &mut ViewContext<Self>) {
5786        if let Some(project) = self.project.clone() {
5787            self.buffer.update(cx, |multi_buffer, cx| {
5788                project.update(cx, |project, cx| {
5789                    project.restart_language_servers_for_buffers(multi_buffer.all_buffers(), cx);
5790                });
5791            })
5792        }
5793    }
5794
5795    fn show_character_palette(&mut self, _: &ShowCharacterPalette, cx: &mut ViewContext<Self>) {
5796        cx.show_character_palette();
5797    }
5798
5799    fn refresh_active_diagnostics(&mut self, cx: &mut ViewContext<Editor>) {
5800        if let Some(active_diagnostics) = self.active_diagnostics.as_mut() {
5801            let buffer = self.buffer.read(cx).snapshot(cx);
5802            let primary_range_start = active_diagnostics.primary_range.start.to_offset(&buffer);
5803            let is_valid = buffer
5804                .diagnostics_in_range::<_, usize>(active_diagnostics.primary_range.clone(), false)
5805                .any(|entry| {
5806                    entry.diagnostic.is_primary
5807                        && !entry.range.is_empty()
5808                        && entry.range.start == primary_range_start
5809                        && entry.diagnostic.message == active_diagnostics.primary_message
5810                });
5811
5812            if is_valid != active_diagnostics.is_valid {
5813                active_diagnostics.is_valid = is_valid;
5814                let mut new_styles = HashMap::default();
5815                for (block_id, diagnostic) in &active_diagnostics.blocks {
5816                    new_styles.insert(
5817                        *block_id,
5818                        diagnostic_block_renderer(diagnostic.clone(), is_valid),
5819                    );
5820                }
5821                self.display_map
5822                    .update(cx, |display_map, _| display_map.replace_blocks(new_styles));
5823            }
5824        }
5825    }
5826
5827    fn activate_diagnostics(&mut self, group_id: usize, cx: &mut ViewContext<Self>) -> bool {
5828        self.dismiss_diagnostics(cx);
5829        self.active_diagnostics = self.display_map.update(cx, |display_map, cx| {
5830            let buffer = self.buffer.read(cx).snapshot(cx);
5831
5832            let mut primary_range = None;
5833            let mut primary_message = None;
5834            let mut group_end = Point::zero();
5835            let diagnostic_group = buffer
5836                .diagnostic_group::<Point>(group_id)
5837                .map(|entry| {
5838                    if entry.range.end > group_end {
5839                        group_end = entry.range.end;
5840                    }
5841                    if entry.diagnostic.is_primary {
5842                        primary_range = Some(entry.range.clone());
5843                        primary_message = Some(entry.diagnostic.message.clone());
5844                    }
5845                    entry
5846                })
5847                .collect::<Vec<_>>();
5848            let primary_range = primary_range?;
5849            let primary_message = primary_message?;
5850            let primary_range =
5851                buffer.anchor_after(primary_range.start)..buffer.anchor_before(primary_range.end);
5852
5853            let blocks = display_map
5854                .insert_blocks(
5855                    diagnostic_group.iter().map(|entry| {
5856                        let diagnostic = entry.diagnostic.clone();
5857                        let message_height = diagnostic.message.lines().count() as u8;
5858                        BlockProperties {
5859                            style: BlockStyle::Fixed,
5860                            position: buffer.anchor_after(entry.range.start),
5861                            height: message_height,
5862                            render: diagnostic_block_renderer(diagnostic, true),
5863                            disposition: BlockDisposition::Below,
5864                        }
5865                    }),
5866                    cx,
5867                )
5868                .into_iter()
5869                .zip(diagnostic_group.into_iter().map(|entry| entry.diagnostic))
5870                .collect();
5871
5872            Some(ActiveDiagnosticGroup {
5873                primary_range,
5874                primary_message,
5875                blocks,
5876                is_valid: true,
5877            })
5878        });
5879        self.active_diagnostics.is_some()
5880    }
5881
5882    fn dismiss_diagnostics(&mut self, cx: &mut ViewContext<Self>) {
5883        if let Some(active_diagnostic_group) = self.active_diagnostics.take() {
5884            self.display_map.update(cx, |display_map, cx| {
5885                display_map.remove_blocks(active_diagnostic_group.blocks.into_keys().collect(), cx);
5886            });
5887            cx.notify();
5888        }
5889    }
5890
5891    pub fn set_selections_from_remote(
5892        &mut self,
5893        selections: Vec<Selection<Anchor>>,
5894        pending_selection: Option<Selection<Anchor>>,
5895        cx: &mut ViewContext<Self>,
5896    ) {
5897        let old_cursor_position = self.selections.newest_anchor().head();
5898        self.selections.change_with(cx, |s| {
5899            s.select_anchors(selections);
5900            if let Some(pending_selection) = pending_selection {
5901                s.set_pending(pending_selection, SelectMode::Character);
5902            } else {
5903                s.clear_pending();
5904            }
5905        });
5906        self.selections_did_change(false, &old_cursor_position, cx);
5907    }
5908
5909    fn push_to_selection_history(&mut self) {
5910        self.selection_history.push(SelectionHistoryEntry {
5911            selections: self.selections.disjoint_anchors(),
5912            select_next_state: self.select_next_state.clone(),
5913            add_selections_state: self.add_selections_state.clone(),
5914        });
5915    }
5916
5917    pub fn transact(
5918        &mut self,
5919        cx: &mut ViewContext<Self>,
5920        update: impl FnOnce(&mut Self, &mut ViewContext<Self>),
5921    ) -> Option<TransactionId> {
5922        self.start_transaction_at(Instant::now(), cx);
5923        update(self, cx);
5924        self.end_transaction_at(Instant::now(), cx)
5925    }
5926
5927    fn start_transaction_at(&mut self, now: Instant, cx: &mut ViewContext<Self>) {
5928        self.end_selection(cx);
5929        if let Some(tx_id) = self
5930            .buffer
5931            .update(cx, |buffer, cx| buffer.start_transaction_at(now, cx))
5932        {
5933            self.selection_history
5934                .insert_transaction(tx_id, self.selections.disjoint_anchors());
5935        }
5936    }
5937
5938    fn end_transaction_at(
5939        &mut self,
5940        now: Instant,
5941        cx: &mut ViewContext<Self>,
5942    ) -> Option<TransactionId> {
5943        if let Some(tx_id) = self
5944            .buffer
5945            .update(cx, |buffer, cx| buffer.end_transaction_at(now, cx))
5946        {
5947            if let Some((_, end_selections)) = self.selection_history.transaction_mut(tx_id) {
5948                *end_selections = Some(self.selections.disjoint_anchors());
5949            } else {
5950                log::error!("unexpectedly ended a transaction that wasn't started by this editor");
5951            }
5952
5953            cx.emit(Event::Edited);
5954            Some(tx_id)
5955        } else {
5956            None
5957        }
5958    }
5959
5960    pub fn fold(&mut self, _: &Fold, cx: &mut ViewContext<Self>) {
5961        let mut fold_ranges = Vec::new();
5962
5963        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
5964
5965        let selections = self.selections.all::<Point>(cx);
5966        for selection in selections {
5967            let range = selection.range().sorted();
5968            let buffer_start_row = range.start.row;
5969
5970            for row in (0..=range.end.row).rev() {
5971                let fold_range = display_map.foldable_range(row);
5972
5973                if let Some(fold_range) = fold_range {
5974                    if fold_range.end.row >= buffer_start_row {
5975                        fold_ranges.push(fold_range);
5976                        if row <= range.start.row {
5977                            break;
5978                        }
5979                    }
5980                }
5981            }
5982        }
5983
5984        self.fold_ranges(fold_ranges, true, cx);
5985    }
5986
5987    pub fn fold_at(&mut self, fold_at: &FoldAt, cx: &mut ViewContext<Self>) {
5988        let buffer_row = fold_at.buffer_row;
5989        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
5990
5991        if let Some(fold_range) = display_map.foldable_range(buffer_row) {
5992            let autoscroll = self
5993                .selections
5994                .all::<Point>(cx)
5995                .iter()
5996                .any(|selection| fold_range.overlaps(&selection.range()));
5997
5998            self.fold_ranges(std::iter::once(fold_range), autoscroll, cx);
5999        }
6000    }
6001
6002    pub fn unfold_lines(&mut self, _: &UnfoldLines, cx: &mut ViewContext<Self>) {
6003        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
6004        let buffer = &display_map.buffer_snapshot;
6005        let selections = self.selections.all::<Point>(cx);
6006        let ranges = selections
6007            .iter()
6008            .map(|s| {
6009                let range = s.display_range(&display_map).sorted();
6010                let mut start = range.start.to_point(&display_map);
6011                let mut end = range.end.to_point(&display_map);
6012                start.column = 0;
6013                end.column = buffer.line_len(end.row);
6014                start..end
6015            })
6016            .collect::<Vec<_>>();
6017
6018        self.unfold_ranges(ranges, true, true, cx);
6019    }
6020
6021    pub fn unfold_at(&mut self, unfold_at: &UnfoldAt, cx: &mut ViewContext<Self>) {
6022        let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
6023
6024        let intersection_range = Point::new(unfold_at.buffer_row, 0)
6025            ..Point::new(
6026                unfold_at.buffer_row,
6027                display_map.buffer_snapshot.line_len(unfold_at.buffer_row),
6028            );
6029
6030        let autoscroll = self
6031            .selections
6032            .all::<Point>(cx)
6033            .iter()
6034            .any(|selection| selection.range().overlaps(&intersection_range));
6035
6036        self.unfold_ranges(std::iter::once(intersection_range), true, autoscroll, cx)
6037    }
6038
6039    pub fn fold_selected_ranges(&mut self, _: &FoldSelectedRanges, cx: &mut ViewContext<Self>) {
6040        let selections = self.selections.all::<Point>(cx);
6041        let ranges = selections.into_iter().map(|s| s.start..s.end);
6042        self.fold_ranges(ranges, true, cx);
6043    }
6044
6045    pub fn fold_ranges<T: ToOffset + Clone>(
6046        &mut self,
6047        ranges: impl IntoIterator<Item = Range<T>>,
6048        auto_scroll: bool,
6049        cx: &mut ViewContext<Self>,
6050    ) {
6051        let mut ranges = ranges.into_iter().peekable();
6052        if ranges.peek().is_some() {
6053            self.display_map.update(cx, |map, cx| map.fold(ranges, cx));
6054
6055            if auto_scroll {
6056                self.request_autoscroll(Autoscroll::fit(), cx);
6057            }
6058
6059            cx.notify();
6060        }
6061    }
6062
6063    pub fn unfold_ranges<T: ToOffset + Clone>(
6064        &mut self,
6065        ranges: impl IntoIterator<Item = Range<T>>,
6066        inclusive: bool,
6067        auto_scroll: bool,
6068        cx: &mut ViewContext<Self>,
6069    ) {
6070        let mut ranges = ranges.into_iter().peekable();
6071        if ranges.peek().is_some() {
6072            self.display_map
6073                .update(cx, |map, cx| map.unfold(ranges, inclusive, cx));
6074            if auto_scroll {
6075                self.request_autoscroll(Autoscroll::fit(), cx);
6076            }
6077
6078            cx.notify();
6079        }
6080    }
6081
6082    pub fn gutter_hover(
6083        &mut self,
6084        GutterHover { hovered }: &GutterHover,
6085        cx: &mut ViewContext<Self>,
6086    ) {
6087        self.gutter_hovered = *hovered;
6088        cx.notify();
6089    }
6090
6091    pub fn insert_blocks(
6092        &mut self,
6093        blocks: impl IntoIterator<Item = BlockProperties<Anchor>>,
6094        cx: &mut ViewContext<Self>,
6095    ) -> Vec<BlockId> {
6096        let blocks = self
6097            .display_map
6098            .update(cx, |display_map, cx| display_map.insert_blocks(blocks, cx));
6099        self.request_autoscroll(Autoscroll::fit(), cx);
6100        blocks
6101    }
6102
6103    pub fn replace_blocks(
6104        &mut self,
6105        blocks: HashMap<BlockId, RenderBlock>,
6106        cx: &mut ViewContext<Self>,
6107    ) {
6108        self.display_map
6109            .update(cx, |display_map, _| display_map.replace_blocks(blocks));
6110        self.request_autoscroll(Autoscroll::fit(), cx);
6111    }
6112
6113    pub fn remove_blocks(&mut self, block_ids: HashSet<BlockId>, cx: &mut ViewContext<Self>) {
6114        self.display_map.update(cx, |display_map, cx| {
6115            display_map.remove_blocks(block_ids, cx)
6116        });
6117    }
6118
6119    pub fn longest_row(&self, cx: &mut MutableAppContext) -> u32 {
6120        self.display_map
6121            .update(cx, |map, cx| map.snapshot(cx))
6122            .longest_row()
6123    }
6124
6125    pub fn max_point(&self, cx: &mut MutableAppContext) -> DisplayPoint {
6126        self.display_map
6127            .update(cx, |map, cx| map.snapshot(cx))
6128            .max_point()
6129    }
6130
6131    pub fn text(&self, cx: &AppContext) -> String {
6132        self.buffer.read(cx).read(cx).text()
6133    }
6134
6135    pub fn set_text(&mut self, text: impl Into<Arc<str>>, cx: &mut ViewContext<Self>) {
6136        self.transact(cx, |this, cx| {
6137            this.buffer
6138                .read(cx)
6139                .as_singleton()
6140                .expect("you can only call set_text on editors for singleton buffers")
6141                .update(cx, |buffer, cx| buffer.set_text(text, cx));
6142        });
6143    }
6144
6145    pub fn display_text(&self, cx: &mut MutableAppContext) -> String {
6146        self.display_map
6147            .update(cx, |map, cx| map.snapshot(cx))
6148            .text()
6149    }
6150
6151    pub fn soft_wrap_mode(&self, cx: &AppContext) -> SoftWrap {
6152        let language_name = self
6153            .buffer
6154            .read(cx)
6155            .as_singleton()
6156            .and_then(|singleton_buffer| singleton_buffer.read(cx).language())
6157            .map(|l| l.name());
6158
6159        let settings = cx.global::<Settings>();
6160        let mode = self
6161            .soft_wrap_mode_override
6162            .unwrap_or_else(|| settings.soft_wrap(language_name.as_deref()));
6163        match mode {
6164            settings::SoftWrap::None => SoftWrap::None,
6165            settings::SoftWrap::EditorWidth => SoftWrap::EditorWidth,
6166            settings::SoftWrap::PreferredLineLength => {
6167                SoftWrap::Column(settings.preferred_line_length(language_name.as_deref()))
6168            }
6169        }
6170    }
6171
6172    pub fn set_soft_wrap_mode(&mut self, mode: settings::SoftWrap, cx: &mut ViewContext<Self>) {
6173        self.soft_wrap_mode_override = Some(mode);
6174        cx.notify();
6175    }
6176
6177    pub fn set_wrap_width(&self, width: Option<f32>, cx: &mut MutableAppContext) -> bool {
6178        self.display_map
6179            .update(cx, |map, cx| map.set_wrap_width(width, cx))
6180    }
6181
6182    pub fn toggle_soft_wrap(&mut self, _: &ToggleSoftWrap, cx: &mut ViewContext<Self>) {
6183        if self.soft_wrap_mode_override.is_some() {
6184            self.soft_wrap_mode_override.take();
6185        } else {
6186            let soft_wrap = match self.soft_wrap_mode(cx) {
6187                SoftWrap::None => settings::SoftWrap::EditorWidth,
6188                SoftWrap::EditorWidth | SoftWrap::Column(_) => settings::SoftWrap::None,
6189            };
6190            self.soft_wrap_mode_override = Some(soft_wrap);
6191        }
6192        cx.notify();
6193    }
6194
6195    pub fn reveal_in_finder(&mut self, _: &RevealInFinder, cx: &mut ViewContext<Self>) {
6196        if let Some(buffer) = self.buffer().read(cx).as_singleton() {
6197            if let Some(file) = buffer.read(cx).file().and_then(|f| f.as_local()) {
6198                cx.reveal_path(&file.abs_path(cx));
6199            }
6200        }
6201    }
6202
6203    pub fn highlight_rows(&mut self, rows: Option<Range<u32>>) {
6204        self.highlighted_rows = rows;
6205    }
6206
6207    pub fn highlighted_rows(&self) -> Option<Range<u32>> {
6208        self.highlighted_rows.clone()
6209    }
6210
6211    pub fn highlight_background<T: 'static>(
6212        &mut self,
6213        ranges: Vec<Range<Anchor>>,
6214        color_fetcher: fn(&Theme) -> Color,
6215        cx: &mut ViewContext<Self>,
6216    ) {
6217        self.background_highlights
6218            .insert(TypeId::of::<T>(), (color_fetcher, ranges));
6219        cx.notify();
6220    }
6221
6222    #[allow(clippy::type_complexity)]
6223    pub fn clear_background_highlights<T: 'static>(
6224        &mut self,
6225        cx: &mut ViewContext<Self>,
6226    ) -> Option<(fn(&Theme) -> Color, Vec<Range<Anchor>>)> {
6227        let highlights = self.background_highlights.remove(&TypeId::of::<T>());
6228        if highlights.is_some() {
6229            cx.notify();
6230        }
6231        highlights
6232    }
6233
6234    #[cfg(feature = "test-support")]
6235    pub fn all_background_highlights(
6236        &mut self,
6237        cx: &mut ViewContext<Self>,
6238    ) -> Vec<(Range<DisplayPoint>, Color)> {
6239        let snapshot = self.snapshot(cx);
6240        let buffer = &snapshot.buffer_snapshot;
6241        let start = buffer.anchor_before(0);
6242        let end = buffer.anchor_after(buffer.len());
6243        let theme = cx.global::<Settings>().theme.as_ref();
6244        self.background_highlights_in_range(start..end, &snapshot, theme)
6245    }
6246
6247    fn document_highlights_for_position<'a>(
6248        &'a self,
6249        position: Anchor,
6250        buffer: &'a MultiBufferSnapshot,
6251    ) -> impl 'a + Iterator<Item = &Range<Anchor>> {
6252        let read_highlights = self
6253            .background_highlights
6254            .get(&TypeId::of::<DocumentHighlightRead>())
6255            .map(|h| &h.1);
6256        let write_highlights = self
6257            .background_highlights
6258            .get(&TypeId::of::<DocumentHighlightWrite>())
6259            .map(|h| &h.1);
6260        let left_position = position.bias_left(buffer);
6261        let right_position = position.bias_right(buffer);
6262        read_highlights
6263            .into_iter()
6264            .chain(write_highlights)
6265            .flat_map(move |ranges| {
6266                let start_ix = match ranges.binary_search_by(|probe| {
6267                    let cmp = probe.end.cmp(&left_position, buffer);
6268                    if cmp.is_ge() {
6269                        Ordering::Greater
6270                    } else {
6271                        Ordering::Less
6272                    }
6273                }) {
6274                    Ok(i) | Err(i) => i,
6275                };
6276
6277                let right_position = right_position.clone();
6278                ranges[start_ix..]
6279                    .iter()
6280                    .take_while(move |range| range.start.cmp(&right_position, buffer).is_le())
6281            })
6282    }
6283
6284    pub fn background_highlights_in_range(
6285        &self,
6286        search_range: Range<Anchor>,
6287        display_snapshot: &DisplaySnapshot,
6288        theme: &Theme,
6289    ) -> Vec<(Range<DisplayPoint>, Color)> {
6290        let mut results = Vec::new();
6291        let buffer = &display_snapshot.buffer_snapshot;
6292        for (color_fetcher, ranges) in self.background_highlights.values() {
6293            let color = color_fetcher(theme);
6294            let start_ix = match ranges.binary_search_by(|probe| {
6295                let cmp = probe.end.cmp(&search_range.start, buffer);
6296                if cmp.is_gt() {
6297                    Ordering::Greater
6298                } else {
6299                    Ordering::Less
6300                }
6301            }) {
6302                Ok(i) | Err(i) => i,
6303            };
6304            for range in &ranges[start_ix..] {
6305                if range.start.cmp(&search_range.end, buffer).is_ge() {
6306                    break;
6307                }
6308                let start = range
6309                    .start
6310                    .to_point(buffer)
6311                    .to_display_point(display_snapshot);
6312                let end = range
6313                    .end
6314                    .to_point(buffer)
6315                    .to_display_point(display_snapshot);
6316                results.push((start..end, color))
6317            }
6318        }
6319        results
6320    }
6321
6322    pub fn highlight_text<T: 'static>(
6323        &mut self,
6324        ranges: Vec<Range<Anchor>>,
6325        style: HighlightStyle,
6326        cx: &mut ViewContext<Self>,
6327    ) {
6328        self.display_map.update(cx, |map, _| {
6329            map.highlight_text(TypeId::of::<T>(), ranges, style)
6330        });
6331        cx.notify();
6332    }
6333
6334    pub fn text_highlights<'a, T: 'static>(
6335        &'a self,
6336        cx: &'a AppContext,
6337    ) -> Option<(HighlightStyle, &'a [Range<Anchor>])> {
6338        self.display_map.read(cx).text_highlights(TypeId::of::<T>())
6339    }
6340
6341    pub fn clear_text_highlights<T: 'static>(
6342        &mut self,
6343        cx: &mut ViewContext<Self>,
6344    ) -> Option<Arc<(HighlightStyle, Vec<Range<Anchor>>)>> {
6345        let highlights = self
6346            .display_map
6347            .update(cx, |map, _| map.clear_text_highlights(TypeId::of::<T>()));
6348        if highlights.is_some() {
6349            cx.notify();
6350        }
6351        highlights
6352    }
6353
6354    pub fn show_local_cursors(&self, cx: &AppContext) -> bool {
6355        self.blink_manager.read(cx).visible() && self.focused
6356    }
6357
6358    fn on_buffer_changed(&mut self, _: ModelHandle<MultiBuffer>, cx: &mut ViewContext<Self>) {
6359        cx.notify();
6360    }
6361
6362    fn on_buffer_event(
6363        &mut self,
6364        _: ModelHandle<MultiBuffer>,
6365        event: &multi_buffer::Event,
6366        cx: &mut ViewContext<Self>,
6367    ) {
6368        match event {
6369            multi_buffer::Event::Edited => {
6370                self.refresh_active_diagnostics(cx);
6371                self.refresh_code_actions(cx);
6372                cx.emit(Event::BufferEdited);
6373            }
6374            multi_buffer::Event::ExcerptsAdded {
6375                buffer,
6376                predecessor,
6377                excerpts,
6378            } => cx.emit(Event::ExcerptsAdded {
6379                buffer: buffer.clone(),
6380                predecessor: *predecessor,
6381                excerpts: excerpts.clone(),
6382            }),
6383            multi_buffer::Event::ExcerptsRemoved { ids } => {
6384                cx.emit(Event::ExcerptsRemoved { ids: ids.clone() })
6385            }
6386            multi_buffer::Event::Reparsed => cx.emit(Event::Reparsed),
6387            multi_buffer::Event::DirtyChanged => cx.emit(Event::DirtyChanged),
6388            multi_buffer::Event::Saved => cx.emit(Event::Saved),
6389            multi_buffer::Event::FileHandleChanged => cx.emit(Event::TitleChanged),
6390            multi_buffer::Event::Reloaded => cx.emit(Event::TitleChanged),
6391            multi_buffer::Event::Closed => cx.emit(Event::Closed),
6392            multi_buffer::Event::DiagnosticsUpdated => {
6393                self.refresh_active_diagnostics(cx);
6394            }
6395        }
6396    }
6397
6398    fn on_display_map_changed(&mut self, _: ModelHandle<DisplayMap>, cx: &mut ViewContext<Self>) {
6399        cx.notify();
6400    }
6401
6402    pub fn set_searchable(&mut self, searchable: bool) {
6403        self.searchable = searchable;
6404    }
6405
6406    pub fn searchable(&self) -> bool {
6407        self.searchable
6408    }
6409
6410    fn open_excerpts(workspace: &mut Workspace, _: &OpenExcerpts, cx: &mut ViewContext<Workspace>) {
6411        let active_item = workspace.active_item(cx);
6412        let editor_handle = if let Some(editor) = active_item
6413            .as_ref()
6414            .and_then(|item| item.act_as::<Self>(cx))
6415        {
6416            editor
6417        } else {
6418            cx.propagate_action();
6419            return;
6420        };
6421
6422        let editor = editor_handle.read(cx);
6423        let buffer = editor.buffer.read(cx);
6424        if buffer.is_singleton() {
6425            cx.propagate_action();
6426            return;
6427        }
6428
6429        let mut new_selections_by_buffer = HashMap::default();
6430        for selection in editor.selections.all::<usize>(cx) {
6431            for (buffer, mut range) in
6432                buffer.range_to_buffer_ranges(selection.start..selection.end, cx)
6433            {
6434                if selection.reversed {
6435                    mem::swap(&mut range.start, &mut range.end);
6436                }
6437                new_selections_by_buffer
6438                    .entry(buffer)
6439                    .or_insert(Vec::new())
6440                    .push(range)
6441            }
6442        }
6443
6444        editor_handle.update(cx, |editor, cx| {
6445            editor.push_to_nav_history(editor.selections.newest_anchor().head(), None, cx);
6446        });
6447        let pane = workspace.active_pane().clone();
6448        pane.update(cx, |pane, _| pane.disable_history());
6449
6450        // We defer the pane interaction because we ourselves are a workspace item
6451        // and activating a new item causes the pane to call a method on us reentrantly,
6452        // which panics if we're on the stack.
6453        cx.defer(move |workspace, cx| {
6454            for (buffer, ranges) in new_selections_by_buffer.into_iter() {
6455                let editor = workspace.open_project_item::<Self>(buffer, cx);
6456                editor.update(cx, |editor, cx| {
6457                    editor.change_selections(Some(Autoscroll::newest()), cx, |s| {
6458                        s.select_ranges(ranges);
6459                    });
6460                });
6461            }
6462
6463            pane.update(cx, |pane, _| pane.enable_history());
6464        });
6465    }
6466
6467    fn jump(workspace: &mut Workspace, action: &Jump, cx: &mut ViewContext<Workspace>) {
6468        let editor = workspace.open_path(action.path.clone(), None, true, cx);
6469        let position = action.position;
6470        let anchor = action.anchor;
6471        cx.spawn_weak(|_, mut cx| async move {
6472            let editor = editor.await.log_err()?.downcast::<Editor>()?;
6473            editor.update(&mut cx, |editor, cx| {
6474                let buffer = editor.buffer().read(cx).as_singleton()?;
6475                let buffer = buffer.read(cx);
6476                let cursor = if buffer.can_resolve(&anchor) {
6477                    language::ToPoint::to_point(&anchor, buffer)
6478                } else {
6479                    buffer.clip_point(position, Bias::Left)
6480                };
6481
6482                let nav_history = editor.nav_history.take();
6483                editor.change_selections(Some(Autoscroll::newest()), cx, |s| {
6484                    s.select_ranges([cursor..cursor]);
6485                });
6486                editor.nav_history = nav_history;
6487
6488                Some(())
6489            })?;
6490            Some(())
6491        })
6492        .detach()
6493    }
6494
6495    fn marked_text_ranges(&self, cx: &AppContext) -> Option<Vec<Range<OffsetUtf16>>> {
6496        let snapshot = self.buffer.read(cx).read(cx);
6497        let (_, ranges) = self.text_highlights::<InputComposition>(cx)?;
6498        Some(
6499            ranges
6500                .iter()
6501                .map(move |range| {
6502                    range.start.to_offset_utf16(&snapshot)..range.end.to_offset_utf16(&snapshot)
6503                })
6504                .collect(),
6505        )
6506    }
6507
6508    fn selection_replacement_ranges(
6509        &self,
6510        range: Range<OffsetUtf16>,
6511        cx: &AppContext,
6512    ) -> Vec<Range<OffsetUtf16>> {
6513        let selections = self.selections.all::<OffsetUtf16>(cx);
6514        let newest_selection = selections
6515            .iter()
6516            .max_by_key(|selection| selection.id)
6517            .unwrap();
6518        let start_delta = range.start.0 as isize - newest_selection.start.0 as isize;
6519        let end_delta = range.end.0 as isize - newest_selection.end.0 as isize;
6520        let snapshot = self.buffer.read(cx).read(cx);
6521        selections
6522            .into_iter()
6523            .map(|mut selection| {
6524                selection.start.0 =
6525                    (selection.start.0 as isize).saturating_add(start_delta) as usize;
6526                selection.end.0 = (selection.end.0 as isize).saturating_add(end_delta) as usize;
6527                snapshot.clip_offset_utf16(selection.start, Bias::Left)
6528                    ..snapshot.clip_offset_utf16(selection.end, Bias::Right)
6529            })
6530            .collect()
6531    }
6532
6533    fn report_event(&self, name: &str, cx: &AppContext) {
6534        if let Some((project, file)) = self.project.as_ref().zip(
6535            self.buffer
6536                .read(cx)
6537                .as_singleton()
6538                .and_then(|b| b.read(cx).file()),
6539        ) {
6540            let extension = Path::new(file.file_name(cx))
6541                .extension()
6542                .and_then(|e| e.to_str());
6543            project.read(cx).client().report_event(
6544                name,
6545                json!({ "File Extension": extension }),
6546                cx.global::<Settings>().telemetry(),
6547            );
6548        }
6549    }
6550
6551    /// Copy the highlighted chunks to the clipboard as JSON. The format is an array of lines,
6552    /// with each line being an array of {text, highlight} objects.
6553    fn copy_highlight_json(&mut self, _: &CopyHighlightJson, cx: &mut ViewContext<Self>) {
6554        let Some(buffer) = self.buffer.read(cx).as_singleton() else {
6555            return;
6556        };
6557
6558        #[derive(Serialize)]
6559        struct Chunk<'a> {
6560            text: String,
6561            highlight: Option<&'a str>,
6562        }
6563
6564        let snapshot = buffer.read(cx).snapshot();
6565        let range = self
6566            .selected_text_range(cx)
6567            .and_then(|selected_range| {
6568                if selected_range.is_empty() {
6569                    None
6570                } else {
6571                    Some(selected_range)
6572                }
6573            })
6574            .unwrap_or_else(|| 0..snapshot.len());
6575
6576        let chunks = snapshot.chunks(range, true);
6577        let mut lines = Vec::new();
6578        let mut line: VecDeque<Chunk> = VecDeque::new();
6579
6580        let theme = &cx.global::<Settings>().theme.editor.syntax;
6581
6582        for chunk in chunks {
6583            let highlight = chunk.syntax_highlight_id.and_then(|id| id.name(theme));
6584            let mut chunk_lines = chunk.text.split("\n").peekable();
6585            while let Some(text) = chunk_lines.next() {
6586                let mut merged_with_last_token = false;
6587                if let Some(last_token) = line.back_mut() {
6588                    if last_token.highlight == highlight {
6589                        last_token.text.push_str(text);
6590                        merged_with_last_token = true;
6591                    }
6592                }
6593
6594                if !merged_with_last_token {
6595                    line.push_back(Chunk {
6596                        text: text.into(),
6597                        highlight,
6598                    });
6599                }
6600
6601                if chunk_lines.peek().is_some() {
6602                    if line.len() > 1 && line.front().unwrap().text.is_empty() {
6603                        line.pop_front();
6604                    }
6605                    if line.len() > 1 && line.back().unwrap().text.is_empty() {
6606                        line.pop_back();
6607                    }
6608
6609                    lines.push(mem::take(&mut line));
6610                }
6611            }
6612        }
6613
6614        let Some(lines) = serde_json::to_string_pretty(&lines).log_err() else { return; };
6615        cx.write_to_clipboard(ClipboardItem::new(lines));
6616    }
6617}
6618
6619fn consume_contiguous_rows(
6620    contiguous_row_selections: &mut Vec<Selection<Point>>,
6621    selection: &Selection<Point>,
6622    display_map: &DisplaySnapshot,
6623    selections: &mut std::iter::Peekable<std::slice::Iter<Selection<Point>>>,
6624) -> (u32, u32) {
6625    contiguous_row_selections.push(selection.clone());
6626    let start_row = selection.start.row;
6627    let mut end_row = ending_row(selection, display_map);
6628
6629    while let Some(next_selection) = selections.peek() {
6630        if next_selection.start.row <= end_row {
6631            end_row = ending_row(next_selection, display_map);
6632            contiguous_row_selections.push(selections.next().unwrap().clone());
6633        } else {
6634            break;
6635        }
6636    }
6637    (start_row, end_row)
6638}
6639
6640fn ending_row(next_selection: &Selection<Point>, display_map: &DisplaySnapshot) -> u32 {
6641    if next_selection.end.column > 0 || next_selection.is_empty() {
6642        display_map.next_line_boundary(next_selection.end).0.row + 1
6643    } else {
6644        next_selection.end.row
6645    }
6646}
6647
6648impl EditorSnapshot {
6649    pub fn language_at<T: ToOffset>(&self, position: T) -> Option<&Arc<Language>> {
6650        self.display_snapshot.buffer_snapshot.language_at(position)
6651    }
6652
6653    pub fn is_focused(&self) -> bool {
6654        self.is_focused
6655    }
6656
6657    pub fn placeholder_text(&self) -> Option<&Arc<str>> {
6658        self.placeholder_text.as_ref()
6659    }
6660
6661    pub fn scroll_position(&self) -> Vector2F {
6662        self.scroll_anchor.scroll_position(&self.display_snapshot)
6663    }
6664}
6665
6666impl Deref for EditorSnapshot {
6667    type Target = DisplaySnapshot;
6668
6669    fn deref(&self) -> &Self::Target {
6670        &self.display_snapshot
6671    }
6672}
6673
6674#[derive(Clone, Debug, PartialEq, Eq)]
6675pub enum Event {
6676    InputIgnored {
6677        text: Arc<str>,
6678    },
6679    ExcerptsAdded {
6680        buffer: ModelHandle<Buffer>,
6681        predecessor: ExcerptId,
6682        excerpts: Vec<(ExcerptId, ExcerptRange<language::Anchor>)>,
6683    },
6684    ExcerptsRemoved {
6685        ids: Vec<ExcerptId>,
6686    },
6687    BufferEdited,
6688    Edited,
6689    Reparsed,
6690    Blurred,
6691    DirtyChanged,
6692    Saved,
6693    TitleChanged,
6694    SelectionsChanged {
6695        local: bool,
6696    },
6697    ScrollPositionChanged {
6698        local: bool,
6699    },
6700    Closed,
6701}
6702
6703pub struct EditorFocused(pub ViewHandle<Editor>);
6704pub struct EditorBlurred(pub ViewHandle<Editor>);
6705pub struct EditorReleased(pub WeakViewHandle<Editor>);
6706
6707impl Entity for Editor {
6708    type Event = Event;
6709
6710    fn release(&mut self, cx: &mut MutableAppContext) {
6711        cx.emit_global(EditorReleased(self.handle.clone()));
6712    }
6713}
6714
6715impl View for Editor {
6716    fn render(&mut self, cx: &mut RenderContext<Self>) -> ElementBox {
6717        let style = self.style(cx);
6718        let font_changed = self.display_map.update(cx, |map, cx| {
6719            map.set_fold_ellipses_color(style.folds.ellipses.text_color);
6720            map.set_font(style.text.font_id, style.text.font_size, cx)
6721        });
6722
6723        if font_changed {
6724            let handle = self.handle.clone();
6725            cx.defer(move |cx| {
6726                if let Some(editor) = handle.upgrade(cx) {
6727                    editor.update(cx, |editor, cx| {
6728                        hide_hover(editor, &HideHover, cx);
6729                        hide_link_definition(editor, cx);
6730                    })
6731                }
6732            });
6733        }
6734
6735        Stack::new()
6736            .with_child(EditorElement::new(self.handle.clone(), style.clone()).boxed())
6737            .with_child(ChildView::new(&self.mouse_context_menu, cx).boxed())
6738            .boxed()
6739    }
6740
6741    fn ui_name() -> &'static str {
6742        "Editor"
6743    }
6744
6745    fn focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext<Self>) {
6746        if cx.is_self_focused() {
6747            let focused_event = EditorFocused(cx.handle());
6748            cx.emit_global(focused_event);
6749        }
6750        if let Some(rename) = self.pending_rename.as_ref() {
6751            cx.focus(&rename.editor);
6752        } else {
6753            if !self.focused {
6754                self.blink_manager.update(cx, BlinkManager::enable);
6755            }
6756            self.focused = true;
6757            self.buffer.update(cx, |buffer, cx| {
6758                buffer.finalize_last_transaction(cx);
6759                if self.leader_replica_id.is_none() {
6760                    buffer.set_active_selections(
6761                        &self.selections.disjoint_anchors(),
6762                        self.selections.line_mode,
6763                        self.cursor_shape,
6764                        cx,
6765                    );
6766                }
6767            });
6768        }
6769    }
6770
6771    fn focus_out(&mut self, _: AnyViewHandle, cx: &mut ViewContext<Self>) {
6772        let blurred_event = EditorBlurred(cx.handle());
6773        cx.emit_global(blurred_event);
6774        self.focused = false;
6775        self.blink_manager.update(cx, BlinkManager::disable);
6776        self.buffer
6777            .update(cx, |buffer, cx| buffer.remove_active_selections(cx));
6778        self.hide_context_menu(cx);
6779        hide_hover(self, &HideHover, cx);
6780        cx.emit(Event::Blurred);
6781        cx.notify();
6782    }
6783
6784    fn modifiers_changed(
6785        &mut self,
6786        event: &gpui::ModifiersChangedEvent,
6787        cx: &mut ViewContext<Self>,
6788    ) -> bool {
6789        let pending_selection = self.has_pending_selection();
6790
6791        if let Some(point) = self.link_go_to_definition_state.last_mouse_location.clone() {
6792            if event.cmd && !pending_selection {
6793                let snapshot = self.snapshot(cx);
6794                let kind = if event.shift {
6795                    LinkDefinitionKind::Type
6796                } else {
6797                    LinkDefinitionKind::Symbol
6798                };
6799
6800                show_link_definition(kind, self, point, snapshot, cx);
6801                return false;
6802            }
6803        }
6804
6805        {
6806            if self.link_go_to_definition_state.symbol_range.is_some()
6807                || !self.link_go_to_definition_state.definitions.is_empty()
6808            {
6809                self.link_go_to_definition_state.symbol_range.take();
6810                self.link_go_to_definition_state.definitions.clear();
6811                cx.notify();
6812            }
6813
6814            self.link_go_to_definition_state.task = None;
6815
6816            self.clear_text_highlights::<LinkGoToDefinitionState>(cx);
6817        }
6818
6819        false
6820    }
6821
6822    fn keymap_context(&self, _: &AppContext) -> KeymapContext {
6823        let mut context = Self::default_keymap_context();
6824        let mode = match self.mode {
6825            EditorMode::SingleLine => "single_line",
6826            EditorMode::AutoHeight { .. } => "auto_height",
6827            EditorMode::Full => "full",
6828        };
6829        context.add_key("mode", mode);
6830        if self.pending_rename.is_some() {
6831            context.add_identifier("renaming");
6832        }
6833        match self.context_menu.as_ref() {
6834            Some(ContextMenu::Completions(_)) => context.add_identifier("showing_completions"),
6835            Some(ContextMenu::CodeActions(_)) => context.add_identifier("showing_code_actions"),
6836            None => {}
6837        }
6838
6839        for layer in self.keymap_context_layers.values() {
6840            context.extend(layer);
6841        }
6842
6843        context
6844    }
6845
6846    fn text_for_range(&self, range_utf16: Range<usize>, cx: &AppContext) -> Option<String> {
6847        Some(
6848            self.buffer
6849                .read(cx)
6850                .read(cx)
6851                .text_for_range(OffsetUtf16(range_utf16.start)..OffsetUtf16(range_utf16.end))
6852                .collect(),
6853        )
6854    }
6855
6856    fn selected_text_range(&self, cx: &AppContext) -> Option<Range<usize>> {
6857        // Prevent the IME menu from appearing when holding down an alphabetic key
6858        // while input is disabled.
6859        if !self.input_enabled {
6860            return None;
6861        }
6862
6863        let range = self.selections.newest::<OffsetUtf16>(cx).range();
6864        Some(range.start.0..range.end.0)
6865    }
6866
6867    fn marked_text_range(&self, cx: &AppContext) -> Option<Range<usize>> {
6868        let snapshot = self.buffer.read(cx).read(cx);
6869        let range = self.text_highlights::<InputComposition>(cx)?.1.get(0)?;
6870        Some(range.start.to_offset_utf16(&snapshot).0..range.end.to_offset_utf16(&snapshot).0)
6871    }
6872
6873    fn unmark_text(&mut self, cx: &mut ViewContext<Self>) {
6874        self.clear_text_highlights::<InputComposition>(cx);
6875        self.ime_transaction.take();
6876    }
6877
6878    fn replace_text_in_range(
6879        &mut self,
6880        range_utf16: Option<Range<usize>>,
6881        text: &str,
6882        cx: &mut ViewContext<Self>,
6883    ) {
6884        self.transact(cx, |this, cx| {
6885            if this.input_enabled {
6886                let new_selected_ranges = if let Some(range_utf16) = range_utf16 {
6887                    let range_utf16 = OffsetUtf16(range_utf16.start)..OffsetUtf16(range_utf16.end);
6888                    Some(this.selection_replacement_ranges(range_utf16, cx))
6889                } else {
6890                    this.marked_text_ranges(cx)
6891                };
6892
6893                if let Some(new_selected_ranges) = new_selected_ranges {
6894                    this.change_selections(None, cx, |selections| {
6895                        selections.select_ranges(new_selected_ranges)
6896                    });
6897                }
6898            }
6899
6900            this.handle_input(text, cx);
6901        });
6902
6903        if !self.input_enabled {
6904            return;
6905        }
6906
6907        if let Some(transaction) = self.ime_transaction {
6908            self.buffer.update(cx, |buffer, cx| {
6909                buffer.group_until_transaction(transaction, cx);
6910            });
6911        }
6912
6913        self.unmark_text(cx);
6914    }
6915
6916    fn replace_and_mark_text_in_range(
6917        &mut self,
6918        range_utf16: Option<Range<usize>>,
6919        text: &str,
6920        new_selected_range_utf16: Option<Range<usize>>,
6921        cx: &mut ViewContext<Self>,
6922    ) {
6923        if !self.input_enabled {
6924            return;
6925        }
6926
6927        let transaction = self.transact(cx, |this, cx| {
6928            let ranges_to_replace = if let Some(mut marked_ranges) = this.marked_text_ranges(cx) {
6929                let snapshot = this.buffer.read(cx).read(cx);
6930                if let Some(relative_range_utf16) = range_utf16.as_ref() {
6931                    for marked_range in &mut marked_ranges {
6932                        marked_range.end.0 = marked_range.start.0 + relative_range_utf16.end;
6933                        marked_range.start.0 += relative_range_utf16.start;
6934                        marked_range.start =
6935                            snapshot.clip_offset_utf16(marked_range.start, Bias::Left);
6936                        marked_range.end =
6937                            snapshot.clip_offset_utf16(marked_range.end, Bias::Right);
6938                    }
6939                }
6940                Some(marked_ranges)
6941            } else if let Some(range_utf16) = range_utf16 {
6942                let range_utf16 = OffsetUtf16(range_utf16.start)..OffsetUtf16(range_utf16.end);
6943                Some(this.selection_replacement_ranges(range_utf16, cx))
6944            } else {
6945                None
6946            };
6947
6948            if let Some(ranges) = ranges_to_replace {
6949                this.change_selections(None, cx, |s| s.select_ranges(ranges));
6950            }
6951
6952            let marked_ranges = {
6953                let snapshot = this.buffer.read(cx).read(cx);
6954                this.selections
6955                    .disjoint_anchors()
6956                    .iter()
6957                    .map(|selection| {
6958                        selection.start.bias_left(&*snapshot)..selection.end.bias_right(&*snapshot)
6959                    })
6960                    .collect::<Vec<_>>()
6961            };
6962
6963            if text.is_empty() {
6964                this.unmark_text(cx);
6965            } else {
6966                this.highlight_text::<InputComposition>(
6967                    marked_ranges.clone(),
6968                    this.style(cx).composition_mark,
6969                    cx,
6970                );
6971            }
6972
6973            this.handle_input(text, cx);
6974
6975            if let Some(new_selected_range) = new_selected_range_utf16 {
6976                let snapshot = this.buffer.read(cx).read(cx);
6977                let new_selected_ranges = marked_ranges
6978                    .into_iter()
6979                    .map(|marked_range| {
6980                        let insertion_start = marked_range.start.to_offset_utf16(&snapshot).0;
6981                        let new_start = OffsetUtf16(new_selected_range.start + insertion_start);
6982                        let new_end = OffsetUtf16(new_selected_range.end + insertion_start);
6983                        snapshot.clip_offset_utf16(new_start, Bias::Left)
6984                            ..snapshot.clip_offset_utf16(new_end, Bias::Right)
6985                    })
6986                    .collect::<Vec<_>>();
6987
6988                drop(snapshot);
6989                this.change_selections(None, cx, |selections| {
6990                    selections.select_ranges(new_selected_ranges)
6991                });
6992            }
6993        });
6994
6995        self.ime_transaction = self.ime_transaction.or(transaction);
6996        if let Some(transaction) = self.ime_transaction {
6997            self.buffer.update(cx, |buffer, cx| {
6998                buffer.group_until_transaction(transaction, cx);
6999            });
7000        }
7001
7002        if self.text_highlights::<InputComposition>(cx).is_none() {
7003            self.ime_transaction.take();
7004        }
7005    }
7006}
7007
7008fn build_style(
7009    settings: &Settings,
7010    get_field_editor_theme: Option<&GetFieldEditorTheme>,
7011    override_text_style: Option<&OverrideTextStyle>,
7012    cx: &AppContext,
7013) -> EditorStyle {
7014    let font_cache = cx.font_cache();
7015
7016    let mut theme = settings.theme.editor.clone();
7017    let mut style = if let Some(get_field_editor_theme) = get_field_editor_theme {
7018        let field_editor_theme = get_field_editor_theme(&settings.theme);
7019        theme.text_color = field_editor_theme.text.color;
7020        theme.selection = field_editor_theme.selection;
7021        theme.background = field_editor_theme
7022            .container
7023            .background_color
7024            .unwrap_or_default();
7025        EditorStyle {
7026            text: field_editor_theme.text,
7027            placeholder_text: field_editor_theme.placeholder_text,
7028            theme,
7029        }
7030    } else {
7031        let font_family_id = settings.buffer_font_family;
7032        let font_family_name = cx.font_cache().family_name(font_family_id).unwrap();
7033        let font_properties = Default::default();
7034        let font_id = font_cache
7035            .select_font(font_family_id, &font_properties)
7036            .unwrap();
7037        let font_size = settings.buffer_font_size;
7038        EditorStyle {
7039            text: TextStyle {
7040                color: settings.theme.editor.text_color,
7041                font_family_name,
7042                font_family_id,
7043                font_id,
7044                font_size,
7045                font_properties,
7046                underline: Default::default(),
7047            },
7048            placeholder_text: None,
7049            theme,
7050        }
7051    };
7052
7053    if let Some(highlight_style) = override_text_style.and_then(|build_style| build_style(&style)) {
7054        if let Some(highlighted) = style
7055            .text
7056            .clone()
7057            .highlight(highlight_style, font_cache)
7058            .log_err()
7059        {
7060            style.text = highlighted;
7061        }
7062    }
7063
7064    style
7065}
7066
7067trait SelectionExt {
7068    fn offset_range(&self, buffer: &MultiBufferSnapshot) -> Range<usize>;
7069    fn point_range(&self, buffer: &MultiBufferSnapshot) -> Range<Point>;
7070    fn display_range(&self, map: &DisplaySnapshot) -> Range<DisplayPoint>;
7071    fn spanned_rows(&self, include_end_if_at_line_start: bool, map: &DisplaySnapshot)
7072        -> Range<u32>;
7073}
7074
7075impl<T: ToPoint + ToOffset> SelectionExt for Selection<T> {
7076    fn point_range(&self, buffer: &MultiBufferSnapshot) -> Range<Point> {
7077        let start = self.start.to_point(buffer);
7078        let end = self.end.to_point(buffer);
7079        if self.reversed {
7080            end..start
7081        } else {
7082            start..end
7083        }
7084    }
7085
7086    fn offset_range(&self, buffer: &MultiBufferSnapshot) -> Range<usize> {
7087        let start = self.start.to_offset(buffer);
7088        let end = self.end.to_offset(buffer);
7089        if self.reversed {
7090            end..start
7091        } else {
7092            start..end
7093        }
7094    }
7095
7096    fn display_range(&self, map: &DisplaySnapshot) -> Range<DisplayPoint> {
7097        let start = self
7098            .start
7099            .to_point(&map.buffer_snapshot)
7100            .to_display_point(map);
7101        let end = self
7102            .end
7103            .to_point(&map.buffer_snapshot)
7104            .to_display_point(map);
7105        if self.reversed {
7106            end..start
7107        } else {
7108            start..end
7109        }
7110    }
7111
7112    fn spanned_rows(
7113        &self,
7114        include_end_if_at_line_start: bool,
7115        map: &DisplaySnapshot,
7116    ) -> Range<u32> {
7117        let start = self.start.to_point(&map.buffer_snapshot);
7118        let mut end = self.end.to_point(&map.buffer_snapshot);
7119        if !include_end_if_at_line_start && start.row != end.row && end.column == 0 {
7120            end.row -= 1;
7121        }
7122
7123        let buffer_start = map.prev_line_boundary(start).0;
7124        let buffer_end = map.next_line_boundary(end).0;
7125        buffer_start.row..buffer_end.row + 1
7126    }
7127}
7128
7129impl<T: InvalidationRegion> InvalidationStack<T> {
7130    fn invalidate<S>(&mut self, selections: &[Selection<S>], buffer: &MultiBufferSnapshot)
7131    where
7132        S: Clone + ToOffset,
7133    {
7134        while let Some(region) = self.last() {
7135            let all_selections_inside_invalidation_ranges =
7136                if selections.len() == region.ranges().len() {
7137                    selections
7138                        .iter()
7139                        .zip(region.ranges().iter().map(|r| r.to_offset(buffer)))
7140                        .all(|(selection, invalidation_range)| {
7141                            let head = selection.head().to_offset(buffer);
7142                            invalidation_range.start <= head && invalidation_range.end >= head
7143                        })
7144                } else {
7145                    false
7146                };
7147
7148            if all_selections_inside_invalidation_ranges {
7149                break;
7150            } else {
7151                self.pop();
7152            }
7153        }
7154    }
7155}
7156
7157impl<T> Default for InvalidationStack<T> {
7158    fn default() -> Self {
7159        Self(Default::default())
7160    }
7161}
7162
7163impl<T> Deref for InvalidationStack<T> {
7164    type Target = Vec<T>;
7165
7166    fn deref(&self) -> &Self::Target {
7167        &self.0
7168    }
7169}
7170
7171impl<T> DerefMut for InvalidationStack<T> {
7172    fn deref_mut(&mut self) -> &mut Self::Target {
7173        &mut self.0
7174    }
7175}
7176
7177impl InvalidationRegion for SnippetState {
7178    fn ranges(&self) -> &[Range<Anchor>] {
7179        &self.ranges[self.active_index]
7180    }
7181}
7182
7183impl Deref for EditorStyle {
7184    type Target = theme::Editor;
7185
7186    fn deref(&self) -> &Self::Target {
7187        &self.theme
7188    }
7189}
7190
7191pub fn diagnostic_block_renderer(diagnostic: Diagnostic, is_valid: bool) -> RenderBlock {
7192    let mut highlighted_lines = Vec::new();
7193    for line in diagnostic.message.lines() {
7194        highlighted_lines.push(highlight_diagnostic_message(line));
7195    }
7196
7197    Arc::new(move |cx: &mut BlockContext| {
7198        let settings = cx.global::<Settings>();
7199        let theme = &settings.theme.editor;
7200        let style = diagnostic_style(diagnostic.severity, is_valid, theme);
7201        let font_size = (style.text_scale_factor * settings.buffer_font_size).round();
7202        Flex::column()
7203            .with_children(highlighted_lines.iter().map(|(line, highlights)| {
7204                Label::new(
7205                    line.clone(),
7206                    style.message.clone().with_font_size(font_size),
7207                )
7208                .with_highlights(highlights.clone())
7209                .contained()
7210                .with_margin_left(cx.anchor_x)
7211                .boxed()
7212            }))
7213            .aligned()
7214            .left()
7215            .boxed()
7216    })
7217}
7218
7219pub fn highlight_diagnostic_message(message: &str) -> (String, Vec<usize>) {
7220    let mut message_without_backticks = String::new();
7221    let mut prev_offset = 0;
7222    let mut inside_block = false;
7223    let mut highlights = Vec::new();
7224    for (match_ix, (offset, _)) in message
7225        .match_indices('`')
7226        .chain([(message.len(), "")])
7227        .enumerate()
7228    {
7229        message_without_backticks.push_str(&message[prev_offset..offset]);
7230        if inside_block {
7231            highlights.extend(prev_offset - match_ix..offset - match_ix);
7232        }
7233
7234        inside_block = !inside_block;
7235        prev_offset = offset + 1;
7236    }
7237
7238    (message_without_backticks, highlights)
7239}
7240
7241pub fn diagnostic_style(
7242    severity: DiagnosticSeverity,
7243    valid: bool,
7244    theme: &theme::Editor,
7245) -> DiagnosticStyle {
7246    match (severity, valid) {
7247        (DiagnosticSeverity::ERROR, true) => theme.error_diagnostic.clone(),
7248        (DiagnosticSeverity::ERROR, false) => theme.invalid_error_diagnostic.clone(),
7249        (DiagnosticSeverity::WARNING, true) => theme.warning_diagnostic.clone(),
7250        (DiagnosticSeverity::WARNING, false) => theme.invalid_warning_diagnostic.clone(),
7251        (DiagnosticSeverity::INFORMATION, true) => theme.information_diagnostic.clone(),
7252        (DiagnosticSeverity::INFORMATION, false) => theme.invalid_information_diagnostic.clone(),
7253        (DiagnosticSeverity::HINT, true) => theme.hint_diagnostic.clone(),
7254        (DiagnosticSeverity::HINT, false) => theme.invalid_hint_diagnostic.clone(),
7255        _ => theme.invalid_hint_diagnostic.clone(),
7256    }
7257}
7258
7259pub fn combine_syntax_and_fuzzy_match_highlights(
7260    text: &str,
7261    default_style: HighlightStyle,
7262    syntax_ranges: impl Iterator<Item = (Range<usize>, HighlightStyle)>,
7263    match_indices: &[usize],
7264) -> Vec<(Range<usize>, HighlightStyle)> {
7265    let mut result = Vec::new();
7266    let mut match_indices = match_indices.iter().copied().peekable();
7267
7268    for (range, mut syntax_highlight) in syntax_ranges.chain([(usize::MAX..0, Default::default())])
7269    {
7270        syntax_highlight.weight = None;
7271
7272        // Add highlights for any fuzzy match characters before the next
7273        // syntax highlight range.
7274        while let Some(&match_index) = match_indices.peek() {
7275            if match_index >= range.start {
7276                break;
7277            }
7278            match_indices.next();
7279            let end_index = char_ix_after(match_index, text);
7280            let mut match_style = default_style;
7281            match_style.weight = Some(fonts::Weight::BOLD);
7282            result.push((match_index..end_index, match_style));
7283        }
7284
7285        if range.start == usize::MAX {
7286            break;
7287        }
7288
7289        // Add highlights for any fuzzy match characters within the
7290        // syntax highlight range.
7291        let mut offset = range.start;
7292        while let Some(&match_index) = match_indices.peek() {
7293            if match_index >= range.end {
7294                break;
7295            }
7296
7297            match_indices.next();
7298            if match_index > offset {
7299                result.push((offset..match_index, syntax_highlight));
7300            }
7301
7302            let mut end_index = char_ix_after(match_index, text);
7303            while let Some(&next_match_index) = match_indices.peek() {
7304                if next_match_index == end_index && next_match_index < range.end {
7305                    end_index = char_ix_after(next_match_index, text);
7306                    match_indices.next();
7307                } else {
7308                    break;
7309                }
7310            }
7311
7312            let mut match_style = syntax_highlight;
7313            match_style.weight = Some(fonts::Weight::BOLD);
7314            result.push((match_index..end_index, match_style));
7315            offset = end_index;
7316        }
7317
7318        if offset < range.end {
7319            result.push((offset..range.end, syntax_highlight));
7320        }
7321    }
7322
7323    fn char_ix_after(ix: usize, text: &str) -> usize {
7324        ix + text[ix..].chars().next().unwrap().len_utf8()
7325    }
7326
7327    result
7328}
7329
7330pub fn styled_runs_for_code_label<'a>(
7331    label: &'a CodeLabel,
7332    syntax_theme: &'a theme::SyntaxTheme,
7333) -> impl 'a + Iterator<Item = (Range<usize>, HighlightStyle)> {
7334    let fade_out = HighlightStyle {
7335        fade_out: Some(0.35),
7336        ..Default::default()
7337    };
7338
7339    let mut prev_end = label.filter_range.end;
7340    label
7341        .runs
7342        .iter()
7343        .enumerate()
7344        .flat_map(move |(ix, (range, highlight_id))| {
7345            let style = if let Some(style) = highlight_id.style(syntax_theme) {
7346                style
7347            } else {
7348                return Default::default();
7349            };
7350            let mut muted_style = style;
7351            muted_style.highlight(fade_out);
7352
7353            let mut runs = SmallVec::<[(Range<usize>, HighlightStyle); 3]>::new();
7354            if range.start >= label.filter_range.end {
7355                if range.start > prev_end {
7356                    runs.push((prev_end..range.start, fade_out));
7357                }
7358                runs.push((range.clone(), muted_style));
7359            } else if range.end <= label.filter_range.end {
7360                runs.push((range.clone(), style));
7361            } else {
7362                runs.push((range.start..label.filter_range.end, style));
7363                runs.push((label.filter_range.end..range.end, muted_style));
7364            }
7365            prev_end = cmp::max(prev_end, range.end);
7366
7367            if ix + 1 == label.runs.len() && label.text.len() > prev_end {
7368                runs.push((prev_end..label.text.len(), fade_out));
7369            }
7370
7371            runs
7372        })
7373}
7374
7375pub fn split_words<'a>(text: &'a str) -> impl std::iter::Iterator<Item = &'a str> + 'a {
7376    let mut index = 0;
7377    let mut codepoints = text.char_indices().peekable();
7378
7379    std::iter::from_fn(move || {
7380        let start_index = index;
7381        while let Some((new_index, codepoint)) = codepoints.next() {
7382            index = new_index + codepoint.len_utf8();
7383            let current_upper = codepoint.is_uppercase();
7384            let next_upper = codepoints
7385                .peek()
7386                .map(|(_, c)| c.is_uppercase())
7387                .unwrap_or(false);
7388
7389            if !current_upper && next_upper {
7390                return Some(&text[start_index..index]);
7391            }
7392        }
7393
7394        index = text.len();
7395        if start_index < text.len() {
7396            return Some(&text[start_index..]);
7397        }
7398        None
7399    })
7400    .flat_map(|word| word.split_inclusive('_'))
7401}
7402
7403trait RangeToAnchorExt {
7404    fn to_anchors(self, snapshot: &MultiBufferSnapshot) -> Range<Anchor>;
7405}
7406
7407impl<T: ToOffset> RangeToAnchorExt for Range<T> {
7408    fn to_anchors(self, snapshot: &MultiBufferSnapshot) -> Range<Anchor> {
7409        snapshot.anchor_after(self.start)..snapshot.anchor_before(self.end)
7410    }
7411}