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