editor.rs

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