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