editor.rs

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