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