editor.rs

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