12296 lines · 488.1 KB · Rust
RawDownload
mod header;mod mouse; #[cfg(test)]pub(crate) use header::StickyHeader;pub use header::file_status_label_color;pub(crate) use header::{header_jump_data, render_buffer_header}; use crate::{    BUFFER_HEADER_PADDING, BlockId, ChunkRendererContext, ChunkReplacement, CodeActionSource,    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, LineDown, LineHighlight, LineUp,    MAX_LINE_LEN, MINIMAP_FONT_SIZE, PageDown, PageUp, Point, RowExt, RowRangeExt, Selection,    SelectionDragState, SizingBehavior, SoftWrap, ToPoint,    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, 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,    },    inlay_hint_settings,    scroll::{        ActiveScrollbarState, ScrollOffset, ScrollPixelOffset, ScrollbarThumbState,        scroll_amount::ScrollAmount,    },};use buffer_diff::{DiffHunkStatus, DiffHunkStatusKind};use collections::{BTreeMap, HashMap, HashSet};use feature_flags::{DiffReviewFeatureFlag, FeatureFlagAppExt as _};use git::{Oid, blame::BlameEntry, commit::ParsedCommitMessage};use gpui::{    Action, Along, AnyElement, App, AppContext, AvailableSpace, Axis as ScrollbarAxis, BorderStyle,    Bounds, ClipboardItem, ContentMask, Context, Corners, CursorStyle, DispatchPhase, Edges,    Element, ElementInputHandler, Entity, Focusable as _, Font, FontId, FontWeight,    GlobalElementId, Hitbox, HitboxBehavior, Hsla, InteractiveElement, IntoElement, IsZero,    ModifiersChangedEvent, MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent, PaintQuad,    ParentElement, Pixels, ScrollHandle, ShapedLine, SharedString, Size,    StatefulInteractiveElement, Style, Styled, StyledText, TaskExt, TextAlign, TextRun,    TextStyleRefinement, WeakEntity, Window, div, fill, outline, pattern_slash, point, px, quad,    relative, size, solid_background, transparent_black,};use itertools::Itertools;use language::{    HighlightedText, IndentGuideSettings, LanguageAwareStyling,    language_settings::ShowWhitespaceSetting,};use markdown::Markdown;use multi_buffer::{    Anchor, ExpandExcerptDirection, ExpandInfo, MultiBufferOffset, MultiBufferPoint,    MultiBufferRow, RowInfo, ToOffset,}; use project::{    debugger::breakpoint_store::{Breakpoint, BreakpointSessionState},    project_settings::ProjectSettings,};use settings::{    GitGutterSetting, GitHunkStyleSetting, IndentGuideBackgroundColoring, IndentGuideColoring,    Settings,};use smallvec::{SmallVec, smallvec};use std::{    any::TypeId,    borrow::Cow,    cell::Cell,    cmp::{self, Ordering},    fmt::{self, Write},    iter, mem,    ops::{Deref, Range},    rc::Rc,    sync::Arc,    time::Duration,};use sum_tree::Bias;use text::BufferId;use theme::{ActiveTheme, Appearance, PlayerColor};use theme_settings::BufferLineHeight;use ui::utils::ensure_minimum_contrast;use ui::{ButtonLike, POPOVER_Y_PADDING, Tooltip, prelude::*, scrollbars::ShowScrollbar};use unicode_segmentation::UnicodeSegmentation;use util::{ResultExt, debug_panic};use workspace::{    CollaboratorId, ItemHandle, 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,} enum LineNumberStyle {    Breakpoint,    DiffAdded,    DiffDeleted,    Active,    Inactive,} impl LineNumberStyle {    fn new(is_active: bool, is_breakpoint: bool, diff_status: Option<DiffHunkStatus>) -> Self {        match (            is_active,            is_breakpoint,            diff_status.map(|status| status.kind),        ) {            (_, true, _) => Self::Breakpoint,            (true, _, _) => Self::Active,            (_, _, Some(DiffHunkStatusKind::Added)) => Self::DiffAdded,            (_, _, Some(DiffHunkStatusKind::Deleted)) => Self::DiffDeleted,            (_, _, _) => Self::Inactive,        }    }     fn color(self, colors: &theme::ThemeColors) -> Hsla {        match self {            Self::Breakpoint => colors.debugger_accent,            Self::DiffAdded => colors.version_control_added,            Self::DiffDeleted => colors.version_control_deleted,            Self::Active => colors.editor_active_line_number,            Self::Inactive => colors.editor_line_number,        }    }} #[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 buffer_snapshot = map.buffer_snapshot();        let point_selection = selection.map(|p| p.to_point(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();        if !line_mode {            let offset_range = point_selection.start.to_offset(buffer_snapshot)                ..point_selection.end.to_offset(buffer_snapshot);            if let Some(contiguous_range) =                map.contiguous_display_point_range_for_buffer_range(offset_range)            {                range = contiguous_range;                // Keep the cursor attached to the highlight boundary; the                // anchor-bias display position may sit on the far side of a                // boundary inlay the highlight excludes.                head = if selection.reversed {                    range.start                } else {                    range.end                };            }        }        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 = ui::EDITOR_SCROLLBAR_WIDTH;     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 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::blame_hover);        register_action(editor, window, Editor::next_snippet_tabstop);        register_action(editor, window, Editor::previous_snippet_tabstop);        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::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_with_cursor_margin(&ScrollAmount::Line(1.), window, cx)        });        register_action(editor, window, |editor, _: &LineUp, window, cx| {            editor.scroll_screen_with_cursor_margin(&ScrollAmount::Line(-1.), window, cx)        });        register_action(editor, window, |editor, _: &HalfPageDown, window, cx| {            editor.scroll_screen_with_cursor_margin(&ScrollAmount::Page(0.5), window, cx)        });        register_action(editor, window, |editor, _: &HalfPageUp, window, cx| {            editor.scroll_screen_with_cursor_margin(&ScrollAmount::Page(-0.5), window, cx)        });        register_action(editor, window, |editor, _: &PageDown, window, cx| {            editor.scroll_screen_with_cursor_margin(&ScrollAmount::Page(1.), window, cx)        });        register_action(editor, window, |editor, _: &PageUp, window, cx| {            editor.scroll_screen_with_cursor_margin(&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_next_comment_paragraph);        register_action(editor, window, Editor::move_to_previous_comment_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::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::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::select_inside_delimiters);        register_action(editor, window, Editor::select_around_delimiters);        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::save_location);        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_breadcrumb);        register_action(editor, window, Editor::toggle_line_numbers);        register_action(editor, window, Editor::toggle_relative_line_numbers);        register_action(editor, window, Editor::toggle_indent_guides);        register_action(editor, window, Editor::toggle_inlay_hints);        register_action(editor, window, Editor::toggle_inline_values);        register_action(editor, window, Editor::toggle_code_lens_action);        register_action(editor, window, Editor::toggle_semantic_highlights);        register_action(editor, window, Editor::toggle_edit_predictions);        if editor.read(cx).diagnostics_enabled() {            register_action(editor, window, Editor::toggle_diagnostics);        }        if editor.read(cx).inline_diagnostics_enabled() {            register_action(editor, window, Editor::toggle_inline_diagnostics);        }        if editor.read(cx).supports_minimap(cx) {            register_action(editor, window, Editor::toggle_minimap);        }        register_action(editor, window, hover_popover::hover);

Lines 1–500 of 12296.