editor.rs

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