editor.rs

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