editor.rs

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