editor.rs

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