14085 lines · 557.6 KB · Rust
RawDownload
use crate::{    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, GutterHoverButton, HalfPageDown, HalfPageUp, HandleInput, HoveredCursor,    InlayHintRefreshReason, JumpData, LineDown, LineHighlight, LineUp, MAX_LINE_LEN,    MINIMAP_FONT_SIZE, MULTI_BUFFER_EXCERPT_HEADER_HEIGHT, OpenExcerpts, PageDown, PageUp,    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, HashSet};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, Corners, CursorStyle, DispatchPhase,    Edges, Element, ElementInputHandler, Entity, Focusable as _, Font, FontId, FontWeight,    GlobalElementId, Hitbox, HitboxBehavior, Hsla, InteractiveElement, IntoElement, IsZero, Length,    Modifiers, ModifiersChangedEvent, MouseButton, MouseClickEvent, MouseDownEvent, MouseMoveEvent,    MousePressureEvent, MouseUpEvent, PaintQuad, ParentElement, Pixels, PressureStage, ScrollDelta,    ScrollHandle, ScrollWheelEvent, ShapedLine, SharedString, Size, StatefulInteractiveElement,    Style, Styled, StyledText, TaskExt, 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, LanguageAwareStyling,    language_settings::ShowWhitespaceSetting,};use markdown::Markdown;use multi_buffer::{    Anchor, ExcerptBoundaryInfo, ExpandExcerptDirection, ExpandInfo, MultiBufferPoint,    MultiBufferRow, RowInfo,}; use project::{    DisableAiSettings, Entry,    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, PlayerColor};use theme_settings::BufferLineHeight;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 = 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 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::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(&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, _: &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::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::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_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_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);        register_action(editor, window, Editor::reveal_in_finder);        register_action(editor, window, Editor::copy_path);        register_action(editor, window, Editor::copy_relative_path);        register_action(editor, window, Editor::copy_file_name);        register_action(editor, window, Editor::copy_file_name_without_extension);        register_action(editor, window, Editor::copy_highlight_json);        register_action(editor, window, Editor::copy_permalink_to_line);        register_action(editor, window, Editor::open_permalink_to_line);        register_action(editor, window, Editor::copy_file_location);        register_action(editor, window, Editor::toggle_git_blame);        register_action(editor, window, Editor::toggle_git_blame_inline);        register_action(editor, window, Editor::open_git_blame_commit);        register_action(editor, window, Editor::toggle_selected_diff_hunks);        register_action(editor, window, Editor::toggle_staged_selected_diff_hunks);        register_action(editor, window, Editor::stage_and_next);        register_action(editor, window, Editor::unstage_and_next);        register_action(editor, window, Editor::expand_all_diff_hunks);        register_action(editor, window, Editor::collapse_all_diff_hunks);        register_action(editor, window, Editor::toggle_review_comments_expanded);        register_action(editor, window, Editor::submit_diff_review_comment_action);        register_action(editor, window, Editor::edit_review_comment);        register_action(editor, window, Editor::delete_review_comment);        register_action(editor, window, Editor::confirm_edit_review_comment_action);        register_action(editor, window, Editor::cancel_edit_review_comment_action);        register_action(editor, window, Editor::go_to_previous_change);        register_action(editor, window, Editor::go_to_next_change);        register_action(editor, window, Editor::go_to_prev_reference);        register_action(editor, window, Editor::go_to_next_reference);        register_action(editor, window, Editor::go_to_previous_symbol);        register_action(editor, window, Editor::go_to_next_symbol);        register_action(editor, window, Editor::restart_language_server);        register_action(editor, window, Editor::stop_language_server);        register_action(editor, window, Editor::show_character_palette);        register_action(editor, window, |editor, action, window, cx| {            if let Some(task) = editor.compose_completion(action, window, cx) {                editor.detach_and_notify_err(task, window, cx);            } else {                cx.propagate();            }        });        register_action(editor, window, |editor, action, window, cx| {            if let Some(task) = editor.find_all_references(action, window, cx) {                task.detach_and_log_err(cx);            } else {                cx.propagate();            }        });        register_action(editor, window, Editor::show_signature_help);

Lines 1–500 of 14085.