More docs

This commit is contained in:
Max Brunsfeld 2024-01-09 10:53:57 -08:00
parent 7fbe0b8638
commit b02f37083b
7 changed files with 133 additions and 42 deletions

View file

@ -10,7 +10,7 @@ use crate::{
markdown::parse_markdown, markdown::parse_markdown,
outline::OutlineItem, outline::OutlineItem,
syntax_map::{ syntax_map::{
SyntaxLayerInfo, SyntaxMap, SyntaxMapCapture, SyntaxMapCaptures, SyntaxMapMatches, SyntaxLayer, SyntaxMap, SyntaxMapCapture, SyntaxMapCaptures, SyntaxMapMatches,
SyntaxSnapshot, ToTreeSitterPoint, SyntaxSnapshot, ToTreeSitterPoint,
}, },
CodeLabel, LanguageScope, Outline, CodeLabel, LanguageScope, Outline,
@ -69,7 +69,8 @@ pub enum Capability {
ReadOnly, ReadOnly,
} }
/// An in-memory representation of a source code file. /// An in-memory representation of a source code file, including its text,
/// syntax trees, git status, and diagnostics.
pub struct Buffer { pub struct Buffer {
text: TextBuffer, text: TextBuffer,
diff_base: Option<String>, diff_base: Option<String>,
@ -123,12 +124,15 @@ pub struct BufferSnapshot {
parse_count: usize, parse_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, Default)] #[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
pub struct IndentSize { pub struct IndentSize {
pub len: u32, pub len: u32,
pub kind: IndentKind, pub kind: IndentKind,
} }
/// A whitespace character that's used for indentation.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)] #[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
pub enum IndentKind { pub enum IndentKind {
#[default] #[default]
@ -136,6 +140,7 @@ pub enum IndentKind {
Tab, Tab,
} }
/// The shape of a selection cursor.
#[derive(Copy, Clone, PartialEq, Eq, Debug, Default)] #[derive(Copy, Clone, PartialEq, Eq, Debug, Default)]
pub enum CursorShape { pub enum CursorShape {
#[default] #[default]
@ -300,6 +305,7 @@ pub trait File: Send + Sync {
fn to_proto(&self) -> rpc::proto::File; fn to_proto(&self) -> rpc::proto::File;
} }
/// The file associated with a buffer, in the case where the file is on the local disk.
pub trait LocalFile: File { pub trait LocalFile: File {
/// Returns the absolute path of this file. /// Returns the absolute path of this file.
fn abs_path(&self, cx: &AppContext) -> PathBuf; fn abs_path(&self, cx: &AppContext) -> PathBuf;
@ -409,6 +415,7 @@ pub(crate) struct DiagnosticEndpoint {
is_unnecessary: bool, is_unnecessary: bool,
} }
/// A class of characters, used for characterizing a run of text.
#[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord, Debug)] #[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord, Debug)]
pub enum CharKind { pub enum CharKind {
Whitespace, Whitespace,
@ -2048,6 +2055,8 @@ impl BufferSnapshot {
} }
} }
/// Retrieve the suggested indent size for all of the given rows. The unit of indentation
/// is passed in as `single_indent_size`.
pub fn suggested_indents( pub fn suggested_indents(
&self, &self,
rows: impl Iterator<Item = u32>, rows: impl Iterator<Item = u32>,
@ -2294,6 +2303,10 @@ impl BufferSnapshot {
None None
} }
/// Iterates over chunks of text in the given range of the buffer. Text is chunked
/// in an arbitrary way due to being stored in a [`rope::Rope`]. The text is also
/// returned in chunks where each chunk has a single syntax highlighting style and
/// diagnostic status.
pub fn chunks<T: ToOffset>(&self, range: Range<T>, language_aware: bool) -> BufferChunks { pub fn chunks<T: ToOffset>(&self, range: Range<T>, language_aware: bool) -> BufferChunks {
let range = range.start.to_offset(self)..range.end.to_offset(self); let range = range.start.to_offset(self)..range.end.to_offset(self);
@ -2330,7 +2343,9 @@ impl BufferSnapshot {
BufferChunks::new(self.text.as_rope(), range, syntax, diagnostic_endpoints) BufferChunks::new(self.text.as_rope(), range, syntax, diagnostic_endpoints)
} }
pub fn for_each_line(&self, range: Range<Point>, mut callback: impl FnMut(u32, &str)) { /// Invokes the given callback for each line of text in the given range of the buffer.
/// Uses callback to avoid allocating a string for each line.
fn for_each_line(&self, range: Range<Point>, mut callback: impl FnMut(u32, &str)) {
let mut line = String::new(); let mut line = String::new();
let mut row = range.start.row; let mut row = range.start.row;
for chunk in self for chunk in self
@ -2349,11 +2364,12 @@ impl BufferSnapshot {
} }
} }
pub fn syntax_layers(&self) -> impl Iterator<Item = SyntaxLayerInfo> + '_ { /// Iterates over every [`SyntaxLayer`] in the buffer.
pub fn syntax_layers(&self) -> impl Iterator<Item = SyntaxLayer> + '_ {
self.syntax.layers_for_range(0..self.len(), &self.text) self.syntax.layers_for_range(0..self.len(), &self.text)
} }
pub fn syntax_layer_at<D: ToOffset>(&self, position: D) -> Option<SyntaxLayerInfo> { pub fn syntax_layer_at<D: ToOffset>(&self, position: D) -> Option<SyntaxLayer> {
let offset = position.to_offset(self); let offset = position.to_offset(self);
self.syntax self.syntax
.layers_for_range(offset..offset, &self.text) .layers_for_range(offset..offset, &self.text)

View file

@ -58,7 +58,7 @@ pub use buffer::*;
pub use diagnostic_set::DiagnosticEntry; pub use diagnostic_set::DiagnosticEntry;
pub use lsp::LanguageServerId; pub use lsp::LanguageServerId;
pub use outline::{Outline, OutlineItem}; pub use outline::{Outline, OutlineItem};
pub use syntax_map::{OwnedSyntaxLayerInfo, SyntaxLayerInfo}; pub use syntax_map::{OwnedSyntaxLayer, SyntaxLayer};
pub use text::LineEnding; pub use text::LineEnding;
pub use tree_sitter::{Parser, Tree}; pub use tree_sitter::{Parser, Tree};
@ -246,6 +246,8 @@ impl CachedLspAdapter {
} }
} }
/// [`LspAdapterDelegate`] allows [`LspAdapter]` implementations to interface with the application
// e.g. to display a notification or fetch data from the web.
pub trait LspAdapterDelegate: Send + Sync { pub trait LspAdapterDelegate: Send + Sync {
fn show_notification(&self, message: &str, cx: &mut AppContext); fn show_notification(&self, message: &str, cx: &mut AppContext);
fn http_client(&self) -> Arc<dyn HttpClient>; fn http_client(&self) -> Arc<dyn HttpClient>;
@ -291,6 +293,10 @@ pub trait LspAdapter: 'static + Send + Sync {
delegate: &dyn LspAdapterDelegate, delegate: &dyn LspAdapterDelegate,
) -> Option<LanguageServerBinary>; ) -> Option<LanguageServerBinary>;
/// Returns true if a language server can be reinstalled.
/// If language server initialization fails, a reinstallation will be attempted unless the value returned from this method is false.
/// Implementations that rely on software already installed on user's system
/// should have [`can_be_reinstalled`] return false.
fn can_be_reinstalled(&self) -> bool { fn can_be_reinstalled(&self) -> bool {
true true
} }
@ -302,6 +308,9 @@ pub trait LspAdapter: 'static + Send + Sync {
fn process_diagnostics(&self, _: &mut lsp::PublishDiagnosticsParams) {} fn process_diagnostics(&self, _: &mut lsp::PublishDiagnosticsParams) {}
/// A callback called for each [`lsp_types::CompletionItem`] obtained from LSP server.
/// Some LspAdapter implementations might want to modify the obtained item to
/// change how it's displayed.
async fn process_completion(&self, _: &mut lsp::CompletionItem) {} async fn process_completion(&self, _: &mut lsp::CompletionItem) {}
async fn label_for_completion( async fn label_for_completion(
@ -321,6 +330,7 @@ pub trait LspAdapter: 'static + Send + Sync {
None None
} }
/// Returns initialization options that are going to be sent to a LSP server as a part of [`lsp_types::InitializeParams`]
async fn initialization_options(&self) -> Option<Value> { async fn initialization_options(&self) -> Option<Value> {
None None
} }
@ -329,6 +339,7 @@ pub trait LspAdapter: 'static + Send + Sync {
futures::future::ready(serde_json::json!({})).boxed() futures::future::ready(serde_json::json!({})).boxed()
} }
/// Returns a list of code actions supported by a given LspAdapter
fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> { fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
Some(vec![ Some(vec![
CodeActionKind::EMPTY, CodeActionKind::EMPTY,
@ -380,19 +391,29 @@ pub struct LanguageConfig {
/// the indentation level for a new line. /// the indentation level for a new line.
#[serde(default = "auto_indent_using_last_non_empty_line_default")] #[serde(default = "auto_indent_using_last_non_empty_line_default")]
pub auto_indent_using_last_non_empty_line: bool, pub auto_indent_using_last_non_empty_line: bool,
/// A regex that is used to determine whether the /// A regex that is used to determine whether the indentation level should be
/// increased in the following line.
#[serde(default, deserialize_with = "deserialize_regex")] #[serde(default, deserialize_with = "deserialize_regex")]
pub increase_indent_pattern: Option<Regex>, pub increase_indent_pattern: Option<Regex>,
/// A regex that is used to determine whether the indentation level should be
/// decreased in the following line.
#[serde(default, deserialize_with = "deserialize_regex")] #[serde(default, deserialize_with = "deserialize_regex")]
pub decrease_indent_pattern: Option<Regex>, pub decrease_indent_pattern: Option<Regex>,
/// A list of characters that trigger the automatic insertion of a closing
/// bracket when they immediately precede the point where an opening
/// bracket is inserted.
#[serde(default)] #[serde(default)]
pub autoclose_before: String, pub autoclose_before: String,
#[serde(default)] /// A placeholder used internally by Semantic Index.
pub line_comment: Option<Arc<str>>,
#[serde(default)] #[serde(default)]
pub collapsed_placeholder: String, pub collapsed_placeholder: String,
/// A line comment string that is inserted in e.g. `toggle comments` action.
#[serde(default)]
pub line_comment: Option<Arc<str>>,
/// Starting and closing characters of a block comment.
#[serde(default)] #[serde(default)]
pub block_comment: Option<(Arc<str>, Arc<str>)>, pub block_comment: Option<(Arc<str>, Arc<str>)>,
/// A list of language servers that are allowed to run on subranges of a given language.
#[serde(default)] #[serde(default)]
pub scope_opt_in_language_servers: Vec<String>, pub scope_opt_in_language_servers: Vec<String>,
#[serde(default)] #[serde(default)]
@ -402,6 +423,7 @@ pub struct LanguageConfig {
/// or a whole-word search in buffer search. /// or a whole-word search in buffer search.
#[serde(default)] #[serde(default)]
pub word_characters: HashSet<char>, pub word_characters: HashSet<char>,
/// The name of a Prettier parser that should be used for this language.
#[serde(default)] #[serde(default)]
pub prettier_parser_name: Option<String>, pub prettier_parser_name: Option<String>,
} }
@ -480,9 +502,9 @@ impl Default for LanguageConfig {
block_comment: Default::default(), block_comment: Default::default(),
scope_opt_in_language_servers: Default::default(), scope_opt_in_language_servers: Default::default(),
overrides: Default::default(), overrides: Default::default(),
collapsed_placeholder: Default::default(),
word_characters: Default::default(), word_characters: Default::default(),
prettier_parser_name: None, prettier_parser_name: None,
collapsed_placeholder: Default::default(),
} }
} }
} }

