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