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