View file

@ -96,24 +96,30 @@ pub struct LanguageSettings {
/// The settings for [GitHub Copilot](https://github.com/features/copilot). /// The settings for [GitHub Copilot](https://github.com/features/copilot).
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
pub struct CopilotSettings { pub struct CopilotSettings {
/// Whether Copilit is enabled. /// Whether Copilot is enabled.
pub feature_enabled: bool, pub feature_enabled: bool,
/// A list of globs representing files that Copilot should be disabled for. /// A list of globs representing files that Copilot should be disabled for.
pub disabled_globs: Vec<GlobMatcher>, pub disabled_globs: Vec<GlobMatcher>,
} }
/// The settings for all languages.
#[derive(Clone, Default, Serialize, Deserialize, JsonSchema)] #[derive(Clone, Default, Serialize, Deserialize, JsonSchema)]
pub struct AllLanguageSettingsContent { pub struct AllLanguageSettingsContent {
/// The settings for enabling/disabling features.
#[serde(default)] #[serde(default)]
pub features: Option<FeaturesContent>, pub features: Option<FeaturesContent>,
/// The settings for GitHub Copilot.
#[serde(default)] #[serde(default)]
pub copilot: Option<CopilotSettingsContent>, pub copilot: Option<CopilotSettingsContent>,
/// The default language settings.
#[serde(flatten)] #[serde(flatten)]
pub defaults: LanguageSettingsContent, pub defaults: LanguageSettingsContent,
/// The settings for individual languages.
#[serde(default, alias = "language_overrides")] #[serde(default, alias = "language_overrides")]
pub languages: HashMap<Arc<str>, LanguageSettingsContent>, pub languages: HashMap<Arc<str>, LanguageSettingsContent>,
} }
/// The settings for a particular language.
#[derive(Clone, Default, Serialize, Deserialize, JsonSchema)] #[derive(Clone, Default, Serialize, Deserialize, JsonSchema)]
pub struct LanguageSettingsContent { pub struct LanguageSettingsContent {
/// How many columns a tab should occupy. /// How many columns a tab should occupy.
@ -204,12 +210,15 @@ pub struct LanguageSettingsContent {
pub inlay_hints: Option<InlayHintSettings>, pub inlay_hints: Option<InlayHintSettings>,
} }
/// The contents of the GitHub Copilot settings.
#[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema)] #[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema)]
pub struct CopilotSettingsContent { pub struct CopilotSettingsContent {
/// A list of globs representing files that Copilot should be disabled for.
#[serde(default)] #[serde(default)]
pub disabled_globs: Option<Vec<String>>, pub disabled_globs: Option<Vec<String>>,
} }
/// The settings for enabling/disabling features.
#[derive(Clone, Default, Serialize, Deserialize, JsonSchema)] #[derive(Clone, Default, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "snake_case")] #[serde(rename_all = "snake_case")]
pub struct FeaturesContent { pub struct FeaturesContent {
@ -237,6 +246,7 @@ pub enum FormatOnSave {
On, On,
/// Files should not be formatted on save. /// Files should not be formatted on save.
Off, Off,
/// Files should be formatted using the current language server.
LanguageServer, LanguageServer,
/// The external program to use to format the files on save. /// The external program to use to format the files on save.
External { External {
@ -247,17 +257,19 @@ pub enum FormatOnSave {
}, },
} }
/// Controls how whitespace should be displayedin the editor.
#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)] #[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
#[serde(rename_all = "snake_case")] #[serde(rename_all = "snake_case")]
pub enum ShowWhitespaceSetting { pub enum ShowWhitespaceSetting {
/// Draw tabs and spaces only for the selected text. /// Draw whitespace only for the selected text.
Selection, Selection,
/// Do not draw any tabs or spaces /// Do not draw any tabs or spaces.
None, None,
/// Draw all invisible symbols /// Draw all invisible symbols.
All, All,
} }
/// Controls which formatter should be used when formatting code.
#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq, JsonSchema)] #[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
#[serde(rename_all = "snake_case")] #[serde(rename_all = "snake_case")]
pub enum Formatter { pub enum Formatter {
@ -271,7 +283,9 @@ pub enum Formatter {
Prettier, Prettier,
/// Format code using an external command. /// Format code using an external command.
External { External {
/// The external program to run.
command: Arc<str>, command: Arc<str>,
/// The arguments to pass to the program.
arguments: Arc<[String]>, arguments: Arc<[String]>,
}, },
} }
@ -323,6 +337,7 @@ impl InlayHintSettings {
} }
impl AllLanguageSettings { impl AllLanguageSettings {
/// Returns the [`LanguageSettings`] for the language with the specified name.
pub fn language<'a>(&'a self, language_name: Option<&str>) -> &'a LanguageSettings { pub fn language<'a>(&'a self, language_name: Option<&str>) -> &'a LanguageSettings {
if let Some(name) = language_name { if let Some(name) = language_name {
if let Some(overrides) = self.languages.get(name) { if let Some(overrides) = self.languages.get(name) {
@ -332,6 +347,7 @@ impl AllLanguageSettings {
&self.defaults &self.defaults
} }
/// Returns whether GitHub Copilot is enabled for the given path.
pub fn copilot_enabled_for_path(&self, path: &Path) -> bool { pub fn copilot_enabled_for_path(&self, path: &Path) -> bool {
!self !self
.copilot .copilot
@ -340,6 +356,7 @@ impl AllLanguageSettings {
.any(|glob| glob.is_match(path)) .any(|glob| glob.is_match(path))
} }
/// Returns whether GitHub Copilot is enabled for the given language and path.
pub fn copilot_enabled(&self, language: Option<&Arc<Language>>, path: Option<&Path>) -> bool { pub fn copilot_enabled(&self, language: Option<&Arc<Language>>, path: Option<&Path>) -> bool {
if !self.copilot.feature_enabled { if !self.copilot.feature_enabled {
return false; return false;
@ -356,13 +373,20 @@ impl AllLanguageSettings {
} }
} }
/// The kind of an inlay hint.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum InlayHintKind { pub enum InlayHintKind {
/// An inlay hint for a type.
Type, Type,
/// An inlay hint for a parameter.
Parameter, Parameter,
} }
impl InlayHintKind { impl InlayHintKind {
/// Returns the [`InlayHintKind`] from the given name.
///
/// Returns `None` if `name` does not match any of the expected
/// string representations.
pub fn from_name(name: &str) -> Option<Self> { pub fn from_name(name: &str) -> Option<Self> {
match name { match name {
"type" => Some(InlayHintKind::Type), "type" => Some(InlayHintKind::Type),
@ -371,6 +395,7 @@ impl InlayHintKind {
} }
} }
/// Returns the name of this [`InlayHintKind`].
pub fn name(&self) -> &'static str { pub fn name(&self) -> &'static str {
match self { match self {
InlayHintKind::Type => "type", InlayHintKind::Type => "type",

View file

@ -2,6 +2,7 @@ use fuzzy::{StringMatch, StringMatchCandidate};
use gpui::{BackgroundExecutor, HighlightStyle}; use gpui::{BackgroundExecutor, HighlightStyle};
use std::ops::Range; use std::ops::Range;
/// An outline of all the symbols contained in a buffer.
#[derive(Debug)] #[derive(Debug)]
pub struct Outline<T> { pub struct Outline<T> {
pub items: Vec<OutlineItem<T>>, pub items: Vec<OutlineItem<T>>,

View file

@ -13,18 +13,18 @@ use text::*;
pub use proto::{BufferState, Operation}; pub use proto::{BufferState, Operation};
/// Serializes a [`RopeFingerprint`] to be sent over the wire. /// Serializes a [`RopeFingerprint`] to be sent over RPC.
pub fn serialize_fingerprint(fingerprint: RopeFingerprint) -> String { pub fn serialize_fingerprint(fingerprint: RopeFingerprint) -> String {
fingerprint.to_hex() fingerprint.to_hex()
} }
/// Deserializes a [`RopeFingerprint`] from the wire format. /// Deserializes a [`RopeFingerprint`] from the RPC representation.
pub fn deserialize_fingerprint(fingerprint: &str) -> Result<RopeFingerprint> { pub fn deserialize_fingerprint(fingerprint: &str) -> Result<RopeFingerprint> {
RopeFingerprint::from_hex(fingerprint) RopeFingerprint::from_hex(fingerprint)
.map_err(|error| anyhow!("invalid fingerprint: {}", error)) .map_err(|error| anyhow!("invalid fingerprint: {}", error))
} }
/// Deserializes a `[text::LineEnding]` from the wire format. /// Deserializes a `[text::LineEnding]` from the RPC representation.
pub fn deserialize_line_ending(message: proto::LineEnding) -> text::LineEnding { pub fn deserialize_line_ending(message: proto::LineEnding) -> text::LineEnding {
match message { match message {
proto::LineEnding::Unix => text::LineEnding::Unix, proto::LineEnding::Unix => text::LineEnding::Unix,
@ -32,7 +32,7 @@ pub fn deserialize_line_ending(message: proto::LineEnding) -> text::LineEnding {
} }
} }
/// Serializes a [`text::LineEnding`] to be sent over the wire. /// Serializes a [`text::LineEnding`] to be sent over RPC.
pub fn serialize_line_ending(message: text::LineEnding) -> proto::LineEnding { pub fn serialize_line_ending(message: text::LineEnding) -> proto::LineEnding {
match message { match message {
text::LineEnding::Unix => proto::LineEnding::Unix, text::LineEnding::Unix => proto::LineEnding::Unix,
@ -40,7 +40,7 @@ pub fn serialize_line_ending(message: text::LineEnding) -> proto::LineEnding {
} }
} }
/// Serializes a [`crate::Operation`] to be sent over the wire. /// Serializes a [`crate::Operation`] to be sent over RPC.
pub fn serialize_operation(operation: &crate::Operation) -> proto::Operation { pub fn serialize_operation(operation: &crate::Operation) -> proto::Operation {
proto::Operation { proto::Operation {
variant: Some(match operation { variant: Some(match operation {
@ -103,7 +103,7 @@ pub fn serialize_operation(operation: &crate::Operation) -> proto::Operation {
} }
} }
/// Serializes an [`operation::EditOperation`] to be sent over the wire. /// Serializes an [`operation::EditOperation`] to be sent over RPC.
pub fn serialize_edit_operation(operation: &EditOperation) -> proto::operation::Edit { pub fn serialize_edit_operation(operation: &EditOperation) -> proto::operation::Edit {
proto::operation::Edit { proto::operation::Edit {
replica_id: operation.timestamp.replica_id as u32, replica_id: operation.timestamp.replica_id as u32,
@ -118,7 +118,7 @@ pub fn serialize_edit_operation(operation: &EditOperation) -> proto::operation::
} }
} }
/// Serializes an entry in the undo map to be sent over the wire. /// Serializes an entry in the undo map to be sent over RPC.
pub fn serialize_undo_map_entry( pub fn serialize_undo_map_entry(
(edit_id, counts): (&clock::Lamport, &[(clock::Lamport, u32)]), (edit_id, counts): (&clock::Lamport, &[(clock::Lamport, u32)]),
) -> proto::UndoMapEntry { ) -> proto::UndoMapEntry {
@ -136,6 +136,7 @@ pub fn serialize_undo_map_entry(
} }
} }
/// Splits the given list of operations into chunks.
pub fn split_operations( pub fn split_operations(
mut operations: Vec<proto::Operation>, mut operations: Vec<proto::Operation>,
) -> impl Iterator<Item = Vec<proto::Operation>> { ) -> impl Iterator<Item = Vec<proto::Operation>> {
@ -161,10 +162,12 @@ pub fn split_operations(
}) })
} }
/// Serializes selections to be sent over RPC.
pub fn serialize_selections(selections: &Arc<[Selection<Anchor>]>) -> Vec<proto::Selection> { pub fn serialize_selections(selections: &Arc<[Selection<Anchor>]>) -> Vec<proto::Selection> {
selections.iter().map(serialize_selection).collect() selections.iter().map(serialize_selection).collect()
} }
/// Serializes a [`Selection`] to be sent over RPC.
pub fn serialize_selection(selection: &Selection<Anchor>) -> proto::Selection { pub fn serialize_selection(selection: &Selection<Anchor>) -> proto::Selection {
proto::Selection { proto::Selection {
id: selection.id as u64, id: selection.id as u64,
@ -180,6 +183,7 @@ pub fn serialize_selection(selection: &Selection<Anchor>) -> proto::Selection {
} }
} }
/// Serializes a [`CursorShape`] to be sent over RPC.
pub fn serialize_cursor_shape(cursor_shape: &CursorShape) -> proto::CursorShape { pub fn serialize_cursor_shape(cursor_shape: &CursorShape) -> proto::CursorShape {
match cursor_shape { match cursor_shape {
CursorShape::Bar => proto::CursorShape::CursorBar, CursorShape::Bar => proto::CursorShape::CursorBar,
@ -189,6 +193,7 @@ pub fn serialize_cursor_shape(cursor_shape: &CursorShape) -> proto::CursorShape
} }
} }
/// Deserializes a [`CursorShape`] from the RPC representation.
pub fn deserialize_cursor_shape(cursor_shape: proto::CursorShape) -> CursorShape { pub fn deserialize_cursor_shape(cursor_shape: proto::CursorShape) -> CursorShape {
match cursor_shape { match cursor_shape {
proto::CursorShape::CursorBar => CursorShape::Bar, proto::CursorShape::CursorBar => CursorShape::Bar,
@ -198,6 +203,7 @@ pub fn deserialize_cursor_shape(cursor_shape: proto::CursorShape) -> CursorShape
} }
} }
/// Serializes a list of diagnostics to be sent over RPC.
pub fn serialize_diagnostics<'a>( pub fn serialize_diagnostics<'a>(
diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<Anchor>>, diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<Anchor>>,
) -> Vec<proto::Diagnostic> { ) -> Vec<proto::Diagnostic> {
@ -225,6 +231,7 @@ pub fn serialize_diagnostics<'a>(
.collect() .collect()
} }
/// Serializes an [`Anchor`] to be sent over RPC.
pub fn serialize_anchor(anchor: &Anchor) -> proto::Anchor { pub fn serialize_anchor(anchor: &Anchor) -> proto::Anchor {
proto::Anchor { proto::Anchor {
replica_id: anchor.timestamp.replica_id as u32, replica_id: anchor.timestamp.replica_id as u32,
@ -239,6 +246,7 @@ pub fn serialize_anchor(anchor: &Anchor) -> proto::Anchor {
} }
// This behavior is currently copied in the collab database, for snapshotting channel notes // This behavior is currently copied in the collab database, for snapshotting channel notes
/// Deserializes an [`crate::Operation`] from the RPC representation.
pub fn deserialize_operation(message: proto::Operation) -> Result<crate::Operation> { pub fn deserialize_operation(message: proto::Operation) -> Result<crate::Operation> {
Ok( Ok(
match message match message
@ -321,6 +329,7 @@ pub fn deserialize_operation(message: proto::Operation) -> Result<crate::Operati
) )
} }
/// Deserializes an [`EditOperation`] from the RPC representation.
pub fn deserialize_edit_operation(edit: proto::operation::Edit) -> EditOperation { pub fn deserialize_edit_operation(edit: proto::operation::Edit) -> EditOperation {
EditOperation { EditOperation {
timestamp: clock::Lamport { timestamp: clock::Lamport {
@ -333,6 +342,7 @@ pub fn deserialize_edit_operation(edit: proto::operation::Edit) -> EditOperation
} }
} }
/// Deserializes an entry in the undo map from the RPC representation.
pub fn deserialize_undo_map_entry( pub fn deserialize_undo_map_entry(
entry: proto::UndoMapEntry, entry: proto::UndoMapEntry,
) -> (clock::Lamport, Vec<(clock::Lamport, u32)>) { ) -> (clock::Lamport, Vec<(clock::Lamport, u32)>) {
@ -357,6 +367,7 @@ pub fn deserialize_undo_map_entry(
) )
} }
/// Deserializes selections from the RPC representation.
pub fn deserialize_selections(selections: Vec<proto::Selection>) -> Arc<[Selection<Anchor>]> { pub fn deserialize_selections(selections: Vec<proto::Selection>) -> Arc<[Selection<Anchor>]> {
Arc::from( Arc::from(
selections selections
@ -366,6 +377,7 @@ pub fn deserialize_selections(selections: Vec<proto::Selection>) -> Arc<[Selecti
) )
} }
/// Deserializes a [`Selection`] from the RPC representation.
pub fn deserialize_selection(selection: proto::Selection) -> Option<Selection<Anchor>> { pub fn deserialize_selection(selection: proto::Selection) -> Option<Selection<Anchor>> {
Some(Selection { Some(Selection {
id: selection.id as usize, id: selection.id as usize,
@ -376,6 +388,7 @@ pub fn deserialize_selection(selection: proto::Selection) -> Option<Selection<An
}) })
} }
/// Deserializes a list of diagnostics from the RPC representation.
pub fn deserialize_diagnostics( pub fn deserialize_diagnostics(
diagnostics: Vec<proto::Diagnostic>, diagnostics: Vec<proto::Diagnostic>,
) -> Arc<[DiagnosticEntry<Anchor>]> { ) -> Arc<[DiagnosticEntry<Anchor>]> {
@ -406,6 +419,7 @@ pub fn deserialize_diagnostics(
.collect() .collect()
} }
/// Deserializes an [`Anchor`] from the RPC representation.
pub fn deserialize_anchor(anchor: proto::Anchor) -> Option<Anchor> { pub fn deserialize_anchor(anchor: proto::Anchor) -> Option<Anchor> {
Some(Anchor { Some(Anchor {
timestamp: clock::Lamport { timestamp: clock::Lamport {
@ -421,6 +435,7 @@ pub fn deserialize_anchor(anchor: proto::Anchor) -> Option<Anchor> {
}) })
} }
/// Returns a `[clock::Lamport`] timestamp for the given [`proto::Operation`].
pub fn lamport_timestamp_for_operation(operation: &proto::Operation) -> Option<clock::Lamport> { pub fn lamport_timestamp_for_operation(operation: &proto::Operation) -> Option<clock::Lamport> {
let replica_id; let replica_id;
let value; let value;
@ -453,6 +468,7 @@ pub fn lamport_timestamp_for_operation(operation: &proto::Operation) -> Option<c
}) })
} }
/// Serializes a [`Completion`] to be sent over RPC.
pub fn serialize_completion(completion: &Completion) -> proto::Completion { pub fn serialize_completion(completion: &Completion) -> proto::Completion {
proto::Completion { proto::Completion {
old_start: Some(serialize_anchor(&completion.old_range.start)), old_start: Some(serialize_anchor(&completion.old_range.start)),
@ -463,6 +479,7 @@ pub fn serialize_completion(completion: &Completion) -> proto::Completion {
} }
} }
/// Deserializes a [`Completion`] from the RPC representation.
pub async fn deserialize_completion( pub async fn deserialize_completion(
completion: proto::Completion, completion: proto::Completion,
language: Option<Arc<Language>>, language: Option<Arc<Language>>,
@ -497,6 +514,7 @@ pub async fn deserialize_completion(
}) })
} }
/// Serializes a [`CodeAction`] to be sent over RPC.
pub fn serialize_code_action(action: &CodeAction) -> proto::CodeAction { pub fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
proto::CodeAction { proto::CodeAction {
server_id: action.server_id.0 as u64, server_id: action.server_id.0 as u64,
@ -506,6 +524,7 @@ pub fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
} }
} }
/// Deserializes a [`CodeAction`] from the RPC representation.
pub fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> { pub fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
let start = action let start = action
.start .start
@ -523,6 +542,7 @@ pub fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction>
}) })
} }
/// Serializes a [`Transaction`] to be sent over RPC.
pub fn serialize_transaction(transaction: &Transaction) -> proto::Transaction { pub fn serialize_transaction(transaction: &Transaction) -> proto::Transaction {
proto::Transaction { proto::Transaction {
id: Some(serialize_timestamp(transaction.id)), id: Some(serialize_timestamp(transaction.id)),
@ -536,6 +556,7 @@ pub fn serialize_transaction(transaction: &Transaction) -> proto::Transaction {
} }
} }
/// Deserializes a [`Transaction`] from the RPC representation.
pub fn deserialize_transaction(transaction: proto::Transaction) -> Result<Transaction> { pub fn deserialize_transaction(transaction: proto::Transaction) -> Result<Transaction> {
Ok(Transaction { Ok(Transaction {
id: deserialize_timestamp( id: deserialize_timestamp(
@ -552,6 +573,7 @@ pub fn deserialize_transaction(transaction: proto::Transaction) -> Result<Transa
}) })
} }
/// Serializes a [`clock::Lamport`] timestamp to be sent over RPC.
pub fn serialize_timestamp(timestamp: clock::Lamport) -> proto::LamportTimestamp { pub fn serialize_timestamp(timestamp: clock::Lamport) -> proto::LamportTimestamp {
proto::LamportTimestamp { proto::LamportTimestamp {
replica_id: timestamp.replica_id as u32, replica_id: timestamp.replica_id as u32,
@ -559,6 +581,7 @@ pub fn serialize_timestamp(timestamp: clock::Lamport) -> proto::LamportTimestamp
} }
} }
/// Deserializes a [`clock::Lamport`] timestamp from the RPC representation.
pub fn deserialize_timestamp(timestamp: proto::LamportTimestamp) -> clock::Lamport { pub fn deserialize_timestamp(timestamp: proto::LamportTimestamp) -> clock::Lamport {
clock::Lamport { clock::Lamport {
replica_id: timestamp.replica_id as ReplicaId, replica_id: timestamp.replica_id as ReplicaId,
@ -566,6 +589,7 @@ pub fn deserialize_timestamp(timestamp: proto::LamportTimestamp) -> clock::Lampo
} }
} }
/// Serializes a range of [`FullOffset`]s to be sent over RPC.
pub fn serialize_range(range: &Range<FullOffset>) -> proto::Range { pub fn serialize_range(range: &Range<FullOffset>) -> proto::Range {
proto::Range { proto::Range {
start: range.start.0 as u64, start: range.start.0 as u64,
@ -573,10 +597,12 @@ pub fn serialize_range(range: &Range<FullOffset>) -> proto::Range {
} }
} }
/// Deserializes a range of [`FullOffset`]s from the RPC representation.
pub fn deserialize_range(range: proto::Range) -> Range<FullOffset> { pub fn deserialize_range(range: proto::Range) -> Range<FullOffset> {
FullOffset(range.start as usize)..FullOffset(range.end as usize) FullOffset(range.start as usize)..FullOffset(range.end as usize)
} }
/// Deserializes a clock version from the RPC representation.
pub fn deserialize_version(message: &[proto::VectorClockEntry]) -> clock::Global { pub fn deserialize_version(message: &[proto::VectorClockEntry]) -> clock::Global {
let mut version = clock::Global::new(); let mut version = clock::Global::new();
for entry in message { for entry in message {
@ -588,6 +614,7 @@ pub fn deserialize_version(message: &[proto::VectorClockEntry]) -> clock::Global
version version
} }
/// Serializes a clock version to be sent over RPC.
pub fn serialize_version(version: &clock::Global) -> Vec<proto::VectorClockEntry> { pub fn serialize_version(version: &clock::Global) -> Vec<proto::VectorClockEntry> {
version version
.iter() .iter()

View file

@ -29,7 +29,7 @@ pub struct SyntaxMap {
#[derive(Clone, Default)] #[derive(Clone, Default)]
pub struct SyntaxSnapshot { pub struct SyntaxSnapshot {
layers: SumTree<SyntaxLayer>, layers: SumTree<SyntaxLayerEntry>,
parsed_version: clock::Global, parsed_version: clock::Global,
interpolated_version: clock::Global, interpolated_version: clock::Global,
language_registry_version: usize, language_registry_version: usize,
@ -84,7 +84,7 @@ struct SyntaxMapMatchesLayer<'a> {
} }
#[derive(Clone)] #[derive(Clone)]
struct SyntaxLayer { struct SyntaxLayerEntry {
depth: usize, depth: usize,
range: Range<Anchor>, range: Range<Anchor>,
content: SyntaxLayerContent, content: SyntaxLayerContent,
@ -118,7 +118,7 @@ impl SyntaxLayerContent {
} }
#[derive(Debug)] #[derive(Debug)]
pub struct SyntaxLayerInfo<'a> { pub struct SyntaxLayer<'a> {
pub depth: usize, pub depth: usize,
pub language: &'a Arc<Language>, pub language: &'a Arc<Language>,
tree: &'a Tree, tree: &'a Tree,
@ -126,7 +126,7 @@ pub struct SyntaxLayerInfo<'a> {
} }
#[derive(Clone)] #[derive(Clone)]
pub struct OwnedSyntaxLayerInfo { pub struct OwnedSyntaxLayer {
pub depth: usize, pub depth: usize,
pub language: Arc<Language>, pub language: Arc<Language>,
tree: tree_sitter::Tree, tree: tree_sitter::Tree,
@ -691,7 +691,7 @@ impl SyntaxSnapshot {
}; };
layers.push( layers.push(
SyntaxLayer { SyntaxLayerEntry {
depth: step.depth, depth: step.depth,
range: step.range, range: step.range,
content, content,
@ -741,7 +741,7 @@ impl SyntaxSnapshot {
SyntaxMapCaptures::new( SyntaxMapCaptures::new(
range.clone(), range.clone(),
text, text,
[SyntaxLayerInfo { [SyntaxLayer {
language, language,
tree, tree,
depth: 0, depth: 0,
@ -781,7 +781,7 @@ impl SyntaxSnapshot {
} }
#[cfg(test)] #[cfg(test)]
pub fn layers<'a>(&'a self, buffer: &'a BufferSnapshot) -> Vec<SyntaxLayerInfo> { pub fn layers<'a>(&'a self, buffer: &'a BufferSnapshot) -> Vec<SyntaxLayer> {
self.layers_for_range(0..buffer.len(), buffer).collect() self.layers_for_range(0..buffer.len(), buffer).collect()
} }
@ -789,7 +789,7 @@ impl SyntaxSnapshot {
&'a self, &'a self,
range: Range<T>, range: Range<T>,
buffer: &'a BufferSnapshot, buffer: &'a BufferSnapshot,
) -> impl 'a + Iterator<Item = SyntaxLayerInfo> { ) -> impl 'a + Iterator<Item = SyntaxLayer> {
let start_offset = range.start.to_offset(buffer); let start_offset = range.start.to_offset(buffer);
let end_offset = range.end.to_offset(buffer); let end_offset = range.end.to_offset(buffer);
let start = buffer.anchor_before(start_offset); let start = buffer.anchor_before(start_offset);
@ -813,7 +813,7 @@ impl SyntaxSnapshot {
let layer_start_offset = layer.range.start.to_offset(buffer); let layer_start_offset = layer.range.start.to_offset(buffer);
let layer_start_point = layer.range.start.to_point(buffer).to_ts_point(); let layer_start_point = layer.range.start.to_point(buffer).to_ts_point();
info = Some(SyntaxLayerInfo { info = Some(SyntaxLayer {
tree, tree,
language, language,
depth: layer.depth, depth: layer.depth,
@ -842,7 +842,7 @@ impl<'a> SyntaxMapCaptures<'a> {
fn new( fn new(
range: Range<usize>, range: Range<usize>,
text: &'a Rope, text: &'a Rope,
layers: impl Iterator<Item = SyntaxLayerInfo<'a>>, layers: impl Iterator<Item = SyntaxLayer<'a>>,
query: fn(&Grammar) -> Option<&Query>, query: fn(&Grammar) -> Option<&Query>,
) -> Self { ) -> Self {
let mut result = Self { let mut result = Self {
@ -964,7 +964,7 @@ impl<'a> SyntaxMapMatches<'a> {
fn new( fn new(
range: Range<usize>, range: Range<usize>,
text: &'a Rope, text: &'a Rope,
layers: impl Iterator<Item = SyntaxLayerInfo<'a>>, layers: impl Iterator<Item = SyntaxLayer<'a>>,
query: fn(&Grammar) -> Option<&Query>, query: fn(&Grammar) -> Option<&Query>,
) -> Self { ) -> Self {
let mut result = Self::default(); let mut result = Self::default();
@ -1436,16 +1436,16 @@ fn insert_newlines_between_ranges(
} }
} }
impl OwnedSyntaxLayerInfo { impl OwnedSyntaxLayer {
pub fn node(&self) -> Node { pub fn node(&self) -> Node {
self.tree self.tree
.root_node_with_offset(self.offset.0, self.offset.1) .root_node_with_offset(self.offset.0, self.offset.1)
} }
} }
impl<'a> SyntaxLayerInfo<'a> { impl<'a> SyntaxLayer<'a> {
pub fn to_owned(&self) -> OwnedSyntaxLayerInfo { pub fn to_owned(&self) -> OwnedSyntaxLayer {
OwnedSyntaxLayerInfo { OwnedSyntaxLayer {
tree: self.tree.clone(), tree: self.tree.clone(),
offset: self.offset, offset: self.offset,
depth: self.depth, depth: self.depth,
@ -1564,7 +1564,7 @@ impl ChangeRegionSet {
) )
} }
fn intersects(&self, layer: &SyntaxLayer, text: &BufferSnapshot) -> bool { fn intersects(&self, layer: &SyntaxLayerEntry, text: &BufferSnapshot) -> bool {
for region in &self.0 { for region in &self.0 {
if region.depth < layer.depth { if region.depth < layer.depth {
continue; continue;
@ -1675,7 +1675,7 @@ impl<'a> SeekTarget<'a, SyntaxLayerSummary, SyntaxLayerSummary>
} }
} }
impl sum_tree::Item for SyntaxLayer { impl sum_tree::Item for SyntaxLayerEntry {
type Summary = SyntaxLayerSummary; type Summary = SyntaxLayerSummary;
fn summary(&self) -> Self::Summary { fn summary(&self) -> Self::Summary {
@ -1690,7 +1690,7 @@ impl sum_tree::Item for SyntaxLayer {
} }
} }
impl std::fmt::Debug for SyntaxLayer { impl std::fmt::Debug for SyntaxLayerEntry {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("SyntaxLayer") f.debug_struct("SyntaxLayer")
.field("depth", &self.depth) .field("depth", &self.depth)

View file

@ -5,7 +5,7 @@ use gpui::{
MouseButton, MouseDownEvent, MouseMoveEvent, ParentElement, Pixels, Render, Styled, MouseButton, MouseDownEvent, MouseMoveEvent, ParentElement, Pixels, Render, Styled,
UniformListScrollHandle, View, ViewContext, VisualContext, WeakView, WindowContext, UniformListScrollHandle, View, ViewContext, VisualContext, WeakView, WindowContext,
}; };
use language::{Buffer, OwnedSyntaxLayerInfo}; use language::{Buffer, OwnedSyntaxLayer};
use settings::Settings; use settings::Settings;
use std::{mem, ops::Range}; use std::{mem, ops::Range};
use theme::{ActiveTheme, ThemeSettings}; use theme::{ActiveTheme, ThemeSettings};
@ -57,7 +57,7 @@ struct EditorState {
struct BufferState { struct BufferState {
buffer: Model<Buffer>, buffer: Model<Buffer>,
excerpt_id: ExcerptId, excerpt_id: ExcerptId,
active_layer: Option<OwnedSyntaxLayerInfo>, active_layer: Option<OwnedSyntaxLayer>,
} }
impl SyntaxTreeView { impl SyntaxTreeView {
@ -491,7 +491,7 @@ impl SyntaxTreeToolbarItemView {
}) })
} }
fn render_header(active_layer: &OwnedSyntaxLayerInfo) -> ButtonLike { fn render_header(active_layer: &OwnedSyntaxLayer) -> ButtonLike {
ButtonLike::new("syntax tree header") ButtonLike::new("syntax tree header")
.child(Label::new(active_layer.language.name())) .child(Label::new(active_layer.language.name()))
.child(Label::new(format_node_range(active_layer.node()))) .child(Label::new(format_node_range(active_layer.node())))