editor.rs

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