editor.rs

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