21322 lines · 772.3 KB · Rust
RawDownload
#![allow(rustdoc::private_intra_doc_links)]//! This is the place where everything editor-related is stored (data-wise) and displayed (ui-wise).//! The main point of interest in this crate is [`Editor`] type, which is used in every other Zed part as a user input element.//! It comes in different flavors: single line, multiline and a fixed height one.//!//! Editor contains of multiple large submodules://! * [`element`] — the place where all rendering happens//! * [`display_map`] - chunks up text in the editor into the logical blocks, establishes coordinates and mapping between each of them.//!   Contains all metadata related to text transformations (folds, fake inlay text insertions, soft wraps, tab markup, etc.).//! * [`inlay_hint_cache`] - is a storage of inlay hints out of LSP requests, responsible for querying LSP and updating `display_map`'s state accordingly.//!//! All other submodules and structs are mostly concerned with holding editor data about the way it displays current buffer region(s).//!//! If you're looking to improve Vim mode, you should check out Vim crate that wraps Editor and overrides its behavior.pub mod actions;mod blink_manager;mod clangd_ext;mod code_context_menus;pub mod display_map;mod editor_settings;mod editor_settings_controls;mod element;mod git;mod highlight_matching_bracket;mod hover_links;pub mod hover_popover;mod indent_guides;mod inlay_hint_cache;pub mod items;mod jsx_tag_auto_close;mod linked_editing_ranges;mod lsp_ext;mod mouse_context_menu;pub mod movement;mod persistence;mod proposed_changes_editor;mod rust_analyzer_ext;pub mod scroll;mod selections_collection;pub mod tasks; #[cfg(test)]mod code_completion_tests;#[cfg(test)]mod editor_tests;#[cfg(test)]mod inline_completion_tests;mod signature_help;#[cfg(any(test, feature = "test-support"))]pub mod test; pub(crate) use actions::*;pub use actions::{AcceptEditPrediction, OpenExcerpts, OpenExcerptsSplit};use aho_corasick::AhoCorasick;use anyhow::{Context as _, Result, anyhow};use blink_manager::BlinkManager;use buffer_diff::DiffHunkStatus;use client::{Collaborator, ParticipantIndex};use clock::{AGENT_REPLICA_ID, ReplicaId};use collections::{BTreeMap, HashMap, HashSet, VecDeque};use convert_case::{Case, Casing};use display_map::*;pub use display_map::{ChunkRenderer, ChunkRendererContext, DisplayPoint, FoldPlaceholder};use editor_settings::GoToDefinitionFallback;pub use editor_settings::{    CurrentLineHighlight, EditorSettings, HideMouseMode, ScrollBeyondLastLine, SearchSettings,    ShowScrollbar,};pub use editor_settings_controls::*;use element::{AcceptEditPredictionBinding, LineWithInvisibles, PositionMap, layout_line};pub use element::{    CursorLayout, EditorElement, HighlightedRange, HighlightedRangeLine, PointForPosition,};use feature_flags::{DebuggerFeatureFlag, FeatureFlagAppExt};use futures::{    FutureExt,    future::{self, Shared, join},};use fuzzy::StringMatchCandidate; use ::git::blame::BlameEntry;use ::git::{Restore, blame::ParsedCommitMessage};use code_context_menus::{    AvailableCodeAction, CodeActionContents, CodeActionsItem, CodeActionsMenu, CodeContextMenu,    CompletionsMenu, ContextMenuOrigin,};use git::blame::{GitBlame, GlobalBlameRenderer};use gpui::{    Action, Animation, AnimationExt, AnyElement, App, AppContext, AsyncWindowContext,    AvailableSpace, Background, Bounds, ClickEvent, ClipboardEntry, ClipboardItem, Context,    DispatchPhase, Edges, Entity, EntityInputHandler, EventEmitter, FocusHandle, FocusOutEvent,    Focusable, FontId, FontWeight, Global, HighlightStyle, Hsla, KeyContext, Modifiers,    MouseButton, MouseDownEvent, PaintQuad, ParentElement, Pixels, Render, ScrollHandle,    SharedString, Size, Stateful, Styled, Subscription, Task, TextStyle, TextStyleRefinement,    UTF16Selection, UnderlineStyle, UniformListScrollHandle, WeakEntity, WeakFocusHandle, Window,    div, impl_actions, point, prelude::*, pulsating_between, px, relative, size,};use highlight_matching_bracket::refresh_matching_bracket_highlights;use hover_links::{HoverLink, HoveredLinkState, InlayHighlight, find_file};pub use hover_popover::hover_markdown_style;use hover_popover::{HoverState, hide_hover};use indent_guides::ActiveIndentGuidesState;use inlay_hint_cache::{InlayHintCache, InlaySplice, InvalidationStrategy};pub use inline_completion::Direction;use inline_completion::{EditPredictionProvider, InlineCompletionProviderHandle};pub use items::MAX_TAB_TITLE_LEN;use itertools::Itertools;use language::{    AutoindentMode, BracketMatch, BracketPair, Buffer, Capability, CharKind, CodeLabel,    CursorShape, DiagnosticEntry, DiffOptions, EditPredictionsMode, EditPreview, HighlightedText,    IndentKind, IndentSize, Language, OffsetRangeExt, Point, Selection, SelectionGoal, TextObject,    TransactionId, TreeSitterOptions, WordsQuery,    language_settings::{        self, InlayHintSettings, LspInsertMode, RewrapBehavior, WordsCompletionMode,        all_language_settings, language_settings,    },    point_from_lsp, text_diff_with_options,};use language::{BufferRow, CharClassifier, Runnable, RunnableRange, point_to_lsp};use linked_editing_ranges::refresh_linked_ranges;use markdown::Markdown;use mouse_context_menu::MouseContextMenu;use persistence::DB;use project::{    ProjectPath,    debugger::{        breakpoint_store::{            BreakpointEditAction, BreakpointState, BreakpointStore, BreakpointStoreEvent,        },        session::{Session, SessionEvent},    },}; pub use git::blame::BlameRenderer;pub use proposed_changes_editor::{    ProposedChangeLocation, ProposedChangesEditor, ProposedChangesEditorToolbar,};use smallvec::smallvec;use std::{cell::OnceCell, iter::Peekable};use task::{ResolvedTask, RunnableTag, TaskTemplate, TaskVariables}; pub use lsp::CompletionContext;use lsp::{    CodeActionKind, CompletionItemKind, CompletionTriggerKind, DiagnosticSeverity,    InsertTextFormat, InsertTextMode, LanguageServerId, LanguageServerName,}; use language::BufferSnapshot;pub use lsp_ext::lsp_tasks;use movement::TextLayoutDetails;pub use multi_buffer::{    Anchor, AnchorRangeExt, ExcerptId, ExcerptRange, MultiBuffer, MultiBufferSnapshot, PathKey,    RowInfo, ToOffset, ToPoint,};use multi_buffer::{    ExcerptInfo, ExpandExcerptDirection, MultiBufferDiffHunk, MultiBufferPoint, MultiBufferRow,    MultiOrSingleBufferOffsetRange, ToOffsetUtf16,};use parking_lot::Mutex;use project::{    CodeAction, Completion, CompletionIntent, CompletionSource, DocumentHighlight, InlayHint,    Location, LocationLink, PrepareRenameResponse, Project, ProjectItem, ProjectTransaction,    TaskSourceKind,    debugger::breakpoint_store::Breakpoint,    lsp_store::{CompletionDocumentation, FormatTrigger, LspFormatTarget, OpenLspBufferHandle},    project_settings::{GitGutterSetting, ProjectSettings},};use rand::prelude::*;use rpc::{ErrorExt, proto::*};use scroll::{Autoscroll, OngoingScroll, ScrollAnchor, ScrollManager, ScrollbarAutoHide};use selections_collection::{    MutableSelectionsCollection, SelectionsCollection, resolve_selections,};use serde::{Deserialize, Serialize};use settings::{Settings, SettingsLocation, SettingsStore, update_settings_file};use smallvec::SmallVec;use snippet::Snippet;use std::sync::Arc;use std::{    any::TypeId,    borrow::Cow,    cell::RefCell,    cmp::{self, Ordering, Reverse},    mem,    num::NonZeroU32,    ops::{ControlFlow, Deref, DerefMut, Not as _, Range, RangeInclusive},    path::{Path, PathBuf},    rc::Rc,    time::{Duration, Instant},};pub use sum_tree::Bias;use sum_tree::TreeMap;use text::{BufferId, FromAnchor, OffsetUtf16, Rope};use theme::{    ActiveTheme, PlayerColor, StatusColors, SyntaxTheme, ThemeColors, ThemeSettings,    observe_buffer_font_size_adjustment,};use ui::{    ButtonSize, ButtonStyle, ContextMenu, Disclosure, IconButton, IconButtonShape, IconName,    IconSize, Key, Tooltip, h_flex, prelude::*,};use util::{RangeExt, ResultExt, TryFutureExt, maybe, post_inc};use workspace::{    CollaboratorId, Item as WorkspaceItem, ItemId, ItemNavHistory, OpenInTerminal, OpenTerminal,    RestoreOnStartupBehavior, SERIALIZATION_THROTTLE_TIME, SplitDirection, TabBarSettings, Toast,    ViewId, Workspace, WorkspaceId, WorkspaceSettings,    item::{ItemHandle, PreviewTabsSettings},    notifications::{DetachAndPromptErr, NotificationId, NotifyTaskExt},    searchable::SearchEvent,}; use crate::hover_links::{find_url, find_url_from_range};use crate::signature_help::{SignatureHelpHiddenBy, SignatureHelpState}; pub const FILE_HEADER_HEIGHT: u32 = 2;pub const MULTI_BUFFER_EXCERPT_HEADER_HEIGHT: u32 = 1;pub const DEFAULT_MULTIBUFFER_CONTEXT: u32 = 2;const CURSOR_BLINK_INTERVAL: Duration = Duration::from_millis(500);const MAX_LINE_LEN: usize = 1024;const MIN_NAVIGATION_HISTORY_ROW_DELTA: i64 = 10;const MAX_SELECTION_HISTORY_LEN: usize = 1024;pub(crate) const CURSORS_VISIBLE_FOR: Duration = Duration::from_millis(2000);#[doc(hidden)]pub const CODE_ACTIONS_DEBOUNCE_TIMEOUT: Duration = Duration::from_millis(250);const SELECTION_HIGHLIGHT_DEBOUNCE_TIMEOUT: Duration = Duration::from_millis(100); pub(crate) const CODE_ACTION_TIMEOUT: Duration = Duration::from_secs(5);pub(crate) const FORMAT_TIMEOUT: Duration = Duration::from_secs(5);pub(crate) const SCROLL_CENTER_TOP_BOTTOM_DEBOUNCE_TIMEOUT: Duration = Duration::from_secs(1); pub(crate) const EDIT_PREDICTION_KEY_CONTEXT: &str = "edit_prediction";pub(crate) const EDIT_PREDICTION_CONFLICT_KEY_CONTEXT: &str = "edit_prediction_conflict";pub(crate) const MIN_LINE_NUMBER_DIGITS: u32 = 4; pub type RenderDiffHunkControlsFn = Arc<    dyn Fn(        u32,        &DiffHunkStatus,        Range<Anchor>,        bool,        Pixels,        &Entity<Editor>,        &mut Window,        &mut App,    ) -> AnyElement,>; const COLUMNAR_SELECTION_MODIFIERS: Modifiers = Modifiers {    alt: true,    shift: true,    control: false,    platform: false,    function: false,}; struct InlineValueCache {    enabled: bool,    inlays: Vec<InlayId>,    refresh_task: Task<Option<()>>,} impl InlineValueCache {    fn new(enabled: bool) -> Self {        Self {            enabled,            inlays: Vec::new(),            refresh_task: Task::ready(None),        }    }} #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]pub enum InlayId {    InlineCompletion(usize),    Hint(usize),    DebuggerValue(usize),} impl InlayId {    fn id(&self) -> usize {        match self {            Self::InlineCompletion(id) => *id,            Self::Hint(id) => *id,            Self::DebuggerValue(id) => *id,        }    }} pub enum ActiveDebugLine {}enum DocumentHighlightRead {}enum DocumentHighlightWrite {}enum InputComposition {}enum SelectedTextHighlight {} pub enum ConflictsOuter {}pub enum ConflictsOurs {}pub enum ConflictsTheirs {}pub enum ConflictsOursMarker {}pub enum ConflictsTheirsMarker {} #[derive(Debug, Copy, Clone, PartialEq, Eq)]pub enum Navigated {    Yes,    No,} impl Navigated {    pub fn from_bool(yes: bool) -> Navigated {        if yes { Navigated::Yes } else { Navigated::No }    }} #[derive(Debug, Clone, PartialEq, Eq)]enum DisplayDiffHunk {    Folded {        display_row: DisplayRow,    },    Unfolded {        is_created_file: bool,        diff_base_byte_range: Range<usize>,        display_row_range: Range<DisplayRow>,        multi_buffer_range: Range<Anchor>,        status: DiffHunkStatus,    },} pub enum HideMouseCursorOrigin {    TypingAction,    MovementAction,} pub fn init_settings(cx: &mut App) {    EditorSettings::register(cx);} pub fn init(cx: &mut App) {    init_settings(cx);     cx.set_global(GlobalBlameRenderer(Arc::new(())));     workspace::register_project_item::<Editor>(cx);    workspace::FollowableViewRegistry::register::<Editor>(cx);    workspace::register_serializable_item::<Editor>(cx);     cx.observe_new(        |workspace: &mut Workspace, _: Option<&mut Window>, _cx: &mut Context<Workspace>| {            workspace.register_action(Editor::new_file);            workspace.register_action(Editor::new_file_vertical);            workspace.register_action(Editor::new_file_horizontal);            workspace.register_action(Editor::cancel_language_server_work);        },    )    .detach();     cx.on_action(move |_: &workspace::NewFile, cx| {        let app_state = workspace::AppState::global(cx);        if let Some(app_state) = app_state.upgrade() {            workspace::open_new(                Default::default(),                app_state,                cx,                |workspace, window, cx| {                    Editor::new_file(workspace, &Default::default(), window, cx)                },            )            .detach();        }    });    cx.on_action(move |_: &workspace::NewWindow, cx| {        let app_state = workspace::AppState::global(cx);        if let Some(app_state) = app_state.upgrade() {            workspace::open_new(                Default::default(),                app_state,                cx,                |workspace, window, cx| {                    cx.activate(true);                    Editor::new_file(workspace, &Default::default(), window, cx)                },            )            .detach();        }    });} pub fn set_blame_renderer(renderer: impl BlameRenderer + 'static, cx: &mut App) {    cx.set_global(GlobalBlameRenderer(Arc::new(renderer)));} pub trait DiagnosticRenderer {    fn render_group(        &self,        diagnostic_group: Vec<DiagnosticEntry<Point>>,        buffer_id: BufferId,        snapshot: EditorSnapshot,        editor: WeakEntity<Editor>,        cx: &mut App,    ) -> Vec<BlockProperties<Anchor>>;     fn render_hover(        &self,        diagnostic_group: Vec<DiagnosticEntry<Point>>,        range: Range<Point>,        buffer_id: BufferId,        cx: &mut App,    ) -> Option<Entity<markdown::Markdown>>;     fn open_link(        &self,        editor: &mut Editor,        link: SharedString,        window: &mut Window,        cx: &mut Context<Editor>,    );} pub(crate) struct GlobalDiagnosticRenderer(pub Arc<dyn DiagnosticRenderer>); impl GlobalDiagnosticRenderer {    fn global(cx: &App) -> Option<Arc<dyn DiagnosticRenderer>> {        cx.try_global::<Self>().map(|g| g.0.clone())    }} impl gpui::Global for GlobalDiagnosticRenderer {}pub fn set_diagnostic_renderer(renderer: impl DiagnosticRenderer + 'static, cx: &mut App) {    cx.set_global(GlobalDiagnosticRenderer(Arc::new(renderer)));} pub struct SearchWithinRange; trait InvalidationRegion {    fn ranges(&self) -> &[Range<Anchor>];} #[derive(Clone, Debug, PartialEq)]pub enum SelectPhase {    Begin {        position: DisplayPoint,        add: bool,        click_count: usize,    },    BeginColumnar {        position: DisplayPoint,        reset: bool,        goal_column: u32,    },    Extend {        position: DisplayPoint,        click_count: usize,    },    Update {        position: DisplayPoint,        goal_column: u32,        scroll_delta: gpui::Point<f32>,    },    End,} #[derive(Clone, Debug)]pub enum SelectMode {    Character,    Word(Range<Anchor>),    Line(Range<Anchor>),    All,} #[derive(Copy, Clone, PartialEq, Eq, Debug)]pub enum EditorMode {    SingleLine {        auto_width: bool,    },    AutoHeight {        max_lines: usize,    },    Full {        /// When set to `true`, the editor will scale its UI elements with the buffer font size.        scale_ui_elements_with_buffer_font_size: bool,        /// When set to `true`, the editor will render a background for the active line.        show_active_line_background: bool,        /// When set to `true`, the editor's height will be determined by its content.        sized_by_content: bool,    },} impl EditorMode {    pub fn full() -> Self {        Self::Full {            scale_ui_elements_with_buffer_font_size: true,            show_active_line_background: true,            sized_by_content: false,        }    }     pub fn is_full(&self) -> bool {        matches!(self, Self::Full { .. })    }} #[derive(Copy, Clone, Debug)]

Lines 1–500 of 21322.