pub use crate::{ diagnostic_set::DiagnosticSet, highlight_map::{HighlightId, HighlightMap}, proto, Grammar, Language, LanguageRegistry,};use crate::{ diagnostic_set::{DiagnosticEntry, DiagnosticGroup}, language_settings::{language_settings, LanguageSettings}, outline::OutlineItem, syntax_map::{ SyntaxLayer, SyntaxMap, SyntaxMapCapture, SyntaxMapCaptures, SyntaxMapMatch, SyntaxMapMatches, SyntaxSnapshot, ToTreeSitterPoint, }, task_context::RunnableRange, text_diff::text_diff, LanguageScope, Outline, OutlineConfig, RunnableCapture, RunnableTag, TextObject, TreeSitterOptions,};use anyhow::{anyhow, Context as _, Result};use async_watch as watch;use clock::Lamport;pub use clock::ReplicaId;use collections::HashMap;use fs::MTime;use futures::channel::oneshot;use gpui::{ AnyElement, App, AppContext as _, Context, Entity, EventEmitter, HighlightStyle, Pixels, SharedString, StyledText, Task, TaskLabel, TextStyle, Window,};use lsp::{LanguageServerId, NumberOrString};use parking_lot::Mutex;use schemars::JsonSchema;use serde::{Deserialize, Serialize};use serde_json::Value;use settings::WorktreeId;use smallvec::SmallVec;use smol::future::yield_now;use std::{ any::Any, borrow::Cow, cell::Cell, cmp::{self, Ordering, Reverse}, collections::{BTreeMap, BTreeSet}, ffi::OsStr, fmt, future::Future, iter::{self, Iterator, Peekable}, mem, num::NonZeroU32, ops::{Deref, DerefMut, Range}, path::{Path, PathBuf}, str, sync::{Arc, LazyLock}, time::{Duration, Instant}, vec,};use sum_tree::TreeMap;use text::operation_queue::OperationQueue;use text::*;pub use text::{ Anchor, Bias, Buffer as TextBuffer, BufferId, BufferSnapshot as TextBufferSnapshot, Edit, OffsetRangeExt, OffsetUtf16, Patch, Point, PointUtf16, Rope, Selection, SelectionGoal, Subscription, TextDimension, TextSummary, ToOffset, ToOffsetUtf16, ToPoint, ToPointUtf16, Transaction, TransactionId, Unclipped,};use theme::{ActiveTheme as _, SyntaxTheme};#[cfg(any(test, feature = "test-support"))]use util::RandomCharIter;use util::{debug_panic, maybe, RangeExt}; #[cfg(any(test, feature = "test-support"))]pub use {tree_sitter_rust, tree_sitter_typescript}; pub use lsp::DiagnosticSeverity; /// A label for the background task spawned by the buffer to compute/// a diff against the contents of its file.pub static BUFFER_DIFF_TASK: LazyLock<TaskLabel> = LazyLock::new(TaskLabel::new); /// Indicate whether a [`Buffer`] has permissions to edit.#[derive(PartialEq, Clone, Copy, Debug)]pub enum Capability { /// The buffer is a mutable replica. ReadWrite, /// The buffer is a read-only replica. ReadOnly,} pub type BufferRow = u32; /// An in-memory representation of a source code file, including its text,/// syntax trees, git status, and diagnostics.pub struct Buffer { text: TextBuffer, branch_state: Option<BufferBranchState>, /// Filesystem state, `None` when there is no path. file: Option<Arc<dyn File>>, /// The mtime of the file when this buffer was last loaded from /// or saved to disk. saved_mtime: Option<MTime>, /// The version vector when this buffer was last loaded from /// or saved to disk. saved_version: clock::Global, preview_version: clock::Global, transaction_depth: usize, was_dirty_before_starting_transaction: Option<bool>, reload_task: Option<Task<Result<()>>>, language: Option<Arc<Language>>, autoindent_requests: Vec<Arc<AutoindentRequest>>, pending_autoindent: Option<Task<()>>, sync_parse_timeout: Duration, syntax_map: Mutex<SyntaxMap>, reparse: Option<Task<()>>, parse_status: (watch::Sender<ParseStatus>, watch::Receiver<ParseStatus>), non_text_state_update_count: usize, diagnostics: SmallVec<[(LanguageServerId, DiagnosticSet); 2]>, remote_selections: TreeMap<ReplicaId, SelectionSet>, diagnostics_timestamp: clock::Lamport, completion_triggers: BTreeSet<String>, completion_triggers_per_language_server: HashMap<LanguageServerId, BTreeSet<String>>, completion_triggers_timestamp: clock::Lamport, deferred_ops: OperationQueue<Operation>, capability: Capability, has_conflict: bool, /// Memoize calls to has_changes_since(saved_version). /// The contents of a cell are (self.version, has_changes) at the time of a last call. has_unsaved_edits: Cell<(clock::Global, bool)>, _subscriptions: Vec<gpui::Subscription>,} #[derive(Copy, Clone, Debug, PartialEq, Eq)]pub enum ParseStatus { Idle, Parsing,} struct BufferBranchState { base_buffer: Entity<Buffer>, merged_operations: Vec<Lamport>,} /// An immutable, cheaply cloneable representation of a fixed/// state of a buffer.pub struct BufferSnapshot { pub text: text::BufferSnapshot, pub(crate) syntax: SyntaxSnapshot, file: Option<Arc<dyn File>>, diagnostics: SmallVec<[(LanguageServerId, DiagnosticSet); 2]>, remote_selections: TreeMap<ReplicaId, SelectionSet>, language: Option<Arc<Language>>, non_text_state_update_count: usize,} /// The kind and amount of indentation in a particular line. For now,/// assumes that indentation is all the same character.#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Default)]pub struct IndentSize { /// The number of bytes that comprise the indentation. pub len: u32, /// The kind of whitespace used for indentation. pub kind: IndentKind,} /// A whitespace character that's used for indentation.#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Default)]pub enum IndentKind { /// An ASCII space character. #[default] Space, /// An ASCII tab character. Tab,} /// The shape of a selection cursor.#[derive(Copy, Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]#[serde(rename_all = "snake_case")]pub enum CursorShape { /// A vertical bar #[default] Bar, /// A block that surrounds the following character Block, /// An underline that runs along the following character Underline, /// A box drawn around the following character Hollow,} #[derive(Clone, Debug)]struct SelectionSet { line_mode: bool, cursor_shape: CursorShape, selections: Arc<[Selection<Anchor>]>, lamport_timestamp: clock::Lamport,} /// A diagnostic associated with a certain range of a buffer.#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]pub struct Diagnostic { /// The name of the service that produced this diagnostic. pub source: Option<String>, /// A machine-readable code that identifies this diagnostic. pub code: Option<NumberOrString>, /// Whether this diagnostic is a hint, warning, or error. pub severity: DiagnosticSeverity, /// The human-readable message associated with this diagnostic. pub message: String, /// An id that identifies the group to which this diagnostic belongs. /// /// When a language server produces a diagnostic with /// one or more associated diagnostics, those diagnostics are all /// assigned a single group ID. pub group_id: usize, /// Whether this diagnostic is the primary diagnostic for its group. /// /// In a given group, the primary diagnostic is the top-level diagnostic /// returned by the language server. The non-primary diagnostics are the /// associated diagnostics. pub is_primary: bool, /// Whether this diagnostic is considered to originate from an analysis of /// files on disk, as opposed to any unsaved buffer contents. This is a /// property of a given diagnostic source, and is configured for a given /// language server via the [`LspAdapter::disk_based_diagnostic_sources`](crate::LspAdapter::disk_based_diagnostic_sources) method /// for the language server. pub is_disk_based: bool, /// Whether this diagnostic marks unnecessary code. pub is_unnecessary: bool, /// Data from language server that produced this diagnostic. Passed back to the LS when we request code actions for this diagnostic. pub data: Option<Value>,} /// An operation used to synchronize this buffer with its other replicas.#[derive(Clone, Debug, PartialEq)]pub enum Operation { /// A text operation. Buffer(text::Operation), /// An update to the buffer's diagnostics. UpdateDiagnostics { /// The id of the language server that produced the new diagnostics. server_id: LanguageServerId, /// The diagnostics. diagnostics: Arc<[DiagnosticEntry<Anchor>]>, /// The buffer's lamport timestamp. lamport_timestamp: clock::Lamport, }, /// An update to the most recent selections in this buffer. UpdateSelections { /// The selections. selections: Arc<[Selection<Anchor>]>, /// The buffer's lamport timestamp. lamport_timestamp: clock::Lamport, /// Whether the selections are in 'line mode'. line_mode: bool, /// The [`CursorShape`] associated with these selections. cursor_shape: CursorShape, }, /// An update to the characters that should trigger autocompletion /// for this buffer. UpdateCompletionTriggers { /// The characters that trigger autocompletion. triggers: Vec<String>, /// The buffer's lamport timestamp. lamport_timestamp: clock::Lamport, /// The language server ID. server_id: LanguageServerId, },} /// An event that occurs in a buffer.#[derive(Clone, Debug, PartialEq)]pub enum BufferEvent { /// The buffer was changed in a way that must be /// propagated to its other replicas. Operation { operation: Operation, is_local: bool, }, /// The buffer was edited. Edited, /// The buffer's `dirty` bit changed. DirtyChanged, /// The buffer was saved. Saved, /// The buffer's file was changed on disk. FileHandleChanged, /// The buffer was reloaded. Reloaded, /// The buffer is in need of a reload ReloadNeeded, /// The buffer's language was changed. LanguageChanged, /// The buffer's syntax trees were updated. Reparsed, /// The buffer's diagnostics were updated. DiagnosticsUpdated, /// The buffer gained or lost editing capabilities. CapabilityChanged, /// The buffer was explicitly requested to close. Closed, /// The buffer was discarded when closing. Discarded,} /// The file associated with a buffer.pub trait File: Send + Sync { /// Returns the [`LocalFile`] associated with this file, if the /// file is local. fn as_local(&self) -> Option<&dyn LocalFile>; /// Returns whether this file is local. fn is_local(&self) -> bool { self.as_local().is_some() } /// Returns whether the file is new, exists in storage, or has been deleted. Includes metadata /// only available in some states, such as modification time. fn disk_state(&self) -> DiskState; /// Returns the path of this file relative to the worktree's root directory. fn path(&self) -> &Arc<Path>; /// Returns the path of this file relative to the worktree's parent directory (this means it /// includes the name of the worktree's root folder). fn full_path(&self, cx: &App) -> PathBuf; /// Returns the last component of this handle's absolute path. If this handle refers to the root /// of its worktree, then this method will return the name of the worktree itself. fn file_name<'a>(&'a self, cx: &'a App) -> &'a OsStr; /// Returns the id of the worktree to which this file belongs. /// /// This is needed for looking up project-specific settings. fn worktree_id(&self, cx: &App) -> WorktreeId; /// Converts this file into an [`Any`] trait object. fn as_any(&self) -> &dyn Any; /// Converts this file into a protobuf message. fn to_proto(&self, cx: &App) -> rpc::proto::File; /// Return whether Zed considers this to be a private file. fn is_private(&self) -> bool;} /// The file's storage status - whether it's stored (`Present`), and if so when it was last/// modified. In the case where the file is not stored, it can be either `New` or `Deleted`. In the/// UI these two states are distinguished. For example, the buffer tab does not display a deletion/// indicator for new files.#[derive(Copy, Clone, Debug, PartialEq)]pub enum DiskState { /// File created in Zed that has not been saved. New, /// File present on the filesystem. Present { mtime: MTime }, /// Deleted file that was previously present. Deleted,} impl DiskState { /// Returns the file's last known modification time on disk. pub fn mtime(self) -> Option<MTime> { match self { DiskState::New => None, DiskState::Present { mtime } => Some(mtime), DiskState::Deleted => None, } } pub fn exists(&self) -> bool { match self { DiskState::New => false, DiskState::Present { .. } => true, DiskState::Deleted => false, } }} /// The file associated with a buffer, in the case where the file is on the local disk.pub trait LocalFile: File { /// Returns the absolute path of this file fn abs_path(&self, cx: &App) -> PathBuf; /// Loads the file contents from disk and returns them as a UTF-8 encoded string. fn load(&self, cx: &App) -> Task<Result<String>>; /// Loads the file's contents from disk. fn load_bytes(&self, cx: &App) -> Task<Result<Vec<u8>>>;} /// The auto-indent behavior associated with an editing operation./// For some editing operations, each affected line of text has its/// indentation recomputed. For other operations, the entire block/// of edited text is adjusted uniformly.#[derive(Clone, Debug)]pub enum AutoindentMode { /// Indent each line of inserted text. EachLine, /// Apply the same indentation adjustment to all of the lines /// in a given insertion. Block { /// The original start column of each insertion, if it was /// copied from elsewhere. /// /// Knowing this start column makes it possible to preserve the /// relative indentation of every line in the insertion from /// when it was copied. /// /// If the start column is `a`, and the first line of insertion /// is then auto-indented to column `b`, then every other line of /// the insertion will be auto-indented to column `b - a` original_start_columns: Vec<u32>, },} #[derive(Clone)]struct AutoindentRequest { before_edit: BufferSnapshot, entries: Vec<AutoindentRequestEntry>, is_block_mode: bool, ignore_empty_lines: bool,} #[derive(Debug, Clone)]struct AutoindentRequestEntry { /// A range of the buffer whose indentation should be adjusted. range: Range<Anchor>, /// Whether or not these lines should be considered brand new, for the /// purpose of auto-indent. When text is not new, its indentation will /// only be adjusted if the suggested indentation level has *changed* /// since the edit was made. first_line_is_new: bool, indent_size: IndentSize, original_indent_column: Option<u32>,} #[derive(Debug)]struct IndentSuggestion { basis_row: u32, delta: Ordering, within_error: bool,} struct BufferChunkHighlights<'a> { captures: SyntaxMapCaptures<'a>, next_capture: Option<SyntaxMapCapture<'a>>, stack: Vec<(usize, HighlightId)>, highlight_maps: Vec<HighlightMap>,} /// An iterator that yields chunks of a buffer's text, along with their/// syntax highlights and diagnostic status.pub struct BufferChunks<'a> { buffer_snapshot: Option<&'a BufferSnapshot>, range: Range<usize>, chunks: text::Chunks<'a>, diagnostic_endpoints: Option<Peekable<vec::IntoIter<DiagnosticEndpoint>>>, error_depth: usize, warning_depth: usize, information_depth: usize, hint_depth: usize, unnecessary_depth: usize, highlights: Option<BufferChunkHighlights<'a>>,} /// A chunk of a buffer's text, along with its syntax highlight and/// diagnostic status.#[derive(Clone, Debug, Default)]pub struct Chunk<'a> { /// The text of the chunk. pub text: &'a str, /// The syntax highlighting style of the chunk. pub syntax_highlight_id: Option<HighlightId>, /// The highlight style that has been applied to this chunk in /// the editor. pub highlight_style: Option<HighlightStyle>, /// The severity of diagnostic associated with this chunk, if any. pub diagnostic_severity: Option<DiagnosticSeverity>, /// Whether this chunk of text is marked as unnecessary. pub is_unnecessary: bool, /// Whether this chunk of text was originally a tab character. pub is_tab: bool, /// An optional recipe for how the chunk should be presented. pub renderer: Option<ChunkRenderer>,} /// A recipe for how the chunk should be presented.#[derive(Clone)]pub struct ChunkRenderer { /// creates a custom element to represent this chunk. pub render: Arc<dyn Send + Sync + Fn(&mut ChunkRendererContext) -> AnyElement>, /// If true, the element is constrained to the shaped width of the text. pub constrain_width: bool,} pub struct ChunkRendererContext<'a, 'b> { pub window: &'a mut Window, pub context: &'b mut App,Lines 1–500 of 4677. Load more
pub use crate::{ diagnostic_set::DiagnosticSet, highlight_map::{HighlightId, HighlightMap}, proto, Grammar, Language, LanguageRegistry, }; use crate::{ diagnostic_set::{DiagnosticEntry, DiagnosticGroup}, language_settings::{language_settings, LanguageSettings}, outline::OutlineItem, syntax_map::{ SyntaxLayer, SyntaxMap, SyntaxMapCapture, SyntaxMapCaptures, SyntaxMapMatch, SyntaxMapMatches, SyntaxSnapshot, ToTreeSitterPoint, }, task_context::RunnableRange, text_diff::text_diff, LanguageScope, Outline, OutlineConfig, RunnableCapture, RunnableTag, TextObject, TreeSitterOptions, }; use anyhow::{anyhow, Context as _, Result}; use async_watch as watch; use clock::Lamport; pub use clock::ReplicaId; use collections::HashMap; use fs::MTime; use futures::channel::oneshot; use gpui::{ AnyElement, App, AppContext as _, Context, Entity, EventEmitter, HighlightStyle, Pixels, SharedString, StyledText, Task, TaskLabel, TextStyle, Window, }; use lsp::{LanguageServerId, NumberOrString}; use parking_lot::Mutex; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use serde_json::Value; use settings::WorktreeId; use smallvec::SmallVec; use smol::future::yield_now; use std::{ any::Any, borrow::Cow, cell::Cell, cmp::{self, Ordering, Reverse}, collections::{BTreeMap, BTreeSet}, ffi::OsStr, fmt, future::Future, iter::{self, Iterator, Peekable}, mem, num::NonZeroU32, ops::{Deref, DerefMut, Range}, path::{Path, PathBuf}, str, sync::{Arc, LazyLock}, time::{Duration, Instant}, vec, }; use sum_tree::TreeMap; use text::operation_queue::OperationQueue; use text::*; pub use text::{ Anchor, Bias, Buffer as TextBuffer, BufferId, BufferSnapshot as TextBufferSnapshot, Edit, OffsetRangeExt, OffsetUtf16, Patch, Point, PointUtf16, Rope, Selection, SelectionGoal, Subscription, TextDimension, TextSummary, ToOffset, ToOffsetUtf16, ToPoint, ToPointUtf16, Transaction, TransactionId, Unclipped, }; use theme::{ActiveTheme as _, SyntaxTheme}; #[cfg(any(test, feature = "test-support"))] use util::RandomCharIter; use util::{debug_panic, maybe, RangeExt}; #[cfg(any(test, feature = "test-support"))] pub use {tree_sitter_rust, tree_sitter_typescript}; pub use lsp::DiagnosticSeverity; /// A label for the background task spawned by the buffer to compute /// a diff against the contents of its file. pub static BUFFER_DIFF_TASK: LazyLock<TaskLabel> = LazyLock::new(TaskLabel::new); /// Indicate whether a [`Buffer`] has permissions to edit. #[derive(PartialEq, Clone, Copy, Debug)] pub enum Capability { /// The buffer is a mutable replica. ReadWrite, /// The buffer is a read-only replica. ReadOnly, } pub type BufferRow = u32; /// An in-memory representation of a source code file, including its text, /// syntax trees, git status, and diagnostics. pub struct Buffer { text: TextBuffer, branch_state: Option<BufferBranchState>, /// Filesystem state, `None` when there is no path. file: Option<Arc<dyn File>>, /// The mtime of the file when this buffer was last loaded from /// or saved to disk. saved_mtime: Option<MTime>, /// The version vector when this buffer was last loaded from /// or saved to disk. saved_version: clock::Global, preview_version: clock::Global, transaction_depth: usize, was_dirty_before_starting_transaction: Option<bool>, reload_task: Option<Task<Result<()>>>, language: Option<Arc<Language>>, autoindent_requests: Vec<Arc<AutoindentRequest>>, pending_autoindent: Option<Task<()>>, sync_parse_timeout: Duration, syntax_map: Mutex<SyntaxMap>, reparse: Option<Task<()>>, parse_status: (watch::Sender<ParseStatus>, watch::Receiver<ParseStatus>), non_text_state_update_count: usize, diagnostics: SmallVec<[(LanguageServerId, DiagnosticSet); 2]>, remote_selections: TreeMap<ReplicaId, SelectionSet>, diagnostics_timestamp: clock::Lamport, completion_triggers: BTreeSet<String>, completion_triggers_per_language_server: HashMap<LanguageServerId, BTreeSet<String>>, completion_triggers_timestamp: clock::Lamport, deferred_ops: OperationQueue<Operation>, capability: Capability, has_conflict: bool, /// Memoize calls to has_changes_since(saved_version). /// The contents of a cell are (self.version, has_changes) at the time of a last call. has_unsaved_edits: Cell<(clock::Global, bool)>, _subscriptions: Vec<gpui::Subscription>, } #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub enum ParseStatus { Idle, Parsing, } struct BufferBranchState { base_buffer: Entity<Buffer>, merged_operations: Vec<Lamport>, } /// An immutable, cheaply cloneable representation of a fixed /// state of a buffer. pub struct BufferSnapshot { pub text: text::BufferSnapshot, pub(crate) syntax: SyntaxSnapshot, file: Option<Arc<dyn File>>, diagnostics: SmallVec<[(LanguageServerId, DiagnosticSet); 2]>, remote_selections: TreeMap<ReplicaId, SelectionSet>, language: Option<Arc<Language>>, non_text_state_update_count: usize, } /// The kind and amount of indentation in a particular line. For now, /// assumes that indentation is all the same character. #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Default)] pub struct IndentSize { /// The number of bytes that comprise the indentation. pub len: u32, /// The kind of whitespace used for indentation. pub kind: IndentKind, } /// A whitespace character that's used for indentation. #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Default)] pub enum IndentKind { /// An ASCII space character. #[default] Space, /// An ASCII tab character. Tab, } /// The shape of a selection cursor. #[derive(Copy, Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq, JsonSchema)] #[serde(rename_all = "snake_case")] pub enum CursorShape { /// A vertical bar #[default] Bar, /// A block that surrounds the following character Block, /// An underline that runs along the following character Underline, /// A box drawn around the following character Hollow, } #[derive(Clone, Debug)] struct SelectionSet { line_mode: bool, cursor_shape: CursorShape, selections: Arc<[Selection<Anchor>]>, lamport_timestamp: clock::Lamport, } /// A diagnostic associated with a certain range of a buffer. #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct Diagnostic { /// The name of the service that produced this diagnostic. pub source: Option<String>, /// A machine-readable code that identifies this diagnostic. pub code: Option<NumberOrString>, /// Whether this diagnostic is a hint, warning, or error. pub severity: DiagnosticSeverity, /// The human-readable message associated with this diagnostic. pub message: String, /// An id that identifies the group to which this diagnostic belongs. /// /// When a language server produces a diagnostic with /// one or more associated diagnostics, those diagnostics are all /// assigned a single group ID. pub group_id: usize, /// Whether this diagnostic is the primary diagnostic for its group. /// /// In a given group, the primary diagnostic is the top-level diagnostic /// returned by the language server. The non-primary diagnostics are the /// associated diagnostics. pub is_primary: bool, /// Whether this diagnostic is considered to originate from an analysis of /// files on disk, as opposed to any unsaved buffer contents. This is a /// property of a given diagnostic source, and is configured for a given /// language server via the [`LspAdapter::disk_based_diagnostic_sources`](crate::LspAdapter::disk_based_diagnostic_sources) method /// for the language server. pub is_disk_based: bool, /// Whether this diagnostic marks unnecessary code. pub is_unnecessary: bool, /// Data from language server that produced this diagnostic. Passed back to the LS when we request code actions for this diagnostic. pub data: Option<Value>, } /// An operation used to synchronize this buffer with its other replicas. #[derive(Clone, Debug, PartialEq)] pub enum Operation { /// A text operation. Buffer(text::Operation), /// An update to the buffer's diagnostics. UpdateDiagnostics { /// The id of the language server that produced the new diagnostics. server_id: LanguageServerId, /// The diagnostics. diagnostics: Arc<[DiagnosticEntry<Anchor>]>, /// The buffer's lamport timestamp. lamport_timestamp: clock::Lamport, }, /// An update to the most recent selections in this buffer. UpdateSelections { /// The selections. selections: Arc<[Selection<Anchor>]>, /// The buffer's lamport timestamp. lamport_timestamp: clock::Lamport, /// Whether the selections are in 'line mode'. line_mode: bool, /// The [`CursorShape`] associated with these selections. cursor_shape: CursorShape, }, /// An update to the characters that should trigger autocompletion /// for this buffer. UpdateCompletionTriggers { /// The characters that trigger autocompletion. triggers: Vec<String>, /// The buffer's lamport timestamp. lamport_timestamp: clock::Lamport, /// The language server ID. server_id: LanguageServerId, }, } /// An event that occurs in a buffer. #[derive(Clone, Debug, PartialEq)] pub enum BufferEvent { /// The buffer was changed in a way that must be /// propagated to its other replicas. Operation { operation: Operation, is_local: bool, }, /// The buffer was edited. Edited, /// The buffer's `dirty` bit changed. DirtyChanged, /// The buffer was saved. Saved, /// The buffer's file was changed on disk. FileHandleChanged, /// The buffer was reloaded. Reloaded, /// The buffer is in need of a reload ReloadNeeded, /// The buffer's language was changed. LanguageChanged, /// The buffer's syntax trees were updated. Reparsed, /// The buffer's diagnostics were updated. DiagnosticsUpdated, /// The buffer gained or lost editing capabilities. CapabilityChanged, /// The buffer was explicitly requested to close. Closed, /// The buffer was discarded when closing. Discarded, } /// The file associated with a buffer. pub trait File: Send + Sync { /// Returns the [`LocalFile`] associated with this file, if the /// file is local. fn as_local(&self) -> Option<&dyn LocalFile>; /// Returns whether this file is local. fn is_local(&self) -> bool { self.as_local().is_some() } /// Returns whether the file is new, exists in storage, or has been deleted. Includes metadata /// only available in some states, such as modification time. fn disk_state(&self) -> DiskState; /// Returns the path of this file relative to the worktree's root directory. fn path(&self) -> &Arc<Path>; /// Returns the path of this file relative to the worktree's parent directory (this means it /// includes the name of the worktree's root folder). fn full_path(&self, cx: &App) -> PathBuf; /// Returns the last component of this handle's absolute path. If this handle refers to the root /// of its worktree, then this method will return the name of the worktree itself. fn file_name<'a>(&'a self, cx: &'a App) -> &'a OsStr; /// Returns the id of the worktree to which this file belongs. /// /// This is needed for looking up project-specific settings. fn worktree_id(&self, cx: &App) -> WorktreeId; /// Converts this file into an [`Any`] trait object. fn as_any(&self) -> &dyn Any; /// Converts this file into a protobuf message. fn to_proto(&self, cx: &App) -> rpc::proto::File; /// Return whether Zed considers this to be a private file. fn is_private(&self) -> bool; } /// The file's storage status - whether it's stored (`Present`), and if so when it was last /// modified. In the case where the file is not stored, it can be either `New` or `Deleted`. In the /// UI these two states are distinguished. For example, the buffer tab does not display a deletion /// indicator for new files. #[derive(Copy, Clone, Debug, PartialEq)] pub enum DiskState { /// File created in Zed that has not been saved. New, /// File present on the filesystem. Present { mtime: MTime }, /// Deleted file that was previously present. Deleted, } impl DiskState { /// Returns the file's last known modification time on disk. pub fn mtime(self) -> Option<MTime> { match self { DiskState::New => None, DiskState::Present { mtime } => Some(mtime), DiskState::Deleted => None, } } pub fn exists(&self) -> bool { match self { DiskState::New => false, DiskState::Present { .. } => true, DiskState::Deleted => false, } } } /// The file associated with a buffer, in the case where the file is on the local disk. pub trait LocalFile: File { /// Returns the absolute path of this file fn abs_path(&self, cx: &App) -> PathBuf; /// Loads the file contents from disk and returns them as a UTF-8 encoded string. fn load(&self, cx: &App) -> Task<Result<String>>; /// Loads the file's contents from disk. fn load_bytes(&self, cx: &App) -> Task<Result<Vec<u8>>>; } /// The auto-indent behavior associated with an editing operation. /// For some editing operations, each affected line of text has its /// indentation recomputed. For other operations, the entire block /// of edited text is adjusted uniformly. #[derive(Clone, Debug)] pub enum AutoindentMode { /// Indent each line of inserted text. EachLine, /// Apply the same indentation adjustment to all of the lines /// in a given insertion. Block { /// The original start column of each insertion, if it was /// copied from elsewhere. /// /// Knowing this start column makes it possible to preserve the /// relative indentation of every line in the insertion from /// when it was copied. /// /// If the start column is `a`, and the first line of insertion /// is then auto-indented to column `b`, then every other line of /// the insertion will be auto-indented to column `b - a` original_start_columns: Vec<u32>, }, } #[derive(Clone)] struct AutoindentRequest { before_edit: BufferSnapshot, entries: Vec<AutoindentRequestEntry>, is_block_mode: bool, ignore_empty_lines: bool, } #[derive(Debug, Clone)] struct AutoindentRequestEntry { /// A range of the buffer whose indentation should be adjusted. range: Range<Anchor>, /// Whether or not these lines should be considered brand new, for the /// purpose of auto-indent. When text is not new, its indentation will /// only be adjusted if the suggested indentation level has *changed* /// since the edit was made. first_line_is_new: bool, indent_size: IndentSize, original_indent_column: Option<u32>, } #[derive(Debug)] struct IndentSuggestion { basis_row: u32, delta: Ordering, within_error: bool, } struct BufferChunkHighlights<'a> { captures: SyntaxMapCaptures<'a>, next_capture: Option<SyntaxMapCapture<'a>>, stack: Vec<(usize, HighlightId)>, highlight_maps: Vec<HighlightMap>, } /// An iterator that yields chunks of a buffer's text, along with their /// syntax highlights and diagnostic status. pub struct BufferChunks<'a> { buffer_snapshot: Option<&'a BufferSnapshot>, range: Range<usize>, chunks: text::Chunks<'a>, diagnostic_endpoints: Option<Peekable<vec::IntoIter<DiagnosticEndpoint>>>, error_depth: usize, warning_depth: usize, information_depth: usize, hint_depth: usize, unnecessary_depth: usize, highlights: Option<BufferChunkHighlights<'a>>, } /// A chunk of a buffer's text, along with its syntax highlight and /// diagnostic status. #[derive(Clone, Debug, Default)] pub struct Chunk<'a> { /// The text of the chunk. pub text: &'a str, /// The syntax highlighting style of the chunk. pub syntax_highlight_id: Option<HighlightId>, /// The highlight style that has been applied to this chunk in /// the editor. pub highlight_style: Option<HighlightStyle>, /// The severity of diagnostic associated with this chunk, if any. pub diagnostic_severity: Option<DiagnosticSeverity>, /// Whether this chunk of text is marked as unnecessary. pub is_unnecessary: bool, /// Whether this chunk of text was originally a tab character. pub is_tab: bool, /// An optional recipe for how the chunk should be presented. pub renderer: Option<ChunkRenderer>, } /// A recipe for how the chunk should be presented. #[derive(Clone)] pub struct ChunkRenderer { /// creates a custom element to represent this chunk. pub render: Arc<dyn Send + Sync + Fn(&mut ChunkRendererContext) -> AnyElement>, /// If true, the element is constrained to the shaped width of the text. pub constrain_width: bool, } pub struct ChunkRendererContext<'a, 'b> { pub window: &'a mut Window, pub context: &'b mut App,