13594 lines · 539.6 KB · Rust
RawDownload
use crate::{    ActiveDiagnostic, BUFFER_HEADER_PADDING, BlockId, CURSORS_VISIBLE_FOR, ChunkRendererContext,    ChunkReplacement, CodeActionSource, ColumnarMode, ConflictsOurs, ConflictsOursMarker,    ConflictsOuter, ConflictsTheirs, ConflictsTheirsMarker, ContextMenuPlacement, CursorShape,    CustomBlockId, DisplayDiffHunk, DisplayPoint, DisplayRow, EditDisplayMode, EditPrediction,    Editor, EditorMode, EditorSettings, EditorSnapshot, EditorStyle, FILE_HEADER_HEIGHT,    FocusedBlock, GutterDimensions, HalfPageDown, HalfPageUp, HandleInput, HoveredCursor,    InlayHintRefreshReason, JumpData, LineDown, LineHighlight, LineUp, MAX_LINE_LEN,    MINIMAP_FONT_SIZE, MULTI_BUFFER_EXCERPT_HEADER_HEIGHT, OpenExcerpts, PageDown, PageUp,    PhantomBreakpointIndicator, PhantomDiffReviewIndicator, Point, RowExt, RowRangeExt,    SelectPhase, Selection, SelectionDragState, SelectionEffects, SizingBehavior, SoftWrap,    StickyHeaderExcerpt, ToPoint, ToggleFold, ToggleFoldAll,    code_context_menus::{CodeActionsMenu, MENU_ASIDE_MAX_WIDTH, MENU_ASIDE_MIN_WIDTH, MENU_GAP},    column_pixels,    display_map::{        Block, BlockContext, BlockStyle, ChunkRendererId, DisplaySnapshot, EditorMargins,        HighlightKey, HighlightedChunk, ToDisplayPoint,    },    editor_settings::{        CurrentLineHighlight, DocumentColorsRenderMode, DoubleClickInMultibuffer, Minimap,        MinimapThumb, MinimapThumbBorder, ScrollBeyondLastLine, ScrollbarAxes,        ScrollbarDiagnostics, ShowMinimap,    },    git::blame::{BlameRenderer, GitBlame, GlobalBlameRenderer},    hover_popover::{        self, HOVER_POPOVER_GAP, MIN_POPOVER_CHARACTER_WIDTH, MIN_POPOVER_LINE_HEIGHT,        POPOVER_RIGHT_OFFSET, hover_at,    },    inlay_hint_settings,    mouse_context_menu::{self, MenuPosition},    scroll::{        ActiveScrollbarState, Autoscroll, ScrollOffset, ScrollPixelOffset, ScrollbarThumbState,        scroll_amount::ScrollAmount,    },};use buffer_diff::{DiffHunkStatus, DiffHunkStatusKind};use collections::{BTreeMap, HashMap};use feature_flags::{DiffReviewFeatureFlag, FeatureFlagAppExt as _};use file_icons::FileIcons;use git::{Oid, blame::BlameEntry, commit::ParsedCommitMessage, status::FileStatus};use gpui::{    Action, Along, AnyElement, App, AppContext, AvailableSpace, Axis as ScrollbarAxis, BorderStyle,    Bounds, ClickEvent, ClipboardItem, ContentMask, Context, Corner, Corners, CursorStyle,    DispatchPhase, Edges, Element, ElementInputHandler, Entity, Focusable as _, Font, FontId,    FontWeight, GlobalElementId, Hitbox, HitboxBehavior, Hsla, InteractiveElement, IntoElement,    IsZero, KeybindingKeystroke, Length, Modifiers, ModifiersChangedEvent, MouseButton,    MouseClickEvent, MouseDownEvent, MouseMoveEvent, MousePressureEvent, MouseUpEvent, PaintQuad,    ParentElement, Pixels, PressureStage, ScrollDelta, ScrollHandle, ScrollWheelEvent, ShapedLine,    SharedString, Size, StatefulInteractiveElement, Style, Styled, StyledText, TextAlign, TextRun,    TextStyleRefinement, WeakEntity, Window, anchored, deferred, div, fill, linear_color_stop,    linear_gradient, outline, pattern_slash, point, px, quad, relative, size, solid_background,    transparent_black,};use itertools::Itertools;use language::{HighlightedText, IndentGuideSettings, language_settings::ShowWhitespaceSetting};use markdown::Markdown;use multi_buffer::{    Anchor, ExcerptId, ExcerptInfo, ExpandExcerptDirection, ExpandInfo, MultiBufferPoint,    MultiBufferRow, RowInfo,}; use edit_prediction_types::EditPredictionGranularity; use project::{    DisableAiSettings, Entry, ProjectPath,    debugger::breakpoint_store::{Breakpoint, BreakpointSessionState},    project_settings::ProjectSettings,};use settings::{    GitGutterSetting, GitHunkStyleSetting, IndentGuideBackgroundColoring, IndentGuideColoring,    RelativeLineNumbers, Settings,};use smallvec::{SmallVec, smallvec};use std::{    any::TypeId,    borrow::Cow,    cell::Cell,    cmp::{self, Ordering},    fmt::{self, Write},    iter, mem,    ops::{Deref, Range},    path::{self, Path},    rc::Rc,    sync::Arc,    time::{Duration, Instant},};use sum_tree::Bias;use text::{BufferId, SelectionGoal};use theme::{ActiveTheme, Appearance, BufferLineHeight, PlayerColor};use ui::utils::ensure_minimum_contrast;use ui::{    ButtonLike, ContextMenu, Indicator, KeyBinding, POPOVER_Y_PADDING, Tooltip, prelude::*,    right_click_menu, scrollbars::ShowScrollbar, text_for_keystroke,};use unicode_segmentation::UnicodeSegmentation;use util::post_inc;use util::{RangeExt, ResultExt, debug_panic};use workspace::{    CollaboratorId, ItemHandle, ItemSettings, OpenInTerminal, OpenTerminal, RevealInProjectPanel,    Workspace,    item::{Item, ItemBufferKind},}; /// Determines what kinds of highlights should be applied to a lines background.#[derive(Clone, Copy, Default)]struct LineHighlightSpec {    selection: bool,    breakpoint: bool,    _active_stack_frame: bool,} #[derive(Debug)]struct SelectionLayout {    head: DisplayPoint,    cursor_shape: CursorShape,    is_newest: bool,    is_local: bool,    range: Range<DisplayPoint>,    active_rows: Range<DisplayRow>,    user_name: Option<SharedString>,} struct InlineBlameLayout {    element: AnyElement,    bounds: Bounds<Pixels>,    buffer_id: BufferId,    entry: BlameEntry,} impl SelectionLayout {    fn new<T: ToPoint + ToDisplayPoint + Clone>(        selection: Selection<T>,        line_mode: bool,        cursor_offset: bool,        cursor_shape: CursorShape,        map: &DisplaySnapshot,        is_newest: bool,        is_local: bool,        user_name: Option<SharedString>,    ) -> Self {        let point_selection = selection.map(|p| p.to_point(map.buffer_snapshot()));        let display_selection = point_selection.map(|p| p.to_display_point(map));        let mut range = display_selection.range();        let mut head = display_selection.head();        let mut active_rows = map.prev_line_boundary(point_selection.start).1.row()            ..map.next_line_boundary(point_selection.end).1.row();         // vim visual line mode        if line_mode {            let point_range = map.expand_to_line(point_selection.range());            range = point_range.start.to_display_point(map)..point_range.end.to_display_point(map);        }         // any vim visual mode (including line mode)        if cursor_offset && !range.is_empty() && !selection.reversed {            if head.column() > 0 {                head = map.clip_point(DisplayPoint::new(head.row(), head.column() - 1), Bias::Left);            } else if head.row().0 > 0 && head != map.max_point() {                head = map.clip_point(                    DisplayPoint::new(                        head.row().previous_row(),                        map.line_len(head.row().previous_row()),                    ),                    Bias::Left,                );                // updating range.end is a no-op unless you're cursor is                // on the newline containing a multi-buffer divider                // in which case the clip_point may have moved the head up                // an additional row.                range.end = DisplayPoint::new(head.row().next_row(), 0);                active_rows.end = head.row();            }        }         Self {            head,            cursor_shape,            is_newest,            is_local,            range,            active_rows,            user_name,        }    }} #[derive(Default)]struct RenderBlocksOutput {    // We store spacer blocks separately because they paint in a different order    // (spacers -> indent guides -> non-spacers)    non_spacer_blocks: Vec<BlockLayout>,    spacer_blocks: Vec<BlockLayout>,    row_block_types: HashMap<DisplayRow, bool>,    resized_blocks: Option<HashMap<CustomBlockId, u32>>,} pub struct EditorElement {    editor: Entity<Editor>,    style: EditorStyle,    split_side: Option<SplitSide>,} #[derive(Debug, Clone, Copy, PartialEq, Eq)]pub enum SplitSide {    Left,    Right,} impl EditorElement {    pub(crate) const SCROLLBAR_WIDTH: Pixels = px(15.);     pub fn new(editor: &Entity<Editor>, style: EditorStyle) -> Self {        Self {            editor: editor.clone(),            style,            split_side: None,        }    }     pub fn set_split_side(&mut self, side: SplitSide) {        self.split_side = Some(side);    }     fn should_show_buffer_headers(&self) -> bool {        self.split_side.is_none()    }     fn register_actions(&self, window: &mut Window, cx: &mut App) {        let editor = &self.editor;        editor.update(cx, |editor, cx| {            for action in editor.editor_actions.borrow().values() {                (action)(editor, window, cx)            }        });         crate::rust_analyzer_ext::apply_related_actions(editor, window, cx);        crate::clangd_ext::apply_related_actions(editor, window, cx);         register_action(editor, window, Editor::open_context_menu);        register_action(editor, window, Editor::move_left);        register_action(editor, window, Editor::move_right);        register_action(editor, window, Editor::move_down);        register_action(editor, window, Editor::move_down_by_lines);        register_action(editor, window, Editor::select_down_by_lines);        register_action(editor, window, Editor::move_up);        register_action(editor, window, Editor::move_up_by_lines);        register_action(editor, window, Editor::select_up_by_lines);        register_action(editor, window, Editor::select_page_down);        register_action(editor, window, Editor::select_page_up);        register_action(editor, window, Editor::cancel);        register_action(editor, window, Editor::newline);        register_action(editor, window, Editor::newline_above);        register_action(editor, window, Editor::newline_below);        register_action(editor, window, Editor::backspace);        register_action(editor, window, Editor::blame_hover);        register_action(editor, window, Editor::delete);        register_action(editor, window, Editor::tab);        register_action(editor, window, Editor::next_snippet_tabstop);        register_action(editor, window, Editor::previous_snippet_tabstop);        register_action(editor, window, Editor::backtab);        register_action(editor, window, Editor::indent);        register_action(editor, window, Editor::outdent);        register_action(editor, window, Editor::autoindent);        register_action(editor, window, Editor::delete_line);        register_action(editor, window, Editor::join_lines);        register_action(editor, window, Editor::sort_lines_by_length);        register_action(editor, window, Editor::sort_lines_case_sensitive);        register_action(editor, window, Editor::sort_lines_case_insensitive);        register_action(editor, window, Editor::reverse_lines);        register_action(editor, window, Editor::shuffle_lines);        register_action(editor, window, Editor::rotate_selections_forward);        register_action(editor, window, Editor::rotate_selections_backward);        register_action(editor, window, Editor::convert_indentation_to_spaces);        register_action(editor, window, Editor::convert_indentation_to_tabs);        register_action(editor, window, Editor::convert_to_upper_case);        register_action(editor, window, Editor::convert_to_lower_case);        register_action(editor, window, Editor::convert_to_title_case);        register_action(editor, window, Editor::convert_to_snake_case);        register_action(editor, window, Editor::convert_to_kebab_case);        register_action(editor, window, Editor::convert_to_upper_camel_case);        register_action(editor, window, Editor::convert_to_lower_camel_case);        register_action(editor, window, Editor::convert_to_opposite_case);        register_action(editor, window, Editor::convert_to_sentence_case);        register_action(editor, window, Editor::toggle_case);        register_action(editor, window, Editor::convert_to_rot13);        register_action(editor, window, Editor::convert_to_rot47);        register_action(editor, window, Editor::delete_to_previous_word_start);        register_action(editor, window, Editor::delete_to_previous_subword_start);        register_action(editor, window, Editor::delete_to_next_word_end);        register_action(editor, window, Editor::delete_to_next_subword_end);        register_action(editor, window, Editor::delete_to_beginning_of_line);        register_action(editor, window, Editor::delete_to_end_of_line);        register_action(editor, window, Editor::cut_to_end_of_line);        register_action(editor, window, Editor::duplicate_line_up);        register_action(editor, window, Editor::duplicate_line_down);        register_action(editor, window, Editor::duplicate_selection);        register_action(editor, window, Editor::move_line_up);        register_action(editor, window, Editor::move_line_down);        register_action(editor, window, Editor::transpose);        register_action(editor, window, Editor::rewrap);        register_action(editor, window, Editor::cut);        register_action(editor, window, Editor::kill_ring_cut);        register_action(editor, window, Editor::kill_ring_yank);        register_action(editor, window, Editor::copy);        register_action(editor, window, Editor::copy_and_trim);        register_action(editor, window, Editor::diff_clipboard_with_selection);        register_action(editor, window, Editor::paste);        register_action(editor, window, Editor::undo);        register_action(editor, window, Editor::redo);        register_action(editor, window, Editor::move_page_up);        register_action(editor, window, Editor::move_page_down);        register_action(editor, window, Editor::next_screen);        register_action(editor, window, Editor::scroll_cursor_top);        register_action(editor, window, Editor::scroll_cursor_center);        register_action(editor, window, Editor::scroll_cursor_bottom);        register_action(editor, window, Editor::scroll_cursor_center_top_bottom);        register_action(editor, window, |editor, _: &LineDown, window, cx| {            editor.scroll_screen(&ScrollAmount::Line(1.), window, cx)        });        register_action(editor, window, |editor, _: &LineUp, window, cx| {            editor.scroll_screen(&ScrollAmount::Line(-1.), window, cx)        });        register_action(editor, window, |editor, _: &HalfPageDown, window, cx| {            editor.scroll_screen(&ScrollAmount::Page(0.5), window, cx)        });        register_action(            editor,            window,            |editor, HandleInput(text): &HandleInput, window, cx| {                if text.is_empty() {                    return;                }                editor.handle_input(text, window, cx);            },        );        register_action(editor, window, |editor, _: &HalfPageUp, window, cx| {            editor.scroll_screen(&ScrollAmount::Page(-0.5), window, cx)        });        register_action(editor, window, |editor, _: &PageDown, window, cx| {            editor.scroll_screen(&ScrollAmount::Page(1.), window, cx)        });        register_action(editor, window, |editor, _: &PageUp, window, cx| {            editor.scroll_screen(&ScrollAmount::Page(-1.), window, cx)        });        register_action(editor, window, Editor::move_to_previous_word_start);        register_action(editor, window, Editor::move_to_previous_subword_start);        register_action(editor, window, Editor::move_to_next_word_end);        register_action(editor, window, Editor::move_to_next_subword_end);        register_action(editor, window, Editor::move_to_beginning_of_line);        register_action(editor, window, Editor::move_to_end_of_line);        register_action(editor, window, Editor::move_to_start_of_paragraph);        register_action(editor, window, Editor::move_to_end_of_paragraph);        register_action(editor, window, Editor::move_to_beginning);        register_action(editor, window, Editor::move_to_end);        register_action(editor, window, Editor::move_to_start_of_excerpt);        register_action(editor, window, Editor::move_to_start_of_next_excerpt);        register_action(editor, window, Editor::move_to_end_of_excerpt);        register_action(editor, window, Editor::move_to_end_of_previous_excerpt);        register_action(editor, window, Editor::select_up);        register_action(editor, window, Editor::select_down);        register_action(editor, window, Editor::select_left);        register_action(editor, window, Editor::select_right);        register_action(editor, window, Editor::select_to_previous_word_start);        register_action(editor, window, Editor::select_to_previous_subword_start);        register_action(editor, window, Editor::select_to_next_word_end);        register_action(editor, window, Editor::select_to_next_subword_end);        register_action(editor, window, Editor::select_to_beginning_of_line);        register_action(editor, window, Editor::select_to_end_of_line);        register_action(editor, window, Editor::select_to_start_of_paragraph);        register_action(editor, window, Editor::select_to_end_of_paragraph);        register_action(editor, window, Editor::select_to_start_of_excerpt);        register_action(editor, window, Editor::select_to_start_of_next_excerpt);        register_action(editor, window, Editor::select_to_end_of_excerpt);        register_action(editor, window, Editor::select_to_end_of_previous_excerpt);        register_action(editor, window, Editor::select_to_beginning);        register_action(editor, window, Editor::select_to_end);        register_action(editor, window, Editor::select_all);        register_action(editor, window, |editor, action, window, cx| {            editor.select_all_matches(action, window, cx).log_err();        });        register_action(editor, window, Editor::select_line);        register_action(editor, window, Editor::split_selection_into_lines);        register_action(editor, window, Editor::add_selection_above);        register_action(editor, window, Editor::add_selection_below);        register_action(editor, window, Editor::insert_snippet_at_selections);        register_action(editor, window, |editor, action, window, cx| {            editor.select_next(action, window, cx).log_err();        });        register_action(editor, window, |editor, action, window, cx| {            editor.select_previous(action, window, cx).log_err();        });        register_action(editor, window, |editor, action, window, cx| {            editor.find_next_match(action, window, cx).log_err();        });        register_action(editor, window, |editor, action, window, cx| {            editor.find_previous_match(action, window, cx).log_err();        });        register_action(editor, window, Editor::toggle_comments);        register_action(editor, window, Editor::select_larger_syntax_node);        register_action(editor, window, Editor::select_smaller_syntax_node);        register_action(editor, window, Editor::select_next_syntax_node);        register_action(editor, window, Editor::select_prev_syntax_node);        register_action(            editor,            window,            Editor::select_to_start_of_larger_syntax_node,        );        register_action(editor, window, Editor::select_to_end_of_larger_syntax_node);        register_action(editor, window, Editor::unwrap_syntax_node);        register_action(editor, window, Editor::move_to_start_of_larger_syntax_node);        register_action(editor, window, Editor::move_to_end_of_larger_syntax_node);        register_action(editor, window, Editor::select_enclosing_symbol);        register_action(editor, window, Editor::move_to_enclosing_bracket);        register_action(editor, window, Editor::undo_selection);        register_action(editor, window, Editor::redo_selection);        if editor.read(cx).buffer_kind(cx) == ItemBufferKind::Multibuffer {            register_action(editor, window, Editor::expand_excerpts);            register_action(editor, window, Editor::expand_excerpts_up);            register_action(editor, window, Editor::expand_excerpts_down);        }        register_action(editor, window, Editor::go_to_diagnostic);        register_action(editor, window, Editor::go_to_prev_diagnostic);        register_action(editor, window, Editor::go_to_next_hunk);        register_action(editor, window, Editor::go_to_prev_hunk);        register_action(editor, window, Editor::go_to_next_document_highlight);        register_action(editor, window, Editor::go_to_prev_document_highlight);        register_action(editor, window, |editor, action, window, cx| {            editor                .go_to_definition(action, window, cx)                .detach_and_log_err(cx);        });        register_action(editor, window, |editor, action, window, cx| {            editor                .go_to_definition_split(action, window, cx)                .detach_and_log_err(cx);        });        register_action(editor, window, |editor, action, window, cx| {            editor                .go_to_declaration(action, window, cx)                .detach_and_log_err(cx);        });        register_action(editor, window, |editor, action, window, cx| {            editor                .go_to_declaration_split(action, window, cx)                .detach_and_log_err(cx);        });        register_action(editor, window, |editor, action, window, cx| {            editor                .go_to_implementation(action, window, cx)                .detach_and_log_err(cx);        });        register_action(editor, window, |editor, action, window, cx| {            editor                .go_to_implementation_split(action, window, cx)                .detach_and_log_err(cx);        });        register_action(editor, window, |editor, action, window, cx| {            editor                .go_to_type_definition(action, window, cx)                .detach_and_log_err(cx);        });        register_action(editor, window, |editor, action, window, cx| {            editor                .go_to_type_definition_split(action, window, cx)                .detach_and_log_err(cx);        });        register_action(editor, window, Editor::open_url);        register_action(editor, window, Editor::open_selected_filename);        register_action(editor, window, Editor::fold);        register_action(editor, window, Editor::fold_at_level);        register_action(editor, window, Editor::fold_at_level_1);        register_action(editor, window, Editor::fold_at_level_2);        register_action(editor, window, Editor::fold_at_level_3);        register_action(editor, window, Editor::fold_at_level_4);        register_action(editor, window, Editor::fold_at_level_5);        register_action(editor, window, Editor::fold_at_level_6);        register_action(editor, window, Editor::fold_at_level_7);        register_action(editor, window, Editor::fold_at_level_8);        register_action(editor, window, Editor::fold_at_level_9);        register_action(editor, window, Editor::fold_all);        register_action(editor, window, Editor::fold_function_bodies);        register_action(editor, window, Editor::fold_recursive);        register_action(editor, window, Editor::toggle_fold);        register_action(editor, window, Editor::toggle_fold_recursive);        register_action(editor, window, Editor::toggle_fold_all);        register_action(editor, window, Editor::unfold_lines);        register_action(editor, window, Editor::unfold_recursive);        register_action(editor, window, Editor::unfold_all);        register_action(editor, window, Editor::fold_selected_ranges);        register_action(editor, window, Editor::set_mark);        register_action(editor, window, Editor::swap_selection_ends);        register_action(editor, window, Editor::show_completions);        register_action(editor, window, Editor::show_word_completions);        register_action(editor, window, Editor::toggle_code_actions);        register_action(editor, window, Editor::open_excerpts);        register_action(editor, window, Editor::open_excerpts_in_split);        register_action(editor, window, Editor::toggle_soft_wrap);        register_action(editor, window, Editor::toggle_tab_bar);        register_action(editor, window, Editor::toggle_line_numbers);        register_action(editor, window, Editor::toggle_relative_line_numbers);

Lines 1–500 of 13594.