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