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