editor.rs

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