#![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.).//!//! 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;pub mod blink_manager;mod bracket_colorization;mod clangd_ext;pub mod code_context_menus;mod code_lens;pub mod display_map;mod document_colors;mod document_links;mod document_symbols;mod editor_settings;mod element;mod fold;mod folding_ranges;mod git;mod highlight_matching_bracket;pub mod hover_links;pub mod hover_popover;mod indent_guides;mod inlays;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 runnables;mod rust_analyzer_ext;pub mod scroll;mod selections_collection;pub mod semantic_tokens;mod split;pub mod split_editor_view; mod bookmarks;#[cfg(test)]mod code_completion_tests;#[cfg(test)]mod edit_prediction_tests;#[cfg(test)]mod editor_block_comment_tests;#[cfg(test)]mod editor_tests;mod signature_help;#[cfg(any(test, feature = "test-support"))]pub mod test; mod clipboard;mod code_actions;mod completions;mod config;mod diagnostics;mod edit_prediction;mod input;mod markdown_actions;mod navigation;mod rewrap;mod selection; pub(crate) use actions::*;pub use clipboard::ClipboardSelection;pub use code_actions::CodeActionProvider;use collections::TypeIdHashMap;pub use completions::CompletionProvider;#[cfg(test)]pub(crate) use completions::snippet_candidate_suffixes;pub(crate) use completions::split_words;use diagnostics::{ActiveDiagnostic, GlobalDiagnosticRenderer, InlineDiagnostic};pub use diagnostics::{DiagnosticRenderer, set_diagnostic_renderer};pub use display_map::{ ChunkRenderer, ChunkRendererContext, DisplayPoint, FoldPlaceholder, HighlightKey, NavigationOverlayKey, SemanticTokenHighlight,};pub use edit_prediction::make_suggestion_styles;pub(crate) use edit_prediction::{ EditDisplayMode, EditPrediction, EditPredictionPreview, EditPredictionSettings, EditPredictionState, MenuEditPredictionsPolicy, RegisteredEditPredictionDelegate,};#[cfg(test)]pub(crate) use edit_prediction::{ EditPredictionKeybindAction, EditPredictionKeybindSurface, edit_prediction_edit_text,};pub use edit_prediction_types::Direction;pub use edit_prediction_types::EditPredictionRequestTrigger;pub use editor_settings::{ CompletionDetailAlignment, CompletionMenuItemKind, CurrentLineHighlight, DiffViewStyle, DocumentColorsRenderMode, EditorSettings, EditorSettingsScrollbarProxy, OpenResultsIn, ScrollBeyondLastLine, ScrollbarAxes, SearchSettings, ShowMinimap, ui_scrollbar_settings_from_raw,};pub use element::{ CursorLayout, EditorElement, HighlightedRange, HighlightedRangeLine, PointForPosition, file_status_label_color, render_breadcrumb_text,};pub use git::blame::BlameRenderer;pub use git::{ DiffHunkDelegate, ResolvedDiffHunk, ResolvedDiffHunks, RestoreOnlyDiffHunkDelegate, RestoreOnlyUnstagedDiffHunkDelegate, UncommittedDiffHunkDelegate, render_diff_hunk_controls, set_blame_renderer,};pub(crate) use git::{DiffHunkKey, StoredReviewComment};use git::{DiffReviewDragState, DiffReviewOverlay, InlineBlamePopover};pub(crate) use git::{DisplayDiffHunk, PhantomDiffReviewIndicator};pub use hover_popover::hover_markdown_style;pub use inlays::Inlay;pub use items::MAX_TAB_TITLE_LEN;pub use linked_editing_ranges::LinkedEdits;pub use lsp::CompletionContext;pub use lsp_ext::lsp_tasks;pub use multi_buffer::{ Anchor, AnchorRangeExt, BufferOffset, ExcerptRange, MBTextSummary, MultiBuffer, MultiBufferOffset, MultiBufferOffsetUtf16, MultiBufferSnapshot, PathKey, RowInfo, ToOffset, ToPoint,};pub use split::{DiffStyleControls, SplittableEditor, ToggleSplitDiff};pub use split_editor_view::SplitEditorView;pub use text::Bias; use ::git::{Blame, status::FileStatus};use aho_corasick::{AhoCorasick, AhoCorasickBuilder, BuildError};use anyhow::{Context as _, Result, anyhow, bail};use blink_manager::BlinkManager;use client::{Collaborator, ParticipantIndex, parse_zed_link};use clock::ReplicaId;use code_context_menus::{ AvailableCodeAction, CodeActionContents, CodeActionsItem, CodeActionsMenu, CodeContextMenu, CompletionsMenu, ContextMenuOrigin,};use code_lens::CodeLensState;use collections::{BTreeMap, HashMap, HashSet, VecDeque};use convert_case::{Case, Casing};use dap::TelemetrySpawnLocation;use display_map::*;use document_colors::LspColorData;use document_links::LspDocumentLinks;use edit_prediction_types::{ EditPredictionDelegate, EditPredictionDelegateHandle, EditPredictionDiscardReason, EditPredictionGranularity, SuggestionDisplayType,};use editor_settings::{GoToDefinitionFallback, Minimap as MinimapSettings};use element::{LineWithInvisibles, PositionMap, layout_line};use futures::{ FutureExt, future::{self, Shared},};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, EntityId, EntityInputHandler, EventEmitter, FocusHandle, FocusOutEvent, Focusable, FontId, FontStyle, FontWeight, Global, HighlightStyle, Hsla, IsZero, KeyContext, Modifiers, MouseButton, MouseDownEvent, MouseMoveEvent, PaintQuad, ParentElement, Pixels, PressureStage, Render, ScrollHandle, SharedString, SharedUri, Size, Stateful, Styled, Subscription, Task, TextRun, TextStyle, TextStyleRefinement, UTF16Selection, UnderlineStyle, UniformListScrollHandle, WeakEntity, WeakFocusHandle, Window, div, point, prelude::*, pulsating_between, px, relative, size,};use hover_links::{HoverLink, HoveredLinkState, find_file};use hover_popover::{HoverState, hide_hover};use indent_guides::ActiveIndentGuidesState;use inlays::{InlaySplice, inlay_hints::InlayHintRefreshReason};use itertools::{Either, Itertools};use language::{ AutoindentMode, BlockCommentConfig, BracketMatch, BracketPair, Buffer, BufferRow, BufferSnapshot, Capability, CharClassifier, CharKind, CharScopeContext, CodeLabel, CursorShape, DiagnosticEntryRef, DiffOptions, EditPredictionsMode, EditPreview, HighlightedText, IndentKind, IndentSize, Language, LanguageAwareStyling, LanguageName, LanguageRegistry, LanguageScope, LocalFile, OffsetRangeExt, OutlineItem, Point, Selection, SelectionGoal, TextObject, TransactionId, TreeSitterOptions, WordsQuery, language_settings::{ self, AllLanguageSettings, LanguageSettings, LspInsertMode, RewrapBehavior, WordsCompletionMode, all_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 markdown::Markdown;use mouse_context_menu::MouseContextMenu;use movement::TextLayoutDetails;use multi_buffer::{ ExcerptBoundaryInfo, ExpandExcerptDirection, MultiBufferDiffHunk, MultiBufferPoint, MultiBufferRow,};use parking_lot::Mutex;use persistence::EditorDb;use project::{ BreakpointWithPosition, CodeAction, Completion, CompletionDisplayOptions, CompletionIntent, CompletionResponse, CompletionSource, DisableAiSettings, DocumentHighlight, InlayHint, InlayId, InvalidationStrategy, Location, LocationLink, LspAction, PrepareRenameResponse, Project, ProjectItem, ProjectPath, ProjectTransaction, bookmark_store::BookmarkStore, debugger::{ breakpoint_store::{ Breakpoint, BreakpointEditAction, BreakpointSessionState, BreakpointState, BreakpointStore, BreakpointStoreEvent, }, session::{Session, SessionEvent}, }, git_store::GitStoreEvent, lsp_store::{ BufferSemanticTokens, CacheInlayHints, CompletionDocumentation, FormatTrigger, LspFormatTarget, OpenLspBufferHandle, }, project_settings::{DiagnosticSeverity, GoToDiagnosticSeverityFilter, ProjectSettings},};use rand::seq::SliceRandom;use regex::Regex;use rpc::{ErrorCode, ErrorExt, proto::PeerId};use scroll::{Autoscroll, OngoingScroll, ScrollAnchor, ScrollManager, SharedScrollAnchor};use selections_collection::{MutableSelectionsCollection, SelectionsCollection};use serde::{Deserialize, Serialize};use settings::{ GitGutterSetting, RelativeLineNumbers, Settings, SettingsLocation, SettingsStore, update_settings_file,};use smallvec::{SmallVec, smallvec};use snippet::Snippet;use std::{ any::{Any, TypeId}, borrow::Cow, cell::{OnceCell, RefCell}, cmp::{self, Ordering, Reverse}, collections::hash_map, iter::{self, Peekable}, mem, num::NonZeroU32, ops::{ControlFlow, Deref, DerefMut, Not, Range, RangeInclusive}, path::{Path, PathBuf}, rc::Rc, sync::Arc, time::{Duration, Instant},};use task::TaskVariables;use text::{BufferId, FromAnchor, OffsetUtf16, Rope, ToOffset as _, ToPoint as _};use theme::{ AccentColors, ActiveTheme, GlobalTheme, PlayerColor, StatusColors, SyntaxTheme, Theme,};use theme_settings::{ThemeSettings, observe_buffer_font_size_adjustment};use ui::{ Avatar, ContextMenu, Disclosure, IconButtonShape, Indicator, Key, KeyBinding, Tooltip, prelude::*, scrollbars::ScrollbarAutoHide, tooltip_container, utils::WithRemSize,};use ui_input::ErasedEditor;use util::{RangeExt, ResultExt, TryFutureExt, maybe, post_inc};use workspace::{ CollaboratorId, Item as WorkspaceItem, ItemId, ItemNavHistory, NavigationEntry, OpenInTerminal, OpenTerminal, Pane, RestoreOnStartupBehavior, SERIALIZATION_THROTTLE_TIME, SplitDirection, TabBarSettings, Toast, ViewId, Workspace, WorkspaceId, WorkspaceSettings, item::{ItemBufferKind, ItemHandle, PreviewTabsSettings, SaveOptions}, notifications::{DetachAndPromptErr, NotificationId, NotifyResultExt, NotifyTaskExt}, searchable::SearchEvent,};pub use zed_actions::editor::RevealInFileManager;use zed_actions::editor::{MoveDown, MoveUp}; use crate::{ code_context_menus::CompletionsMenuSource, editor_settings::MultiCursorModifier, hover_links::{find_url, find_url_from_range}, inlays::{ InlineValueCache, inlay_hints::{LspInlayHintData, inlay_hint_settings}, }, runnables::{ResolvedTasks, RunnableData, RunnableTaskStatus, RunnableTasks}, scroll::{ScrollOffset, ScrollPixelOffset}, selections_collection::resolve_selections_wrapping_blocks, semantic_tokens::SemanticTokenState, signature_help::{SignatureHelpHiddenBy, SignatureHelpState},}; pub const FILE_HEADER_HEIGHT: u32 = 2;pub const BUFFER_HEADER_PADDING: Rems = rems(0.25);pub const MULTI_BUFFER_EXCERPT_HEADER_HEIGHT: u32 = 1;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);pub 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 const LSP_REQUEST_DEBOUNCE_TIMEOUT: Duration = Duration::from_millis(50); pub(crate) const EDIT_PREDICTION_KEY_CONTEXT: &str = "edit_prediction";pub(crate) const MINIMAP_FONT_SIZE: AbsoluteLength = AbsoluteLength::Pixels(px(2.)); enum ReportEditorEvent { Saved { auto_saved: bool }, EditorOpened, Closed,} impl ReportEditorEvent { pub fn event_type(&self) -> &'static str { match self { Self::Saved { .. } => "Editor Saved", Self::EditorOpened => "Editor Opened", Self::Closed => "Editor Closed", } }} pub enum ActiveDebugLine {}pub enum DebugStackFrameLine {} pub enum ConflictsOuter {}pub enum ConflictsOurs {}pub enum ConflictsTheirs {}pub enum ConflictsOursMarker {}pub enum ConflictsTheirsMarker {} pub struct HunkAddedColor;pub struct HunkRemovedColor; #[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 } }} pub fn init(cx: &mut App) { cx.set_global(GlobalBlameRenderer(Arc::new(()))); cx.set_global(breadcrumbs::RenderBreadcrumbText(render_breadcrumb_text)); 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_split); 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); workspace.register_action(Editor::view_bookmarks); }, ) .detach(); cx.on_action(move |_: &workspace::NewFile, cx| { let app_state = workspace::AppState::global(cx); workspace::open_new( Default::default(), app_state, cx, |workspace, window, cx| Editor::new_file(workspace, &Default::default(), window, cx), ) .detach_and_log_err(cx); }) .on_action(move |_: &workspace::NewWindow, cx| { let app_state = workspace::AppState::global(cx); workspace::open_new( Default::default(), app_state, cx, |workspace, window, cx| { cx.activate(true); Editor::new_file(workspace, &Default::default(), window, cx) }, ) .detach_and_log_err(cx); }); _ = ui_input::ERASED_EDITOR_FACTORY.set(|window, cx| { Arc::new(ErasedEditorImpl( cx.new(|cx| Editor::single_line(window, cx)), )) as Arc<dyn ErasedEditor> }); _ = multi_buffer::EXCERPT_CONTEXT_LINES.set(multibuffer_context_lines);} 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(Copy, Clone, Default, PartialEq, Eq, Debug)]pub enum SizingBehavior { /// The editor will layout itself using `size_full` and will include the vertical /// scroll margin as requested by user settings. #[default] Default, /// The editor will layout itself using `size_full`, but will not have any /// vertical overscroll. ExcludeOverscrollMargin, /// The editor will request a vertical size according to its content and will be /// layouted without a vertical scroll margin. SizeByContent,} #[derive(Clone, PartialEq, Eq, Debug)]pub enum EditorMode { SingleLine, AutoHeight { min_lines: usize, max_lines: Option<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, /// Determines the sizing behavior for this editor sizing_behavior: SizingBehavior, }, Minimap { parent: WeakEntity<Editor>, },} impl EditorMode { pub fn full() -> Self { Self::Full { scale_ui_elements_with_buffer_font_size: true, show_active_line_background: true, sizing_behavior: SizingBehavior::Default, } } #[inline] pub fn is_full(&self) -> bool { matches!(self, Self::Full { .. }) } #[inline] pub fn is_single_line(&self) -> bool { matches!(self, Self::SingleLine { .. }) } #[inline]Lines 1–500 of 12553. Load more
#![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.). //! //! 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; pub mod blink_manager; mod bracket_colorization; mod clangd_ext; pub mod code_context_menus; mod code_lens; pub mod display_map; mod document_colors; mod document_links; mod document_symbols; mod editor_settings; mod element; mod fold; mod folding_ranges; mod git; mod highlight_matching_bracket; pub mod hover_links; pub mod hover_popover; mod indent_guides; mod inlays; 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 runnables; mod rust_analyzer_ext; pub mod scroll; mod selections_collection; pub mod semantic_tokens; mod split; pub mod split_editor_view; mod bookmarks; #[cfg(test)] mod code_completion_tests; #[cfg(test)] mod edit_prediction_tests; #[cfg(test)] mod editor_block_comment_tests; #[cfg(test)] mod editor_tests; mod signature_help; #[cfg(any(test, feature = "test-support"))] pub mod test; mod clipboard; mod code_actions; mod completions; mod config; mod diagnostics; mod edit_prediction; mod input; mod markdown_actions; mod navigation; mod rewrap; mod selection; pub(crate) use actions::*; pub use clipboard::ClipboardSelection; pub use code_actions::CodeActionProvider; use collections::TypeIdHashMap; pub use completions::CompletionProvider; #[cfg(test)] pub(crate) use completions::snippet_candidate_suffixes; pub(crate) use completions::split_words; use diagnostics::{ActiveDiagnostic, GlobalDiagnosticRenderer, InlineDiagnostic}; pub use diagnostics::{DiagnosticRenderer, set_diagnostic_renderer}; pub use display_map::{ ChunkRenderer, ChunkRendererContext, DisplayPoint, FoldPlaceholder, HighlightKey, NavigationOverlayKey, SemanticTokenHighlight, }; pub use edit_prediction::make_suggestion_styles; pub(crate) use edit_prediction::{ EditDisplayMode, EditPrediction, EditPredictionPreview, EditPredictionSettings, EditPredictionState, MenuEditPredictionsPolicy, RegisteredEditPredictionDelegate, }; #[cfg(test)] pub(crate) use edit_prediction::{ EditPredictionKeybindAction, EditPredictionKeybindSurface, edit_prediction_edit_text, }; pub use edit_prediction_types::Direction; pub use edit_prediction_types::EditPredictionRequestTrigger; pub use editor_settings::{ CompletionDetailAlignment, CompletionMenuItemKind, CurrentLineHighlight, DiffViewStyle, DocumentColorsRenderMode, EditorSettings, EditorSettingsScrollbarProxy, OpenResultsIn, ScrollBeyondLastLine, ScrollbarAxes, SearchSettings, ShowMinimap, ui_scrollbar_settings_from_raw, }; pub use element::{ CursorLayout, EditorElement, HighlightedRange, HighlightedRangeLine, PointForPosition, file_status_label_color, render_breadcrumb_text, }; pub use git::blame::BlameRenderer; pub use git::{ DiffHunkDelegate, ResolvedDiffHunk, ResolvedDiffHunks, RestoreOnlyDiffHunkDelegate, RestoreOnlyUnstagedDiffHunkDelegate, UncommittedDiffHunkDelegate, render_diff_hunk_controls, set_blame_renderer, }; pub(crate) use git::{DiffHunkKey, StoredReviewComment}; use git::{DiffReviewDragState, DiffReviewOverlay, InlineBlamePopover}; pub(crate) use git::{DisplayDiffHunk, PhantomDiffReviewIndicator}; pub use hover_popover::hover_markdown_style; pub use inlays::Inlay; pub use items::MAX_TAB_TITLE_LEN; pub use linked_editing_ranges::LinkedEdits; pub use lsp::CompletionContext; pub use lsp_ext::lsp_tasks; pub use multi_buffer::{ Anchor, AnchorRangeExt, BufferOffset, ExcerptRange, MBTextSummary, MultiBuffer, MultiBufferOffset, MultiBufferOffsetUtf16, MultiBufferSnapshot, PathKey, RowInfo, ToOffset, ToPoint, }; pub use split::{DiffStyleControls, SplittableEditor, ToggleSplitDiff}; pub use split_editor_view::SplitEditorView; pub use text::Bias; use ::git::{Blame, status::FileStatus}; use aho_corasick::{AhoCorasick, AhoCorasickBuilder, BuildError}; use anyhow::{Context as _, Result, anyhow, bail}; use blink_manager::BlinkManager; use client::{Collaborator, ParticipantIndex, parse_zed_link}; use clock::ReplicaId; use code_context_menus::{ AvailableCodeAction, CodeActionContents, CodeActionsItem, CodeActionsMenu, CodeContextMenu, CompletionsMenu, ContextMenuOrigin, }; use code_lens::CodeLensState; use collections::{BTreeMap, HashMap, HashSet, VecDeque}; use convert_case::{Case, Casing}; use dap::TelemetrySpawnLocation; use display_map::*; use document_colors::LspColorData; use document_links::LspDocumentLinks; use edit_prediction_types::{ EditPredictionDelegate, EditPredictionDelegateHandle, EditPredictionDiscardReason, EditPredictionGranularity, SuggestionDisplayType, }; use editor_settings::{GoToDefinitionFallback, Minimap as MinimapSettings}; use element::{LineWithInvisibles, PositionMap, layout_line}; use futures::{ FutureExt, future::{self, Shared}, }; 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, EntityId, EntityInputHandler, EventEmitter, FocusHandle, FocusOutEvent, Focusable, FontId, FontStyle, FontWeight, Global, HighlightStyle, Hsla, IsZero, KeyContext, Modifiers, MouseButton, MouseDownEvent, MouseMoveEvent, PaintQuad, ParentElement, Pixels, PressureStage, Render, ScrollHandle, SharedString, SharedUri, Size, Stateful, Styled, Subscription, Task, TextRun, TextStyle, TextStyleRefinement, UTF16Selection, UnderlineStyle, UniformListScrollHandle, WeakEntity, WeakFocusHandle, Window, div, point, prelude::*, pulsating_between, px, relative, size, }; use hover_links::{HoverLink, HoveredLinkState, find_file}; use hover_popover::{HoverState, hide_hover}; use indent_guides::ActiveIndentGuidesState; use inlays::{InlaySplice, inlay_hints::InlayHintRefreshReason}; use itertools::{Either, Itertools}; use language::{ AutoindentMode, BlockCommentConfig, BracketMatch, BracketPair, Buffer, BufferRow, BufferSnapshot, Capability, CharClassifier, CharKind, CharScopeContext, CodeLabel, CursorShape, DiagnosticEntryRef, DiffOptions, EditPredictionsMode, EditPreview, HighlightedText, IndentKind, IndentSize, Language, LanguageAwareStyling, LanguageName, LanguageRegistry, LanguageScope, LocalFile, OffsetRangeExt, OutlineItem, Point, Selection, SelectionGoal, TextObject, TransactionId, TreeSitterOptions, WordsQuery, language_settings::{ self, AllLanguageSettings, LanguageSettings, LspInsertMode, RewrapBehavior, WordsCompletionMode, all_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 markdown::Markdown; use mouse_context_menu::MouseContextMenu; use movement::TextLayoutDetails; use multi_buffer::{ ExcerptBoundaryInfo, ExpandExcerptDirection, MultiBufferDiffHunk, MultiBufferPoint, MultiBufferRow, }; use parking_lot::Mutex; use persistence::EditorDb; use project::{ BreakpointWithPosition, CodeAction, Completion, CompletionDisplayOptions, CompletionIntent, CompletionResponse, CompletionSource, DisableAiSettings, DocumentHighlight, InlayHint, InlayId, InvalidationStrategy, Location, LocationLink, LspAction, PrepareRenameResponse, Project, ProjectItem, ProjectPath, ProjectTransaction, bookmark_store::BookmarkStore, debugger::{ breakpoint_store::{ Breakpoint, BreakpointEditAction, BreakpointSessionState, BreakpointState, BreakpointStore, BreakpointStoreEvent, }, session::{Session, SessionEvent}, }, git_store::GitStoreEvent, lsp_store::{ BufferSemanticTokens, CacheInlayHints, CompletionDocumentation, FormatTrigger, LspFormatTarget, OpenLspBufferHandle, }, project_settings::{DiagnosticSeverity, GoToDiagnosticSeverityFilter, ProjectSettings}, }; use rand::seq::SliceRandom; use regex::Regex; use rpc::{ErrorCode, ErrorExt, proto::PeerId}; use scroll::{Autoscroll, OngoingScroll, ScrollAnchor, ScrollManager, SharedScrollAnchor}; use selections_collection::{MutableSelectionsCollection, SelectionsCollection}; use serde::{Deserialize, Serialize}; use settings::{ GitGutterSetting, RelativeLineNumbers, Settings, SettingsLocation, SettingsStore, update_settings_file, }; use smallvec::{SmallVec, smallvec}; use snippet::Snippet; use std::{ any::{Any, TypeId}, borrow::Cow, cell::{OnceCell, RefCell}, cmp::{self, Ordering, Reverse}, collections::hash_map, iter::{self, Peekable}, mem, num::NonZeroU32, ops::{ControlFlow, Deref, DerefMut, Not, Range, RangeInclusive}, path::{Path, PathBuf}, rc::Rc, sync::Arc, time::{Duration, Instant}, }; use task::TaskVariables; use text::{BufferId, FromAnchor, OffsetUtf16, Rope, ToOffset as _, ToPoint as _}; use theme::{ AccentColors, ActiveTheme, GlobalTheme, PlayerColor, StatusColors, SyntaxTheme, Theme, }; use theme_settings::{ThemeSettings, observe_buffer_font_size_adjustment}; use ui::{ Avatar, ContextMenu, Disclosure, IconButtonShape, Indicator, Key, KeyBinding, Tooltip, prelude::*, scrollbars::ScrollbarAutoHide, tooltip_container, utils::WithRemSize, }; use ui_input::ErasedEditor; use util::{RangeExt, ResultExt, TryFutureExt, maybe, post_inc}; use workspace::{ CollaboratorId, Item as WorkspaceItem, ItemId, ItemNavHistory, NavigationEntry, OpenInTerminal, OpenTerminal, Pane, RestoreOnStartupBehavior, SERIALIZATION_THROTTLE_TIME, SplitDirection, TabBarSettings, Toast, ViewId, Workspace, WorkspaceId, WorkspaceSettings, item::{ItemBufferKind, ItemHandle, PreviewTabsSettings, SaveOptions}, notifications::{DetachAndPromptErr, NotificationId, NotifyResultExt, NotifyTaskExt}, searchable::SearchEvent, }; pub use zed_actions::editor::RevealInFileManager; use zed_actions::editor::{MoveDown, MoveUp}; use crate::{ code_context_menus::CompletionsMenuSource, editor_settings::MultiCursorModifier, hover_links::{find_url, find_url_from_range}, inlays::{ InlineValueCache, inlay_hints::{LspInlayHintData, inlay_hint_settings}, }, runnables::{ResolvedTasks, RunnableData, RunnableTaskStatus, RunnableTasks}, scroll::{ScrollOffset, ScrollPixelOffset}, selections_collection::resolve_selections_wrapping_blocks, semantic_tokens::SemanticTokenState, signature_help::{SignatureHelpHiddenBy, SignatureHelpState}, }; pub const FILE_HEADER_HEIGHT: u32 = 2; pub const BUFFER_HEADER_PADDING: Rems = rems(0.25); pub const MULTI_BUFFER_EXCERPT_HEADER_HEIGHT: u32 = 1; 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); pub 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 const LSP_REQUEST_DEBOUNCE_TIMEOUT: Duration = Duration::from_millis(50); pub(crate) const EDIT_PREDICTION_KEY_CONTEXT: &str = "edit_prediction"; pub(crate) const MINIMAP_FONT_SIZE: AbsoluteLength = AbsoluteLength::Pixels(px(2.)); enum ReportEditorEvent { Saved { auto_saved: bool }, EditorOpened, Closed, } impl ReportEditorEvent { pub fn event_type(&self) -> &'static str { match self { Self::Saved { .. } => "Editor Saved", Self::EditorOpened => "Editor Opened", Self::Closed => "Editor Closed", } } } pub enum ActiveDebugLine {} pub enum DebugStackFrameLine {} pub enum ConflictsOuter {} pub enum ConflictsOurs {} pub enum ConflictsTheirs {} pub enum ConflictsOursMarker {} pub enum ConflictsTheirsMarker {} pub struct HunkAddedColor; pub struct HunkRemovedColor; #[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 } } } pub fn init(cx: &mut App) { cx.set_global(GlobalBlameRenderer(Arc::new(()))); cx.set_global(breadcrumbs::RenderBreadcrumbText(render_breadcrumb_text)); 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_split); 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); workspace.register_action(Editor::view_bookmarks); }, ) .detach(); cx.on_action(move |_: &workspace::NewFile, cx| { let app_state = workspace::AppState::global(cx); workspace::open_new( Default::default(), app_state, cx, |workspace, window, cx| Editor::new_file(workspace, &Default::default(), window, cx), ) .detach_and_log_err(cx); }) .on_action(move |_: &workspace::NewWindow, cx| { let app_state = workspace::AppState::global(cx); workspace::open_new( Default::default(), app_state, cx, |workspace, window, cx| { cx.activate(true); Editor::new_file(workspace, &Default::default(), window, cx) }, ) .detach_and_log_err(cx); }); _ = ui_input::ERASED_EDITOR_FACTORY.set(|window, cx| { Arc::new(ErasedEditorImpl( cx.new(|cx| Editor::single_line(window, cx)), )) as Arc<dyn ErasedEditor> }); _ = multi_buffer::EXCERPT_CONTEXT_LINES.set(multibuffer_context_lines); } 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(Copy, Clone, Default, PartialEq, Eq, Debug)] pub enum SizingBehavior { /// The editor will layout itself using `size_full` and will include the vertical /// scroll margin as requested by user settings. #[default] Default, /// The editor will layout itself using `size_full`, but will not have any /// vertical overscroll. ExcludeOverscrollMargin, /// The editor will request a vertical size according to its content and will be /// layouted without a vertical scroll margin. SizeByContent, } #[derive(Clone, PartialEq, Eq, Debug)] pub enum EditorMode { SingleLine, AutoHeight { min_lines: usize, max_lines: Option<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, /// Determines the sizing behavior for this editor sizing_behavior: SizingBehavior, }, Minimap { parent: WeakEntity<Editor>, }, } impl EditorMode { pub fn full() -> Self { Self::Full { scale_ui_elements_with_buffer_font_size: true, show_active_line_background: true, sizing_behavior: SizingBehavior::Default, } } #[inline] pub fn is_full(&self) -> bool { matches!(self, Self::Full { .. }) } #[inline] pub fn is_single_line(&self) -> bool { matches!(self, Self::SingleLine { .. }) } #[inline]