23973 lines · 865.1 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;pub 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_colors;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 edit_prediction_tests;#[cfg(test)]mod editor_tests;mod signature_help;#[cfg(any(test, feature = "test-support"))]pub mod test; pub(crate) use actions::*;pub use display_map::{ChunkRenderer, ChunkRendererContext, DisplayPoint, FoldPlaceholder};pub use edit_prediction::Direction;pub use editor_settings::{    CurrentLineHighlight, DocumentColorsRenderMode, EditorSettings, HideMouseMode,    ScrollBeyondLastLine, ScrollbarAxes, SearchSettings, ShowMinimap, ShowScrollbar,};pub use editor_settings_controls::*;pub use element::{    CursorLayout, EditorElement, HighlightedRange, HighlightedRangeLine, PointForPosition,};pub use git::blame::BlameRenderer;pub use hover_popover::hover_markdown_style;pub use items::MAX_TAB_TITLE_LEN;pub use lsp::CompletionContext;pub use lsp_ext::lsp_tasks;pub use multi_buffer::{    Anchor, AnchorRangeExt, ExcerptId, ExcerptRange, MultiBuffer, MultiBufferSnapshot, PathKey,    RowInfo, ToOffset, ToPoint,};pub use proposed_changes_editor::{    ProposedChangeLocation, ProposedChangesEditor, ProposedChangesEditorToolbar,};pub use text::Bias; use ::git::{    Restore,    blame::{BlameEntry, ParsedCommitMessage},};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 code_context_menus::{    AvailableCodeAction, CodeActionContents, CodeActionsItem, CodeActionsMenu, CodeContextMenu,    CompletionsMenu, ContextMenuOrigin,};use collections::{BTreeMap, HashMap, HashSet, VecDeque};use convert_case::{Case, Casing};use dap::TelemetrySpawnLocation;use display_map::*;use edit_prediction::{EditPredictionProvider, EditPredictionProviderHandle};use editor_settings::{GoToDefinitionFallback, Minimap as MinimapSettings};use element::{AcceptEditPredictionBinding, LineWithInvisibles, PositionMap, layout_line};use futures::{    FutureExt, StreamExt as _,    future::{self, Shared, join},    stream::FuturesUnordered,};use fuzzy::{StringMatch, StringMatchCandidate};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, point, prelude::*, pulsating_between, px, relative, size,};use highlight_matching_bracket::refresh_matching_bracket_highlights;use hover_links::{HoverLink, HoveredLinkState, InlayHighlight, find_file};use hover_popover::{HoverState, hide_hover};use indent_guides::ActiveIndentGuidesState;use inlay_hint_cache::{InlayHintCache, InlaySplice, InvalidationStrategy};use itertools::{Either, Itertools};use language::{    AutoindentMode, BlockCommentConfig, BracketMatch, BracketPair, Buffer, BufferRow,    BufferSnapshot, Capability, CharClassifier, CharKind, CodeLabel, CursorShape, DiagnosticEntry,    DiffOptions, EditPredictionsMode, EditPreview, HighlightedText, IndentKind, IndentSize,    Language, OffsetRangeExt, Point, Runnable, RunnableRange, Selection, SelectionGoal, TextObject,    TransactionId, TreeSitterOptions, WordsQuery,    language_settings::{        self, InlayHintSettings, LspInsertMode, RewrapBehavior, WordsCompletionMode,        all_language_settings, language_settings,    },    point_from_lsp, point_to_lsp, text_diff_with_options,};use linked_editing_ranges::refresh_linked_ranges;use lsp::{    CodeActionKind, CompletionItemKind, CompletionTriggerKind, InsertTextFormat, InsertTextMode,    LanguageServerId,};use lsp_colors::LspColorData;use markdown::Markdown;use mouse_context_menu::MouseContextMenu;use movement::TextLayoutDetails;use multi_buffer::{    ExcerptInfo, ExpandExcerptDirection, MultiBufferDiffHunk, MultiBufferPoint, MultiBufferRow,    MultiOrSingleBufferOffsetRange, ToOffsetUtf16,};use parking_lot::Mutex;use persistence::DB;use project::{    BreakpointWithPosition, CodeAction, Completion, CompletionIntent, CompletionResponse,    CompletionSource, DisableAiSettings, DocumentHighlight, InlayHint, Location, LocationLink,    PrepareRenameResponse, Project, ProjectItem, ProjectPath, ProjectTransaction, TaskSourceKind,    debugger::breakpoint_store::Breakpoint,    debugger::{        breakpoint_store::{            BreakpointEditAction, BreakpointSessionState, BreakpointState, BreakpointStore,            BreakpointStoreEvent,        },        session::{Session, SessionEvent},    },    git_store::{GitStoreEvent, RepositoryEvent},    lsp_store::{CompletionDocumentation, FormatTrigger, LspFormatTarget, OpenLspBufferHandle},    project_settings::{DiagnosticSeverity, GoToDiagnosticSeverityFilter},    project_settings::{GitGutterSetting, ProjectSettings},};use rand::{seq::SliceRandom, thread_rng};use rpc::{ErrorCode, ErrorExt, proto::PeerId};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, smallvec};use snippet::Snippet;use std::{    any::TypeId,    borrow::Cow,    cell::OnceCell,    cell::RefCell,    cmp::{self, Ordering, Reverse},    iter::Peekable,    mem,    num::NonZeroU32,    ops::Not,    ops::{ControlFlow, Deref, DerefMut, Range, RangeInclusive},    path::{Path, PathBuf},    rc::Rc,    sync::Arc,    time::{Duration, Instant},};use sum_tree::TreeMap;use task::{ResolvedTask, RunnableTag, TaskTemplate, TaskVariables};use text::{BufferId, FromAnchor, OffsetUtf16, Rope};use theme::{    ActiveTheme, PlayerColor, StatusColors, SyntaxTheme, Theme, ThemeSettings,    observe_buffer_font_size_adjustment,};use ui::{    ButtonSize, ButtonStyle, ContextMenu, Disclosure, IconButton, IconButtonShape, IconName,    IconSize, Indicator, 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, SaveOptions},    notifications::{DetachAndPromptErr, NotificationId, NotifyTaskExt},    searchable::SearchEvent,}; use crate::{    code_context_menus::CompletionsMenuSource,    editor_settings::MultiCursorModifier,    hover_links::{find_url, find_url_from_range},    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 MINIMAP_FONT_SIZE: AbsoluteLength = AbsoluteLength::Pixels(px(2.)); pub type RenderDiffHunkControlsFn = Arc<    dyn Fn(        u32,        &DiffHunkStatus,        Range<Anchor>,        bool,        Pixels,        &Entity<Editor>,        &mut Window,        &mut App,    ) -> AnyElement,>; enum ReportEditorEvent {    Saved { auto_saved: bool },    EditorOpened,    ZetaTosClicked,    Closed,} impl ReportEditorEvent {    pub fn event_type(&self) -> &'static str {        match self {            Self::Saved { .. } => "Editor Saved",            Self::EditorOpened => "Editor Opened",            Self::ZetaTosClicked => "Edit Prediction Provider ToS Clicked",            Self::Closed => "Editor Closed",        }    }} 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 {    EditPrediction(usize),    DebuggerValue(usize),    // LSP    Hint(usize),    Color(usize),} impl InlayId {    fn id(&self) -> usize {        match self {            Self::EditPrediction(id) => *id,            Self::DebuggerValue(id) => *id,            Self::Hint(id) => *id,            Self::Color(id) => *id,        }    }} pub enum ActiveDebugLine {}pub enum DebugStackFrameLine {}enum DocumentHighlightRead {}enum DocumentHighlightWrite {}enum InputComposition {}pub enum PendingInput {}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);            workspace.register_action(Editor::toggle_focus);        },    )    .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,        mode: ColumnarMode,        goal_column: u32,    },    Extend {        position: DisplayPoint,        click_count: usize,    },    Update {        position: DisplayPoint,        goal_column: u32,        scroll_delta: gpui::Point<f32>,    },    End,} #[derive(Clone, Debug, PartialEq)]pub enum ColumnarMode {    FromMouse,    FromSelection,} #[derive(Clone, Debug)]pub enum SelectMode {    Character,    Word(Range<Anchor>),    Line(Range<Anchor>),    All,} #[derive(Clone, PartialEq, Eq, Debug)]pub enum EditorMode {    SingleLine,    AutoHeight {        min_lines: usize,

Lines 1–500 of 23973.