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