Detailed changes
@@ -42,7 +42,13 @@ use std::{
};
use sum_tree::TreeMap;
use text::operation_queue::OperationQueue;
-pub use text::{Buffer as TextBuffer, BufferSnapshot as TextBufferSnapshot, *};
+use text::*;
+pub use text::{
+ Anchor, Bias, Buffer as TextBuffer, BufferSnapshot as TextBufferSnapshot, Edit, OffsetRangeExt,
+ OffsetUtf16, Patch, Point, PointUtf16, Rope, RopeFingerprint, Selection, SelectionGoal,
+ Subscription, TextDimension, TextSummary, ToOffset, ToOffsetUtf16, ToPoint, ToPointUtf16,
+ Transaction, TransactionId, Unclipped,
+};
use theme::SyntaxTheme;
#[cfg(any(test, feature = "test-support"))]
use util::RandomCharIter;
@@ -63,6 +69,7 @@ pub enum Capability {
ReadOnly,
}
+/// An in-memory representation of a source code file.
pub struct Buffer {
text: TextBuffer,
diff_base: Option<String>,
@@ -99,6 +106,8 @@ pub struct Buffer {
capability: Capability,
}
+/// An immutable, cheaply cloneable representation of a certain
+/// state of a buffer.
pub struct BufferSnapshot {
text: text::BufferSnapshot,
pub git_diff: git::diff::BufferDiff,
@@ -150,6 +159,7 @@ pub struct GroupId {
id: usize,
}
+/// A diagnostic associated with a certain range of a buffer.
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Diagnostic {
pub source: Option<String>,
@@ -257,6 +267,7 @@ pub enum Event {
Closed,
}
+/// The file associated with a buffer.
pub trait File: Send + Sync {
fn as_local(&self) -> Option<&dyn LocalFile>;
@@ -306,6 +317,10 @@ pub trait LocalFile: File {
);
}
+/// 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.
@@ -353,6 +368,8 @@ struct BufferChunkHighlights<'a> {
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> {
range: Range<usize>,
chunks: text::Chunks<'a>,
@@ -365,6 +382,8 @@ pub struct BufferChunks<'a> {
highlights: Option<BufferChunkHighlights<'a>>,
}
+/// A chunk of a buffer's text, along with its syntax highlight and
+/// diagnostic status.
#[derive(Clone, Copy, Debug, Default)]
pub struct Chunk<'a> {
pub text: &'a str,
@@ -375,6 +394,7 @@ pub struct Chunk<'a> {
pub is_tab: bool,
}
+/// A set of edits to a given version of a buffer, computed asynchronously.
pub struct Diff {
pub(crate) base_version: clock::Global,
line_ending: LineEnding,
@@ -407,6 +427,7 @@ impl CharKind {
}
impl Buffer {
+ /// Create a new buffer with the given base text.
pub fn new<T: Into<String>>(replica_id: ReplicaId, id: u64, base_text: T) -> Self {
Self::build(
TextBuffer::new(replica_id, id, base_text.into()),
@@ -416,6 +437,7 @@ impl Buffer {
)
}
+ /// Create a new buffer that is a replica of a remote buffer.
pub fn remote(
remote_id: u64,
replica_id: ReplicaId,
@@ -430,6 +452,8 @@ impl Buffer {
)
}
+ /// Create a new buffer that is a replica of a remote buffer, populating its
+ /// state from the given protobuf message.
pub fn from_proto(
replica_id: ReplicaId,
capability: Capability,
@@ -456,6 +480,7 @@ impl Buffer {
Ok(this)
}
+ /// Serialize the buffer's state to a protobuf message.
pub fn to_proto(&self) -> proto::BufferState {
proto::BufferState {
id: self.remote_id(),
@@ -469,6 +494,7 @@ impl Buffer {
}
}
+ /// Serialize as protobufs all of the changes to the buffer since the given version.
pub fn serialize_ops(
&self,
since: Option<clock::Global>,
@@ -515,6 +541,7 @@ impl Buffer {
})
}
+ /// Assign a language to the buffer, returning the buffer.
pub fn with_language(mut self, language: Arc<Language>, cx: &mut ModelContext<Self>) -> Self {
self.set_language(Some(language), cx);
self
@@ -572,6 +599,8 @@ impl Buffer {
}
}
+ /// Retrieve a snapshot of the buffer's current state. This is computationally
+ /// cheap, and allows reading from the buffer on a background thread.
pub fn snapshot(&self) -> BufferSnapshot {
let text = self.text.snapshot();
let mut syntax_map = self.syntax_map.lock();
@@ -594,18 +623,22 @@ impl Buffer {
}
}
- pub fn as_text_snapshot(&self) -> &text::BufferSnapshot {
+ pub(crate) fn as_text_snapshot(&self) -> &text::BufferSnapshot {
&self.text
}
+ /// Retrieve a snapshot of the buffer's raw text, without any
+ /// language-related state like the syntax tree or diagnostics.
pub fn text_snapshot(&self) -> text::BufferSnapshot {
self.text.snapshot()
}
+ /// The file associated with the buffer, if any.
pub fn file(&self) -> Option<&Arc<dyn File>> {
self.file.as_ref()
}
+ /// The version of the buffer that was last saved or reloaded from disk.
pub fn saved_version(&self) -> &clock::Global {
&self.saved_version
}
@@ -614,10 +647,12 @@ impl Buffer {
self.file_fingerprint
}
+ /// The mtime of the buffer's file when the buffer was last saved or reloaded from disk.
pub fn saved_mtime(&self) -> SystemTime {
self.saved_mtime
}
+ /// Assign a language to the buffer.
pub fn set_language(&mut self, language: Option<Arc<Language>>, cx: &mut ModelContext<Self>) {
self.syntax_map.lock().clear();
self.language = language;
@@ -625,6 +660,8 @@ impl Buffer {
cx.emit(Event::LanguageChanged);
}
+ /// Assign a language registry to the buffer. This allows the buffer to retrieve
+ /// other languages if parts of the buffer are written in different languages.
pub fn set_language_registry(&mut self, language_registry: Arc<LanguageRegistry>) {
self.syntax_map
.lock()
@@ -935,6 +972,7 @@ impl Buffer {
cx.notify();
}
+ /// Assign to the buffer a set of diagnostics created by a given language server.
pub fn update_diagnostics(
&mut self,
server_id: LanguageServerId,
@@ -1164,9 +1202,9 @@ impl Buffer {
self.edit(edits, None, cx);
}
- // Create a minimal edit that will cause the the given row to be indented
- // with the given size. After applying this edit, the length of the line
- // will always be at least `new_size.len`.
+ /// Create a minimal edit that will cause the the given row to be indented
+ /// with the given size. After applying this edit, the length of the line
+ /// will always be at least `new_size.len`.
pub fn edit_for_indent_size_adjustment(
row: u32,
current_size: IndentSize,
@@ -1201,6 +1239,8 @@ impl Buffer {
}
}
+ /// Spawns a background task that asynchronously computes a `Diff` between the buffer's text
+ /// and the given new text.
pub fn diff(&self, mut new_text: String, cx: &AppContext) -> Task<Diff> {
let old_text = self.as_rope().clone();
let base_version = self.version();
@@ -1272,7 +1312,7 @@ impl Buffer {
})
}
- /// Spawn a background task that searches the buffer for any whitespace
+ /// Spawns a background task that searches the buffer for any whitespace
/// at the ends of a lines, and returns a `Diff` that removes that whitespace.
pub fn remove_trailing_whitespace(&self, cx: &AppContext) -> Task<Diff> {
let old_text = self.as_rope().clone();
@@ -1292,7 +1332,7 @@ impl Buffer {
})
}
- /// Ensure that the buffer ends with a single newline character, and
+ /// Ensures that the buffer ends with a single newline character, and
/// no other whitespace.
pub fn ensure_final_newline(&mut self, cx: &mut ModelContext<Self>) {
let len = self.len();
@@ -1313,7 +1353,7 @@ impl Buffer {
self.edit([(offset..len, "\n")], None, cx);
}
- /// Apply a diff to the buffer. If the buffer has changed since the given diff was
+ /// Applies a diff to the buffer. If the buffer has changed since the given diff was
/// calculated, then adjust the diff to account for those changes, and discard any
/// parts of the diff that conflict with those changes.
pub fn apply_diff(&mut self, diff: Diff, cx: &mut ModelContext<Self>) -> Option<TransactionId> {
@@ -1352,11 +1392,14 @@ impl Buffer {
self.end_transaction(cx)
}
+ /// Checks if the buffer has unsaved changes.
pub fn is_dirty(&self) -> bool {
self.file_fingerprint != self.as_rope().fingerprint()
|| self.file.as_ref().map_or(false, |file| file.is_deleted())
}
+ /// Checks if the buffer and its file have both changed since the buffer
+ /// was last saved or reloaded.
pub fn has_conflict(&self) -> bool {
self.file_fingerprint != self.as_rope().fingerprint()
&& self
@@ -1365,14 +1408,23 @@ impl Buffer {
.map_or(false, |file| file.mtime() > self.saved_mtime)
}
+ /// Gets a [`Subscription`] that tracks all of the changes to the buffer's text.
pub fn subscribe(&mut self) -> Subscription {
self.text.subscribe()
}
+ /// Starts a transaction, if one is not already in-progress. When undoing or
+ /// redoing edits, all of the edits performed within a transaction are undone
+ /// or redone together.
pub fn start_transaction(&mut self) -> Option<TransactionId> {
self.start_transaction_at(Instant::now())
}
+ /// Starts a transaction, providing the current time. Subsequent transactions
+ /// that occur within a short period of time will be grouped together. This
+ /// is controlled by the buffer's undo grouping duration.
+ ///
+ /// See [`Buffer::set_group_interval`].
pub fn start_transaction_at(&mut self, now: Instant) -> Option<TransactionId> {
self.transaction_depth += 1;
if self.was_dirty_before_starting_transaction.is_none() {
@@ -1381,10 +1433,16 @@ impl Buffer {
self.text.start_transaction_at(now)
}
+ /// Terminates the current transaction, if this is the outermost transaction.
pub fn end_transaction(&mut self, cx: &mut ModelContext<Self>) -> Option<TransactionId> {
self.end_transaction_at(Instant::now(), cx)
}
+ /// Terminates the current transaction, providing the current time. Subsequent transactions
+ /// that occur within a short period of time will be grouped together. This
+ /// is controlled by the buffer's undo grouping duration.
+ ///
+ /// See [`Buffer::set_group_interval`].
pub fn end_transaction_at(
&mut self,
now: Instant,
@@ -1405,26 +1463,33 @@ impl Buffer {
}
}
+ /// Manually add a transaction to the buffer's undo history.
pub fn push_transaction(&mut self, transaction: Transaction, now: Instant) {
self.text.push_transaction(transaction, now);
}
+ /// Prevent the last transaction from being grouped with any subsequent transactions,
+ /// even if they occur with the buffer's undo grouping duration.
pub fn finalize_last_transaction(&mut self) -> Option<&Transaction> {
self.text.finalize_last_transaction()
}
+ /// Manually group all changes since a given transaction.
pub fn group_until_transaction(&mut self, transaction_id: TransactionId) {
self.text.group_until_transaction(transaction_id);
}
+ /// Manually remove a transaction from the buffer's undo history
pub fn forget_transaction(&mut self, transaction_id: TransactionId) {
self.text.forget_transaction(transaction_id);
}
+ /// Manually merge two adjacent transactions in the buffer's undo history.
pub fn merge_transactions(&mut self, transaction: TransactionId, destination: TransactionId) {
self.text.merge_transactions(transaction, destination);
}
+ /// Waits for the buffer to receive operations with the given timestamps.
pub fn wait_for_edits(
&mut self,
edit_ids: impl IntoIterator<Item = clock::Lamport>,
@@ -1432,6 +1497,7 @@ impl Buffer {
self.text.wait_for_edits(edit_ids)
}
+ /// Waits for the buffer to receive the operations necessary for resolving the given anchors.
pub fn wait_for_anchors(
&mut self,
anchors: impl IntoIterator<Item = Anchor>,
@@ -1439,14 +1505,18 @@ impl Buffer {
self.text.wait_for_anchors(anchors)
}
+ /// Waits for the buffer to receive operations up to the given version.
pub fn wait_for_version(&mut self, version: clock::Global) -> impl Future<Output = Result<()>> {
self.text.wait_for_version(version)
}
+ /// Forces all futures returned by [`Buffer::wait_for_version`], [`Buffer::wait_for_edits`], or
+ /// [`Buffer::wait_for_version`] to resolve with an error.
pub fn give_up_waiting(&mut self) {
self.text.give_up_waiting();
}
+ /// Stores a set of selections that should be broadcasted to all of the buffer's replicas.
pub fn set_active_selections(
&mut self,
selections: Arc<[Selection<Anchor>]>,
@@ -1475,6 +1545,8 @@ impl Buffer {
);
}
+ /// Clears the selections, so that other replicas of the buffer do not see any selections for
+ /// this replica.
pub fn remove_active_selections(&mut self, cx: &mut ModelContext<Self>) {
if self
.remote_selections
@@ -1485,6 +1557,7 @@ impl Buffer {
}
}
+ /// Replaces the buffer's entire text.
pub fn set_text<T>(&mut self, text: T, cx: &mut ModelContext<Self>) -> Option<clock::Lamport>
where
T: Into<Arc<str>>,
@@ -1493,6 +1566,15 @@ impl Buffer {
self.edit([(0..self.len(), text)], None, cx)
}
+ /// Applies the given edits to the buffer. Each edit is specified as a range of text to
+ /// delete, and a string of text to insert at that location.
+ ///
+ /// If an [`AutoindentMode`] is provided, then the buffer will enqueue an auto-indent
+ /// request for the edited ranges, which will be processed when the buffer finishes
+ /// parsing.
+ ///
+ /// Parsing takes place at the end of a transaction, and may compute synchronously
+ /// or asynchronously, depending on the changes.
pub fn edit<I, S, T>(
&mut self,
edits_iter: I,
@@ -1626,6 +1708,7 @@ impl Buffer {
cx.notify();
}
+ /// Applies the given remote operations to the buffer.
pub fn apply_ops<I: IntoIterator<Item = Operation>>(
&mut self,
ops: I,
@@ -1773,11 +1856,13 @@ impl Buffer {
cx.emit(Event::Operation(operation));
}
+ /// Removes the selections for a given peer.
pub fn remove_peer(&mut self, replica_id: ReplicaId, cx: &mut ModelContext<Self>) {
self.remote_selections.remove(&replica_id);
cx.notify();
}
+ /// Undoes the most recent transaction.
pub fn undo(&mut self, cx: &mut ModelContext<Self>) -> Option<TransactionId> {
let was_dirty = self.is_dirty();
let old_version = self.version.clone();
@@ -1791,6 +1876,7 @@ impl Buffer {
}
}
+ /// Manually undoes a specific transaction in the buffer's undo history.
pub fn undo_transaction(
&mut self,
transaction_id: TransactionId,
@@ -1807,6 +1893,7 @@ impl Buffer {
}
}
+ /// Manually undoes all changes after a given transaction in the buffer's undo history.
pub fn undo_to_transaction(
&mut self,
transaction_id: TransactionId,
@@ -1,3 +1,7 @@
+//! The `language` crate provides... ???
+
+#![warn(missing_docs)]
+
mod buffer;
mod diagnostic_set;
mod highlight_map;
@@ -58,6 +62,9 @@ pub use syntax_map::{OwnedSyntaxLayerInfo, SyntaxLayerInfo};
pub use text::LineEnding;
pub use tree_sitter::{Parser, Tree};
+/// Initializes the `language` crate.
+///
+/// This should be called before making use of items from the create.
pub fn init(cx: &mut AppContext) {
language_settings::init(cx);
}
@@ -90,7 +97,7 @@ thread_local! {
}
lazy_static! {
- pub static ref NEXT_GRAMMAR_ID: AtomicUsize = Default::default();
+ pub(crate) static ref NEXT_GRAMMAR_ID: AtomicUsize = Default::default();
pub static ref PLAIN_TEXT: Arc<Language> = Arc::new(Language::new(
LanguageConfig {
name: "Plain Text".into(),
@@ -358,14 +365,22 @@ pub struct CodeLabel {
#[derive(Clone, Deserialize)]
pub struct LanguageConfig {
+ /// Human-readable name of the language.
pub name: Arc<str>,
+ // The name of the grammar in a WASM bundle.
pub grammar_name: Option<Arc<str>>,
+ /// Given a list of `LanguageConfig`'s, the language of a file can be determined based on the path extension matching any of the `path_suffixes`.
pub path_suffixes: Vec<String>,
+ /// List of
pub brackets: BracketPairConfig,
+ /// A regex pattern that determines whether the language should be assigned to a file or not.
#[serde(default, deserialize_with = "deserialize_regex")]
pub first_line_pattern: Option<Regex>,
+ /// If set to true, auto indentation uses last non empty line to determine
+ /// the indentation level for a new line.
#[serde(default = "auto_indent_using_last_non_empty_line_default")]
pub auto_indent_using_last_non_empty_line: bool,
+ /// A regex that is used to determine whether the
#[serde(default, deserialize_with = "deserialize_regex")]
pub increase_indent_pattern: Option<Regex>,
#[serde(default, deserialize_with = "deserialize_regex")]
@@ -382,12 +397,16 @@ pub struct LanguageConfig {
pub scope_opt_in_language_servers: Vec<String>,
#[serde(default)]
pub overrides: HashMap<String, LanguageConfigOverride>,
+ /// A list of characters that Zed should treat as word characters for the
+ /// purpose of features that operate on word boundaries, like 'move to next word end'
+ /// or a whole-word search in buffer search.
#[serde(default)]
pub word_characters: HashSet<char>,
#[serde(default)]
pub prettier_parser_name: Option<String>,
}
+/// Tree-sitter language queries for a given language.
#[derive(Debug, Default)]
pub struct LanguageQueries {
pub highlights: Option<Cow<'static, str>>,
@@ -399,6 +418,9 @@ pub struct LanguageQueries {
pub overrides: Option<Cow<'static, str>>,
}
+/// Represents a language for the given range. Some languages (e.g. HTML)
+/// interleave several languages together, thus a single buffer might actually contain
+/// several nested scopes.
#[derive(Clone, Debug)]
pub struct LanguageScope {
language: Arc<Language>,
@@ -491,7 +513,10 @@ pub struct FakeLspAdapter {
#[derive(Clone, Debug, Default)]
pub struct BracketPairConfig {
+ /// A list of character pairs that should be treated as brackets in the context of a given language.
pub pairs: Vec<BracketPair>,
+ /// A list of tree-sitter scopes for which a given bracket should not be active.
+ /// N-th entry in `[Self::disabled_scopes_by_bracket_ix]` contains a list of disabled scopes for an n-th entry in `[Self::pairs]`
pub disabled_scopes_by_bracket_ix: Vec<Vec<String>>,
}
@@ -1641,6 +1666,8 @@ impl LanguageScope {
self.language.config.collapsed_placeholder.as_ref()
}
+ /// Returns line prefix that is inserted in e.g. line continuations or
+ /// in `toggle comments` action.
pub fn line_comment_prefix(&self) -> Option<&Arc<str>> {
Override::as_option(
self.config_override().map(|o| &o.line_comment),
@@ -1656,6 +1683,11 @@ impl LanguageScope {
.map(|e| (&e.0, &e.1))
}
+ /// Returns a list of language-specific word characters.
+ ///
+ /// By default, Zed treats alphanumeric characters (and '_') as word characters for
+ /// the purpose of actions like 'move to next word end` or whole-word search.
+ /// It additionally accounts for language's additional word characters.
pub fn word_characters(&self) -> Option<&HashSet<char>> {
Override::as_option(
self.config_override().map(|o| &o.word_characters),
@@ -1663,6 +1695,8 @@ impl LanguageScope {
)
}
+ /// Returns a list of bracket pairs for a given language with an additional
+ /// piece of information about whether the particular bracket pair is currently active for a given language.
pub fn brackets(&self) -> impl Iterator<Item = (&BracketPair, bool)> {
let mut disabled_ids = self
.config_override()
@@ -1,3 +1,5 @@
+//! Provides `language`-related settings.
+
use crate::{File, Language};
use anyhow::Result;
use collections::{HashMap, HashSet};
@@ -11,10 +13,12 @@ use serde::{Deserialize, Serialize};
use settings::Settings;
use std::{num::NonZeroU32, path::Path, sync::Arc};
-pub fn init(cx: &mut AppContext) {
+/// Initializes the language settings.
+pub(crate) fn init(cx: &mut AppContext) {
AllLanguageSettings::register(cx);
}
+/// Returns the settings for the specified language from the provided file.
pub fn language_settings<'a>(
language: Option<&Arc<Language>>,
file: Option<&Arc<dyn File>>,
@@ -24,6 +28,7 @@ pub fn language_settings<'a>(
all_language_settings(file, cx).language(language_name.as_deref())
}
+/// Returns the settings for all languages from the provided file.
pub fn all_language_settings<'a>(
file: Option<&Arc<dyn File>>,
cx: &'a AppContext,
@@ -32,36 +37,68 @@ pub fn all_language_settings<'a>(
AllLanguageSettings::get(location, cx)
}
+/// The settings for all languages.
#[derive(Debug, Clone)]
pub struct AllLanguageSettings {
+ /// The settings for GitHub Copilot.
pub copilot: CopilotSettings,
defaults: LanguageSettings,
languages: HashMap<Arc<str>, LanguageSettings>,
}
+/// The settings for a particular language.
#[derive(Debug, Clone, Deserialize)]
pub struct LanguageSettings {
+ /// How many columns a tab should occupy.
pub tab_size: NonZeroU32,
+ /// Whether to indent lines using tab characters, as opposed to multiple
+ /// spaces.
pub hard_tabs: bool,
+ /// How to soft-wrap long lines of text.
pub soft_wrap: SoftWrap,
+ /// The column at which to soft-wrap lines, for buffers where soft-wrap
+ /// is enabled.
pub preferred_line_length: u32,
+ /// Whether to show wrap guides in the editor. Setting this to true will
+ /// show a guide at the 'preferred_line_length' value if softwrap is set to
+ /// 'preferred_line_length', and will show any additional guides as specified
+ /// by the 'wrap_guides' setting.
pub show_wrap_guides: bool,
+ /// Character counts at which to show wrap guides in the editor.
pub wrap_guides: Vec<usize>,
+ /// Whether or not to perform a buffer format before saving.
pub format_on_save: FormatOnSave,
+ /// Whether or not to remove any trailing whitespace from lines of a buffer
+ /// before saving it.
pub remove_trailing_whitespace_on_save: bool,
+ /// Whether or not to ensure there's a single newline at the end of a buffer
+ /// when saving it.
pub ensure_final_newline_on_save: bool,
+ /// How to perform a buffer format.
pub formatter: Formatter,
+ /// Zed's Prettier integration settings.
+ /// If Prettier is enabled, Zed will use this its Prettier instance for any applicable file, if
+ /// the project has no other Prettier installed.
pub prettier: HashMap<String, serde_json::Value>,
+ /// Whether to use language servers to provide code intelligence.
pub enable_language_server: bool,
+ /// Controls whether Copilot provides suggestion immediately (true)
+ /// or waits for a `copilot::Toggle` (false).
pub show_copilot_suggestions: bool,
+ /// Whether to show tabs and spaces in the editor.
pub show_whitespaces: ShowWhitespaceSetting,
+ /// Whether to start a new line with a comment when a previous line is a comment as well.
pub extend_comment_on_newline: bool,
+ /// Inlay hint related settings.
pub inlay_hints: InlayHintSettings,
}
+/// The settings for [GitHub Copilot](https://github.com/features/copilot).
#[derive(Clone, Debug, Default)]
pub struct CopilotSettings {
+ /// Whether Copilit is enabled.
pub feature_enabled: bool,
+ /// A list of globs representing files that Copilot should be disabled for.
pub disabled_globs: Vec<GlobMatcher>,
}
@@ -138,7 +175,7 @@ pub struct LanguageSettingsContent {
pub formatter: Option<Formatter>,
/// Zed's Prettier integration settings.
/// If Prettier is enabled, Zed will use this its Prettier instance for any applicable file, if
- /// project has no other Prettier installed.
+ /// the project has no other Prettier installed.
///
/// Default: {}
#[serde(default)]
@@ -148,7 +185,7 @@ pub struct LanguageSettingsContent {
/// Default: true
#[serde(default)]
pub enable_language_server: Option<bool>,
- /// Controls whether copilot provides suggestion immediately (true)
+ /// Controls whether Copilot provides suggestion immediately (true)
/// or waits for a `copilot::Toggle` (false).
///
/// Default: true
@@ -176,9 +213,11 @@ pub struct CopilotSettingsContent {
#[derive(Clone, Default, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub struct FeaturesContent {
+ /// Whether the GitHub Copilot feature is enabled.
pub copilot: Option<bool>,
}
+/// Controls the soft-wrapping behavior in the editor.
#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum SoftWrap {
@@ -190,14 +229,20 @@ pub enum SoftWrap {
PreferredLineLength,
}
+/// Controls the behavior of formatting files when they are saved.
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum FormatOnSave {
+ /// Files should be formatted on save.
On,
+ /// Files should not be formatted on save.
Off,
LanguageServer,
+ /// The external program to use to format the files on save.
External {
+ /// The external program to run.
command: Arc<str>,
+ /// The arguments to pass to the program.
arguments: Arc<[String]>,
},
}
@@ -231,6 +276,7 @@ pub enum Formatter {
},
}
+/// The settings for inlay hints.
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
pub struct InlayHintSettings {
/// Global switch to toggle hints on and off.
@@ -238,10 +284,19 @@ pub struct InlayHintSettings {
/// Default: false
#[serde(default)]
pub enabled: bool,
+ /// Whether type hints should be shown.
+ ///
+ /// Default: true
#[serde(default = "default_true")]
pub show_type_hints: bool,
+ /// Whether parameter hints should be shown.
+ ///
+ /// Default: true
#[serde(default = "default_true")]
pub show_parameter_hints: bool,
+ /// Whether other hints should be shown.
+ ///
+ /// Default: true
#[serde(default = "default_true")]
pub show_other_hints: bool,
}
@@ -251,6 +306,7 @@ fn default_true() -> bool {
}
impl InlayHintSettings {
+ /// Returns the kinds of inlay hints that are enabled based on the settings.
pub fn enabled_inlay_hint_kinds(&self) -> HashSet<Option<InlayHintKind>> {
let mut kinds = HashSet::default();
if self.show_type_hints {
@@ -1,3 +1,5 @@
+//! Provides Markdown-related constructs.
+
use std::sync::Arc;
use std::{ops::Range, path::PathBuf};
@@ -5,21 +7,30 @@ use crate::{HighlightId, Language, LanguageRegistry};
use gpui::{px, FontStyle, FontWeight, HighlightStyle, UnderlineStyle};
use pulldown_cmark::{CodeBlockKind, Event, Options, Parser, Tag};
+/// Parsed Markdown content.
#[derive(Debug, Clone)]
pub struct ParsedMarkdown {
+ /// The Markdown text.
pub text: String,
+ /// The list of highlights contained in the Markdown document.
pub highlights: Vec<(Range<usize>, MarkdownHighlight)>,
+ /// The regions of the various ranges in the Markdown document.
pub region_ranges: Vec<Range<usize>>,
+ /// The regions of the Markdown document.
pub regions: Vec<ParsedRegion>,
}
+/// A run of highlighted Markdown text.
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum MarkdownHighlight {
+ /// A styled Markdown highlight.
Style(MarkdownHighlightStyle),
+ /// A highlighted code block.
Code(HighlightId),
}
impl MarkdownHighlight {
+ /// Converts this [`MarkdownHighlight`] to a [`HighlightStyle`].
pub fn to_highlight_style(&self, theme: &theme::SyntaxTheme) -> Option<HighlightStyle> {
match self {
MarkdownHighlight::Style(style) => {
@@ -48,23 +59,39 @@ impl MarkdownHighlight {
}
}
+/// The style for a Markdown highlight.
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct MarkdownHighlightStyle {
+ /// Whether the text should be italicized.
pub italic: bool,
+ /// Whether the text should be underlined.
pub underline: bool,
+ /// The weight of the text.
pub weight: FontWeight,
}
+/// A parsed region in a Markdown document.
#[derive(Debug, Clone)]
pub struct ParsedRegion {
+ /// Whether the region is a code block.
pub code: bool,
+ /// The link contained in this region, if it has one.
pub link: Option<Link>,
}
+/// A Markdown link.
#[derive(Debug, Clone)]
pub enum Link {
- Web { url: String },
- Path { path: PathBuf },
+ /// A link to a webpage.
+ Web {
+ /// The URL of the webpage.
+ url: String,
+ },
+ /// A link to a path on the filesystem.
+ Path {
+ /// The path to the item.
+ path: PathBuf,
+ },
}
impl Link {
@@ -82,6 +109,7 @@ impl Link {
}
}
+/// Parses a string of Markdown.
pub async fn parse_markdown(
markdown: &str,
language_registry: &Arc<LanguageRegistry>,
@@ -111,6 +139,7 @@ pub async fn parse_markdown(
}
}
+/// Parses a Markdown block.
pub async fn parse_markdown_block(
markdown: &str,
language_registry: &Arc<LanguageRegistry>,
@@ -261,6 +290,7 @@ pub async fn parse_markdown_block(
}
}
+/// Appends a highlighted run of text to the provided `text` buffer.
pub fn highlight_code(
text: &mut String,
highlights: &mut Vec<(Range<usize>, MarkdownHighlight)>,
@@ -275,6 +305,7 @@ pub fn highlight_code(
}
}
+/// Appends a new paragraph to the provided `text` buffer.
pub fn new_paragraph(text: &mut String, list_stack: &mut Vec<(Option<u64>, bool)>) {
let mut is_subsequent_paragraph_of_list = false;
if let Some((_, has_content)) = list_stack.last_mut() {
@@ -1,3 +1,5 @@
+//! Handles conversions of `language` items to and from the [`rpc`] protocol.
+
use crate::{
diagnostic_set::DiagnosticEntry, CodeAction, CodeLabel, Completion, CursorShape, Diagnostic,
Language,
@@ -11,15 +13,18 @@ use text::*;
pub use proto::{BufferState, Operation};
+/// Serializes a [`RopeFingerprint`] to be sent over the wire.
pub fn serialize_fingerprint(fingerprint: RopeFingerprint) -> String {
fingerprint.to_hex()
}
+/// Deserializes a [`RopeFingerprint`] from the wire format.
pub fn deserialize_fingerprint(fingerprint: &str) -> Result<RopeFingerprint> {
RopeFingerprint::from_hex(fingerprint)
.map_err(|error| anyhow!("invalid fingerprint: {}", error))
}
+/// Deserializes a `[text::LineEnding]` from the wire format.
pub fn deserialize_line_ending(message: proto::LineEnding) -> text::LineEnding {
match message {
proto::LineEnding::Unix => text::LineEnding::Unix,
@@ -27,6 +32,7 @@ pub fn deserialize_line_ending(message: proto::LineEnding) -> text::LineEnding {
}
}
+/// Serializes a [`text::LineEnding`] to be sent over the wire.
pub fn serialize_line_ending(message: text::LineEnding) -> proto::LineEnding {
match message {
text::LineEnding::Unix => proto::LineEnding::Unix,
@@ -34,6 +40,7 @@ pub fn serialize_line_ending(message: text::LineEnding) -> proto::LineEnding {
}
}
+/// Serializes a [`crate::Operation`] to be sent over the wire.
pub fn serialize_operation(operation: &crate::Operation) -> proto::Operation {
proto::Operation {
variant: Some(match operation {
@@ -96,6 +103,7 @@ pub fn serialize_operation(operation: &crate::Operation) -> proto::Operation {
}
}
+/// Serializes an [`operation::EditOperation`] to be sent over the wire.
pub fn serialize_edit_operation(operation: &EditOperation) -> proto::operation::Edit {
proto::operation::Edit {
replica_id: operation.timestamp.replica_id as u32,
@@ -110,6 +118,7 @@ pub fn serialize_edit_operation(operation: &EditOperation) -> proto::operation::
}
}
+/// Serializes an entry in the undo map to be sent over the wire.
pub fn serialize_undo_map_entry(
(edit_id, counts): (&clock::Lamport, &[(clock::Lamport, u32)]),
) -> proto::UndoMapEntry {