#![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 commit_tooltip;pub mod display_map;mod editor_settings;mod editor_settings_controls;mod element;mod git;mod highlight_matching_bracket;mod hover_links;mod hover_popover;mod indent_guides;mod inlay_hint_cache;pub mod items;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 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::{anyhow, Context as _, Result};use blink_manager::BlinkManager;use buffer_diff::DiffHunkSecondaryStatus;use client::{Collaborator, ParticipantIndex};use clock::ReplicaId;use collections::{BTreeMap, HashMap, HashSet, VecDeque};use convert_case::{Case, Casing};use display_map::*;pub use display_map::{DisplayPoint, FoldPlaceholder};pub use editor_settings::{ CurrentLineHighlight, EditorSettings, ScrollBeyondLastLine, SearchSettings, ShowScrollbar,};pub use editor_settings_controls::*;use element::{AcceptEditPredictionBinding, LineWithInvisibles, PositionMap};pub use element::{ CursorLayout, EditorElement, HighlightedRange, HighlightedRangeLine, PointForPosition,};use futures::{ future::{self, Shared}, FutureExt,};use fuzzy::StringMatchCandidate; use ::git::Restore;use code_context_menus::{ AvailableCodeAction, CodeActionContents, CodeActionsItem, CodeActionsMenu, CodeContextMenu, CompletionsMenu, ContextMenuOrigin,};use git::blame::GitBlame;use gpui::{ div, impl_actions, point, prelude::*, pulsating_between, px, relative, size, Action, Animation, AnimationExt, AnyElement, App, AsyncWindowContext, AvailableSpace, Background, Bounds, ClipboardEntry, ClipboardItem, Context, DispatchPhase, Entity, EntityInputHandler, EventEmitter, FocusHandle, FocusOutEvent, Focusable, FontId, FontWeight, Global, HighlightStyle, Hsla, KeyContext, Modifiers, MouseButton, MouseDownEvent, PaintQuad, ParentElement, Pixels, Render, SharedString, Size, Styled, StyledText, Subscription, Task, TextStyle, TextStyleRefinement, UTF16Selection, UnderlineStyle, UniformListScrollHandle, WeakEntity, WeakFocusHandle, Window,};use highlight_matching_bracket::refresh_matching_bracket_highlights;use hover_popover::{hide_hover, HoverState};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::{ language_settings::{ self, all_language_settings, language_settings, InlayHintSettings, RewrapBehavior, }, point_from_lsp, text_diff_with_options, AutoindentMode, BracketPair, Buffer, Capability, CharKind, CodeLabel, CursorShape, Diagnostic, DiffOptions, DiskState, EditPredictionsMode, EditPreview, HighlightedText, IndentKind, IndentSize, Language, OffsetRangeExt, Point, Selection, SelectionGoal, TextObject, TransactionId, TreeSitterOptions,};use language::{point_to_lsp, BufferRow, CharClassifier, Runnable, RunnableRange};use linked_editing_ranges::refresh_linked_ranges;use mouse_context_menu::MouseContextMenu;use persistence::DB;pub use proposed_changes_editor::{ ProposedChangeLocation, ProposedChangesEditor, ProposedChangesEditorToolbar,};use std::iter::Peekable;use task::{ResolvedTask, TaskTemplate, TaskVariables}; use hover_links::{find_file, HoverLink, HoveredLinkState, InlayHighlight};pub use lsp::CompletionContext;use lsp::{ CompletionItemKind, CompletionTriggerKind, DiagnosticSeverity, InsertTextFormat, LanguageServerId, LanguageServerName,}; use language::BufferSnapshot;use movement::TextLayoutDetails;pub use multi_buffer::{ Anchor, AnchorRangeExt, ExcerptId, ExcerptRange, MultiBuffer, MultiBufferSnapshot, RowInfo, ToOffset, ToPoint,};use multi_buffer::{ ExcerptInfo, ExpandExcerptDirection, MultiBufferDiffHunk, MultiBufferPoint, MultiBufferRow, ToOffsetUtf16,};use project::{ lsp_store::{CompletionDocumentation, FormatTrigger, LspFormatTarget, OpenLspBufferHandle}, project_settings::{GitGutterSetting, ProjectSettings}, CodeAction, Completion, CompletionIntent, DocumentHighlight, InlayHint, Location, LocationLink, PrepareRenameResponse, Project, ProjectItem, ProjectTransaction, TaskSourceKind,};use rand::prelude::*;use rpc::{proto::*, ErrorExt};use scroll::{Autoscroll, OngoingScroll, ScrollAnchor, ScrollManager, ScrollbarAutoHide};use selections_collection::{ resolve_selections, MutableSelectionsCollection, SelectionsCollection,};use serde::{Deserialize, Serialize};use settings::{update_settings_file, Settings, SettingsLocation, SettingsStore};use smallvec::SmallVec;use snippet::Snippet;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, sync::Arc, time::{Duration, Instant},};pub use sum_tree::Bias;use sum_tree::TreeMap;use text::{BufferId, OffsetUtf16, Rope};use theme::{ observe_buffer_font_size_adjustment, ActiveTheme, PlayerColor, StatusColors, SyntaxTheme, ThemeColors, ThemeSettings,};use ui::{ h_flex, prelude::*, ButtonSize, ButtonStyle, Disclosure, IconButton, IconName, IconSize, Key, Tooltip,};use util::{defer, maybe, post_inc, RangeExt, ResultExt, TryFutureExt};use workspace::{ item::{ItemHandle, PreviewTabsSettings}, ItemId, RestoreOnStartupBehavior,};use workspace::{ notifications::{DetachAndPromptErr, NotificationId, NotifyTaskExt}, WorkspaceSettings,};use workspace::{ searchable::SearchEvent, ItemNavHistory, SplitDirection, ViewId, Workspace, WorkspaceId,};use workspace::{Item as WorkspaceItem, OpenInTerminal, OpenTerminal, TabBarSettings, Toast}; 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 MULTI_BUFFER_EXCERPT_FOOTER_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); 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"; const COLUMNAR_SELECTION_MODIFIERS: Modifiers = Modifiers { alt: true, shift: true, control: false, platform: false, function: false,}; #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]pub enum InlayId { InlineCompletion(usize), Hint(usize),} impl InlayId { fn id(&self) -> usize { match self { Self::InlineCompletion(id) => *id, Self::Hint(id) => *id, } }} enum DocumentHighlightRead {}enum DocumentHighlightWrite {}enum InputComposition {}enum SelectedTextHighlight {} #[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_settings(cx: &mut App) { EditorSettings::register(cx);} pub fn init(cx: &mut App) { init_settings(cx); 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 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,} #[derive(Copy, Clone, Debug)]pub enum SoftWrap { /// Prefer not to wrap at all. /// /// Note: this is currently internal, as actually limited by [`crate::MAX_LINE_LEN`] until it wraps. /// The mode is used inside git diff hunks, where it's seems currently more useful to not wrap as much as possible. GitDiff, /// Prefer a single line generally, unless an overly long line is encountered. None, /// Soft wrap lines that exceed the editor width. EditorWidth, /// Soft wrap lines at the preferred line length. Column(u32), /// Soft wrap line at the preferred line length or the editor width (whichever is smaller). Bounded(u32),} #[derive(Clone)]pub struct EditorStyle { pub background: Hsla, pub local_player: PlayerColor, pub text: TextStyle, pub scrollbar_width: Pixels, pub syntax: Arc<SyntaxTheme>, pub status: StatusColors, pub inlay_hints_style: HighlightStyle, pub inline_completion_styles: InlineCompletionStyles, pub unnecessary_code_fade: f32,} impl Default for EditorStyle { fn default() -> Self { Self { background: Hsla::default(), local_player: PlayerColor::default(), text: TextStyle::default(), scrollbar_width: Pixels::default(), syntax: Default::default(), // HACK: Status colors don't have a real default. // We should look into removing the status colors from the editor // style and retrieve them directly from the theme. status: StatusColors::dark(), inlay_hints_style: HighlightStyle::default(), inline_completion_styles: InlineCompletionStyles { insertion: HighlightStyle::default(), whitespace: HighlightStyle::default(), }, unnecessary_code_fade: Default::default(), } }} pub fn make_inlay_hints_style(cx: &mut App) -> HighlightStyle { let show_background = language_settings::language_settings(None, None, cx) .inlay_hints .show_background; HighlightStyle { color: Some(cx.theme().status().hint), background_color: show_background.then(|| cx.theme().status().hint_background), ..HighlightStyle::default() }} pub fn make_suggestion_styles(cx: &mut App) -> InlineCompletionStyles { InlineCompletionStyles { insertion: HighlightStyle { color: Some(cx.theme().status().predictive), ..HighlightStyle::default() }, whitespace: HighlightStyle { background_color: Some(cx.theme().status().created_background), ..HighlightStyle::default() }, }} type CompletionId = usize; pub(crate) enum EditDisplayMode { TabAccept, DiffPopover, Inline,} enum InlineCompletion { Edit { edits: Vec<(Range<Anchor>, String)>, edit_preview: Option<EditPreview>, display_mode: EditDisplayMode, snapshot: BufferSnapshot, }, Move { target: Anchor, snapshot: BufferSnapshot, },} struct InlineCompletionState { inlay_ids: Vec<InlayId>, completion: InlineCompletion, completion_id: Option<SharedString>, invalidation_range: Range<Anchor>,} enum EditPredictionSettings { Disabled, Enabled { show_in_menu: bool, preview_requires_modifier: bool, },} enum InlineCompletionHighlight {} pub enum MenuInlineCompletionsPolicy { Never, ByProvider,} pub enum EditPredictionPreview { /// Modifier is not pressed Inactive, /// Modifier pressed Active { previous_scroll_position: Option<ScrollAnchor>, },} #[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord, Debug, Default)]struct EditorActionId(usize); impl EditorActionId { pub fn post_inc(&mut self) -> Self { let answer = self.0; *self = Self(answer + 1); Self(answer) }} // type GetFieldEditorTheme = dyn Fn(&theme::Theme) -> theme::FieldEditor;// type OverrideTextStyle = dyn Fn(&EditorStyle) -> Option<HighlightStyle>; type BackgroundHighlight = (fn(&ThemeColors) -> Hsla, Arc<[Range<Anchor>]>);type GutterHighlight = (fn(&App) -> Hsla, Arc<[Range<Anchor>]>); #[derive(Default)]Lines 1–500 of 17124. 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.). //! * [`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 commit_tooltip; pub mod display_map; mod editor_settings; mod editor_settings_controls; mod element; mod git; mod highlight_matching_bracket; mod hover_links; mod hover_popover; mod indent_guides; mod inlay_hint_cache; pub mod items; 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 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::{anyhow, Context as _, Result}; use blink_manager::BlinkManager; use buffer_diff::DiffHunkSecondaryStatus; use client::{Collaborator, ParticipantIndex}; use clock::ReplicaId; use collections::{BTreeMap, HashMap, HashSet, VecDeque}; use convert_case::{Case, Casing}; use display_map::*; pub use display_map::{DisplayPoint, FoldPlaceholder}; pub use editor_settings::{ CurrentLineHighlight, EditorSettings, ScrollBeyondLastLine, SearchSettings, ShowScrollbar, }; pub use editor_settings_controls::*; use element::{AcceptEditPredictionBinding, LineWithInvisibles, PositionMap}; pub use element::{ CursorLayout, EditorElement, HighlightedRange, HighlightedRangeLine, PointForPosition, }; use futures::{ future::{self, Shared}, FutureExt, }; use fuzzy::StringMatchCandidate; use ::git::Restore; use code_context_menus::{ AvailableCodeAction, CodeActionContents, CodeActionsItem, CodeActionsMenu, CodeContextMenu, CompletionsMenu, ContextMenuOrigin, }; use git::blame::GitBlame; use gpui::{ div, impl_actions, point, prelude::*, pulsating_between, px, relative, size, Action, Animation, AnimationExt, AnyElement, App, AsyncWindowContext, AvailableSpace, Background, Bounds, ClipboardEntry, ClipboardItem, Context, DispatchPhase, Entity, EntityInputHandler, EventEmitter, FocusHandle, FocusOutEvent, Focusable, FontId, FontWeight, Global, HighlightStyle, Hsla, KeyContext, Modifiers, MouseButton, MouseDownEvent, PaintQuad, ParentElement, Pixels, Render, SharedString, Size, Styled, StyledText, Subscription, Task, TextStyle, TextStyleRefinement, UTF16Selection, UnderlineStyle, UniformListScrollHandle, WeakEntity, WeakFocusHandle, Window, }; use highlight_matching_bracket::refresh_matching_bracket_highlights; use hover_popover::{hide_hover, HoverState}; 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::{ language_settings::{ self, all_language_settings, language_settings, InlayHintSettings, RewrapBehavior, }, point_from_lsp, text_diff_with_options, AutoindentMode, BracketPair, Buffer, Capability, CharKind, CodeLabel, CursorShape, Diagnostic, DiffOptions, DiskState, EditPredictionsMode, EditPreview, HighlightedText, IndentKind, IndentSize, Language, OffsetRangeExt, Point, Selection, SelectionGoal, TextObject, TransactionId, TreeSitterOptions, }; use language::{point_to_lsp, BufferRow, CharClassifier, Runnable, RunnableRange}; use linked_editing_ranges::refresh_linked_ranges; use mouse_context_menu::MouseContextMenu; use persistence::DB; pub use proposed_changes_editor::{ ProposedChangeLocation, ProposedChangesEditor, ProposedChangesEditorToolbar, }; use std::iter::Peekable; use task::{ResolvedTask, TaskTemplate, TaskVariables}; use hover_links::{find_file, HoverLink, HoveredLinkState, InlayHighlight}; pub use lsp::CompletionContext; use lsp::{ CompletionItemKind, CompletionTriggerKind, DiagnosticSeverity, InsertTextFormat, LanguageServerId, LanguageServerName, }; use language::BufferSnapshot; use movement::TextLayoutDetails; pub use multi_buffer::{ Anchor, AnchorRangeExt, ExcerptId, ExcerptRange, MultiBuffer, MultiBufferSnapshot, RowInfo, ToOffset, ToPoint, }; use multi_buffer::{ ExcerptInfo, ExpandExcerptDirection, MultiBufferDiffHunk, MultiBufferPoint, MultiBufferRow, ToOffsetUtf16, }; use project::{ lsp_store::{CompletionDocumentation, FormatTrigger, LspFormatTarget, OpenLspBufferHandle}, project_settings::{GitGutterSetting, ProjectSettings}, CodeAction, Completion, CompletionIntent, DocumentHighlight, InlayHint, Location, LocationLink, PrepareRenameResponse, Project, ProjectItem, ProjectTransaction, TaskSourceKind, }; use rand::prelude::*; use rpc::{proto::*, ErrorExt}; use scroll::{Autoscroll, OngoingScroll, ScrollAnchor, ScrollManager, ScrollbarAutoHide}; use selections_collection::{ resolve_selections, MutableSelectionsCollection, SelectionsCollection, }; use serde::{Deserialize, Serialize}; use settings::{update_settings_file, Settings, SettingsLocation, SettingsStore}; use smallvec::SmallVec; use snippet::Snippet; 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, sync::Arc, time::{Duration, Instant}, }; pub use sum_tree::Bias; use sum_tree::TreeMap; use text::{BufferId, OffsetUtf16, Rope}; use theme::{ observe_buffer_font_size_adjustment, ActiveTheme, PlayerColor, StatusColors, SyntaxTheme, ThemeColors, ThemeSettings, }; use ui::{ h_flex, prelude::*, ButtonSize, ButtonStyle, Disclosure, IconButton, IconName, IconSize, Key, Tooltip, }; use util::{defer, maybe, post_inc, RangeExt, ResultExt, TryFutureExt}; use workspace::{ item::{ItemHandle, PreviewTabsSettings}, ItemId, RestoreOnStartupBehavior, }; use workspace::{ notifications::{DetachAndPromptErr, NotificationId, NotifyTaskExt}, WorkspaceSettings, }; use workspace::{ searchable::SearchEvent, ItemNavHistory, SplitDirection, ViewId, Workspace, WorkspaceId, }; use workspace::{Item as WorkspaceItem, OpenInTerminal, OpenTerminal, TabBarSettings, Toast}; 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 MULTI_BUFFER_EXCERPT_FOOTER_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); 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"; const COLUMNAR_SELECTION_MODIFIERS: Modifiers = Modifiers { alt: true, shift: true, control: false, platform: false, function: false, }; #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum InlayId { InlineCompletion(usize), Hint(usize), } impl InlayId { fn id(&self) -> usize { match self { Self::InlineCompletion(id) => *id, Self::Hint(id) => *id, } } } enum DocumentHighlightRead {} enum DocumentHighlightWrite {} enum InputComposition {} enum SelectedTextHighlight {} #[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_settings(cx: &mut App) { EditorSettings::register(cx); } pub fn init(cx: &mut App) { init_settings(cx); 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 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, } #[derive(Copy, Clone, Debug)] pub enum SoftWrap { /// Prefer not to wrap at all. /// /// Note: this is currently internal, as actually limited by [`crate::MAX_LINE_LEN`] until it wraps. /// The mode is used inside git diff hunks, where it's seems currently more useful to not wrap as much as possible. GitDiff, /// Prefer a single line generally, unless an overly long line is encountered. None, /// Soft wrap lines that exceed the editor width. EditorWidth, /// Soft wrap lines at the preferred line length. Column(u32), /// Soft wrap line at the preferred line length or the editor width (whichever is smaller). Bounded(u32), } #[derive(Clone)] pub struct EditorStyle { pub background: Hsla, pub local_player: PlayerColor, pub text: TextStyle, pub scrollbar_width: Pixels, pub syntax: Arc<SyntaxTheme>, pub status: StatusColors, pub inlay_hints_style: HighlightStyle, pub inline_completion_styles: InlineCompletionStyles, pub unnecessary_code_fade: f32, } impl Default for EditorStyle { fn default() -> Self { Self { background: Hsla::default(), local_player: PlayerColor::default(), text: TextStyle::default(), scrollbar_width: Pixels::default(), syntax: Default::default(), // HACK: Status colors don't have a real default. // We should look into removing the status colors from the editor // style and retrieve them directly from the theme. status: StatusColors::dark(), inlay_hints_style: HighlightStyle::default(), inline_completion_styles: InlineCompletionStyles { insertion: HighlightStyle::default(), whitespace: HighlightStyle::default(), }, unnecessary_code_fade: Default::default(), } } } pub fn make_inlay_hints_style(cx: &mut App) -> HighlightStyle { let show_background = language_settings::language_settings(None, None, cx) .inlay_hints .show_background; HighlightStyle { color: Some(cx.theme().status().hint), background_color: show_background.then(|| cx.theme().status().hint_background), ..HighlightStyle::default() } } pub fn make_suggestion_styles(cx: &mut App) -> InlineCompletionStyles { InlineCompletionStyles { insertion: HighlightStyle { color: Some(cx.theme().status().predictive), ..HighlightStyle::default() }, whitespace: HighlightStyle { background_color: Some(cx.theme().status().created_background), ..HighlightStyle::default() }, } } type CompletionId = usize; pub(crate) enum EditDisplayMode { TabAccept, DiffPopover, Inline, } enum InlineCompletion { Edit { edits: Vec<(Range<Anchor>, String)>, edit_preview: Option<EditPreview>, display_mode: EditDisplayMode, snapshot: BufferSnapshot, }, Move { target: Anchor, snapshot: BufferSnapshot, }, } struct InlineCompletionState { inlay_ids: Vec<InlayId>, completion: InlineCompletion, completion_id: Option<SharedString>, invalidation_range: Range<Anchor>, } enum EditPredictionSettings { Disabled, Enabled { show_in_menu: bool, preview_requires_modifier: bool, }, } enum InlineCompletionHighlight {} pub enum MenuInlineCompletionsPolicy { Never, ByProvider, } pub enum EditPredictionPreview { /// Modifier is not pressed Inactive, /// Modifier pressed Active { previous_scroll_position: Option<ScrollAnchor>, }, } #[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord, Debug, Default)] struct EditorActionId(usize); impl EditorActionId { pub fn post_inc(&mut self) -> Self { let answer = self.0; *self = Self(answer + 1); Self(answer) } } // type GetFieldEditorTheme = dyn Fn(&theme::Theme) -> theme::FieldEditor; // type OverrideTextStyle = dyn Fn(&EditorStyle) -> Option<HighlightStyle>; type BackgroundHighlight = (fn(&ThemeColors) -> Hsla, Arc<[Range<Anchor>]>); type GutterHighlight = (fn(&App) -> Hsla, Arc<[Range<Anchor>]>); #[derive(Default)]