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