WIP and merge
This commit is contained in:
parent
97f4406ef6
commit
1bdde8b2e4
584 changed files with 33536 additions and 17400 deletions
|
@ -20,6 +20,7 @@ test-support = [
|
|||
"text/test-support",
|
||||
"tree-sitter-rust",
|
||||
"tree-sitter-python",
|
||||
"tree-sitter-rust",
|
||||
"tree-sitter-typescript",
|
||||
"settings/test-support",
|
||||
"util/test-support",
|
||||
|
|
|
@ -1,12 +1,6 @@
|
|||
pub use crate::{
|
||||
Grammar, Language, LanguageRegistry,
|
||||
diagnostic_set::DiagnosticSet,
|
||||
highlight_map::{HighlightId, HighlightMap},
|
||||
proto,
|
||||
};
|
||||
use crate::{
|
||||
LanguageScope, Outline, OutlineConfig, RunnableCapture, RunnableTag, TextObject,
|
||||
TreeSitterOptions,
|
||||
DebuggerTextObject, LanguageScope, Outline, OutlineConfig, RunnableCapture, RunnableTag,
|
||||
TextObject, TreeSitterOptions,
|
||||
diagnostic_set::{DiagnosticEntry, DiagnosticGroup},
|
||||
language_settings::{LanguageSettings, language_settings},
|
||||
outline::OutlineItem,
|
||||
|
@ -17,6 +11,12 @@ use crate::{
|
|||
task_context::RunnableRange,
|
||||
text_diff::text_diff,
|
||||
};
|
||||
pub use crate::{
|
||||
Grammar, Language, LanguageRegistry,
|
||||
diagnostic_set::DiagnosticSet,
|
||||
highlight_map::{HighlightId, HighlightMap},
|
||||
proto,
|
||||
};
|
||||
use anyhow::{Context as _, Result};
|
||||
pub use clock::ReplicaId;
|
||||
use clock::{AGENT_REPLICA_ID, Lamport};
|
||||
|
@ -107,6 +107,7 @@ pub struct Buffer {
|
|||
reload_task: Option<Task<Result<()>>>,
|
||||
language: Option<Arc<Language>>,
|
||||
autoindent_requests: Vec<Arc<AutoindentRequest>>,
|
||||
wait_for_autoindent_txs: Vec<oneshot::Sender<()>>,
|
||||
pending_autoindent: Option<Task<()>>,
|
||||
sync_parse_timeout: Duration,
|
||||
syntax_map: Mutex<SyntaxMap>,
|
||||
|
@ -949,6 +950,7 @@ impl Buffer {
|
|||
sync_parse_timeout: Duration::from_millis(1),
|
||||
parse_status: watch::channel(ParseStatus::Idle),
|
||||
autoindent_requests: Default::default(),
|
||||
wait_for_autoindent_txs: Default::default(),
|
||||
pending_autoindent: Default::default(),
|
||||
language: None,
|
||||
remote_selections: Default::default(),
|
||||
|
@ -1454,7 +1456,7 @@ impl Buffer {
|
|||
self.syntax_map.lock().contains_unknown_injections()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
pub fn set_sync_parse_timeout(&mut self, timeout: Duration) {
|
||||
self.sync_parse_timeout = timeout;
|
||||
}
|
||||
|
@ -1605,6 +1607,9 @@ impl Buffer {
|
|||
}
|
||||
} else {
|
||||
self.autoindent_requests.clear();
|
||||
for tx in self.wait_for_autoindent_txs.drain(..) {
|
||||
tx.send(()).ok();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1786,6 +1791,9 @@ impl Buffer {
|
|||
cx: &mut Context<Self>,
|
||||
) {
|
||||
self.autoindent_requests.clear();
|
||||
for tx in self.wait_for_autoindent_txs.drain(..) {
|
||||
tx.send(()).ok();
|
||||
}
|
||||
|
||||
let edits: Vec<_> = indent_sizes
|
||||
.into_iter()
|
||||
|
@ -2125,6 +2133,16 @@ impl Buffer {
|
|||
self.text.give_up_waiting();
|
||||
}
|
||||
|
||||
pub fn wait_for_autoindent_applied(&mut self) -> Option<oneshot::Receiver<()>> {
|
||||
let mut rx = None;
|
||||
if !self.autoindent_requests.is_empty() {
|
||||
let channel = oneshot::channel();
|
||||
self.wait_for_autoindent_txs.push(channel.0);
|
||||
rx = Some(channel.1);
|
||||
}
|
||||
rx
|
||||
}
|
||||
|
||||
/// Stores a set of selections that should be broadcasted to all of the buffer's replicas.
|
||||
pub fn set_active_selections(
|
||||
&mut self,
|
||||
|
@ -3835,6 +3853,74 @@ impl BufferSnapshot {
|
|||
.filter(|pair| !pair.newline_only)
|
||||
}
|
||||
|
||||
pub fn debug_variables_query<T: ToOffset>(
|
||||
&self,
|
||||
range: Range<T>,
|
||||
) -> impl Iterator<Item = (Range<usize>, DebuggerTextObject)> + '_ {
|
||||
let range = range.start.to_offset(self).saturating_sub(1)
|
||||
..self.len().min(range.end.to_offset(self) + 1);
|
||||
|
||||
let mut matches = self.syntax.matches_with_options(
|
||||
range.clone(),
|
||||
&self.text,
|
||||
TreeSitterOptions::default(),
|
||||
|grammar| grammar.debug_variables_config.as_ref().map(|c| &c.query),
|
||||
);
|
||||
|
||||
let configs = matches
|
||||
.grammars()
|
||||
.iter()
|
||||
.map(|grammar| grammar.debug_variables_config.as_ref())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let mut captures = Vec::<(Range<usize>, DebuggerTextObject)>::new();
|
||||
|
||||
iter::from_fn(move || {
|
||||
loop {
|
||||
while let Some(capture) = captures.pop() {
|
||||
if capture.0.overlaps(&range) {
|
||||
return Some(capture);
|
||||
}
|
||||
}
|
||||
|
||||
let mat = matches.peek()?;
|
||||
|
||||
let Some(config) = configs[mat.grammar_index].as_ref() else {
|
||||
matches.advance();
|
||||
continue;
|
||||
};
|
||||
|
||||
for capture in mat.captures {
|
||||
let Some(ix) = config
|
||||
.objects_by_capture_ix
|
||||
.binary_search_by_key(&capture.index, |e| e.0)
|
||||
.ok()
|
||||
else {
|
||||
continue;
|
||||
};
|
||||
let text_object = config.objects_by_capture_ix[ix].1;
|
||||
let byte_range = capture.node.byte_range();
|
||||
|
||||
let mut found = false;
|
||||
for (range, existing) in captures.iter_mut() {
|
||||
if existing == &text_object {
|
||||
range.start = range.start.min(byte_range.start);
|
||||
range.end = range.end.max(byte_range.end);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
captures.push((byte_range, text_object));
|
||||
}
|
||||
}
|
||||
|
||||
matches.advance();
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn text_object_ranges<T: ToOffset>(
|
||||
&self,
|
||||
range: Range<T>,
|
||||
|
@ -4273,6 +4359,11 @@ impl BufferSnapshot {
|
|||
self.non_text_state_update_count
|
||||
}
|
||||
|
||||
/// An integer version that changes when the buffer's syntax changes.
|
||||
pub fn syntax_update_count(&self) -> usize {
|
||||
self.syntax.update_count()
|
||||
}
|
||||
|
||||
/// Returns a snapshot of underlying file.
|
||||
pub fn file(&self) -> Option<&Arc<dyn File>> {
|
||||
self.file.as_ref()
|
||||
|
|
|
@ -32,7 +32,9 @@ use futures::Future;
|
|||
use gpui::{App, AsyncApp, Entity, SharedString, Task};
|
||||
pub use highlight_map::HighlightMap;
|
||||
use http_client::HttpClient;
|
||||
pub use language_registry::{LanguageName, LoadedLanguage};
|
||||
pub use language_registry::{
|
||||
LanguageName, LanguageServerStatusUpdate, LoadedLanguage, ServerHealth,
|
||||
};
|
||||
use lsp::{CodeActionKind, InitializeParams, LanguageServerBinary, LanguageServerBinaryOptions};
|
||||
pub use manifest::{ManifestDelegate, ManifestName, ManifestProvider, ManifestQuery};
|
||||
use parking_lot::Mutex;
|
||||
|
@ -1080,6 +1082,7 @@ pub struct Grammar {
|
|||
pub embedding_config: Option<EmbeddingConfig>,
|
||||
pub(crate) injection_config: Option<InjectionConfig>,
|
||||
pub(crate) override_config: Option<OverrideConfig>,
|
||||
pub(crate) debug_variables_config: Option<DebugVariablesConfig>,
|
||||
pub(crate) highlight_map: Mutex<HighlightMap>,
|
||||
}
|
||||
|
||||
|
@ -1102,6 +1105,22 @@ pub struct OutlineConfig {
|
|||
pub annotation_capture_ix: Option<u32>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub enum DebuggerTextObject {
|
||||
Variable,
|
||||
Scope,
|
||||
}
|
||||
|
||||
impl DebuggerTextObject {
|
||||
pub fn from_capture_name(name: &str) -> Option<DebuggerTextObject> {
|
||||
match name {
|
||||
"debug-variable" => Some(DebuggerTextObject::Variable),
|
||||
"debug-scope" => Some(DebuggerTextObject::Scope),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub enum TextObject {
|
||||
InsideFunction,
|
||||
|
@ -1204,6 +1223,11 @@ struct BracketsPatternConfig {
|
|||
newline_only: bool,
|
||||
}
|
||||
|
||||
pub struct DebugVariablesConfig {
|
||||
pub query: Query,
|
||||
pub objects_by_capture_ix: Vec<(u32, DebuggerTextObject)>,
|
||||
}
|
||||
|
||||
impl Language {
|
||||
pub fn new(config: LanguageConfig, ts_language: Option<tree_sitter::Language>) -> Self {
|
||||
Self::new_with_id(LanguageId::new(), config, ts_language)
|
||||
|
@ -1235,6 +1259,7 @@ impl Language {
|
|||
redactions_config: None,
|
||||
runnable_config: None,
|
||||
error_query: Query::new(&ts_language, "(ERROR) @error").ok(),
|
||||
debug_variables_config: None,
|
||||
ts_language,
|
||||
highlight_map: Default::default(),
|
||||
})
|
||||
|
@ -1305,6 +1330,11 @@ impl Language {
|
|||
.with_text_object_query(query.as_ref())
|
||||
.context("Error loading textobject query")?;
|
||||
}
|
||||
if let Some(query) = queries.debugger {
|
||||
self = self
|
||||
.with_debug_variables_query(query.as_ref())
|
||||
.context("Error loading debug variables query")?;
|
||||
}
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
|
@ -1423,6 +1453,24 @@ impl Language {
|
|||
Ok(self)
|
||||
}
|
||||
|
||||
pub fn with_debug_variables_query(mut self, source: &str) -> Result<Self> {
|
||||
let grammar = self.grammar_mut().context("cannot mutate grammar")?;
|
||||
let query = Query::new(&grammar.ts_language, source)?;
|
||||
|
||||
let mut objects_by_capture_ix = Vec::new();
|
||||
for (ix, name) in query.capture_names().iter().enumerate() {
|
||||
if let Some(text_object) = DebuggerTextObject::from_capture_name(name) {
|
||||
objects_by_capture_ix.push((ix as u32, text_object));
|
||||
}
|
||||
}
|
||||
|
||||
grammar.debug_variables_config = Some(DebugVariablesConfig {
|
||||
query,
|
||||
objects_by_capture_ix,
|
||||
});
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
pub fn with_brackets_query(mut self, source: &str) -> Result<Self> {
|
||||
let grammar = self.grammar_mut().context("cannot mutate grammar")?;
|
||||
let query = Query::new(&grammar.ts_language, source)?;
|
||||
|
@ -1928,6 +1976,10 @@ impl Grammar {
|
|||
.capture_index_for_name(name)?;
|
||||
Some(self.highlight_map.lock().get(capture_id))
|
||||
}
|
||||
|
||||
pub fn debug_variables_config(&self) -> Option<&DebugVariablesConfig> {
|
||||
self.debug_variables_config.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
impl CodeLabel {
|
||||
|
@ -1980,25 +2032,27 @@ impl CodeLabel {
|
|||
} else {
|
||||
label.clone()
|
||||
};
|
||||
let filter_range = item
|
||||
.filter_text
|
||||
.as_deref()
|
||||
.and_then(|filter| text.find(filter).map(|ix| ix..ix + filter.len()))
|
||||
.unwrap_or(0..label_length);
|
||||
Self {
|
||||
text,
|
||||
runs,
|
||||
filter_range: 0..label_length,
|
||||
filter_range,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn plain(text: String, filter_text: Option<&str>) -> Self {
|
||||
let mut result = Self {
|
||||
let filter_range = filter_text
|
||||
.and_then(|filter| text.find(filter).map(|ix| ix..ix + filter.len()))
|
||||
.unwrap_or(0..text.len());
|
||||
Self {
|
||||
runs: Vec::new(),
|
||||
filter_range: 0..text.len(),
|
||||
filter_range,
|
||||
text,
|
||||
};
|
||||
if let Some(filter_text) = filter_text {
|
||||
if let Some(ix) = result.text.find(filter_text) {
|
||||
result.filter_range = ix..ix + filter_text.len();
|
||||
}
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
pub fn push_str(&mut self, text: &str, highlight: Option<HighlightId>) {
|
||||
|
|
|
@ -107,7 +107,7 @@ pub struct LanguageRegistry {
|
|||
state: RwLock<LanguageRegistryState>,
|
||||
language_server_download_dir: Option<Arc<Path>>,
|
||||
executor: BackgroundExecutor,
|
||||
lsp_binary_status_tx: BinaryStatusSender,
|
||||
lsp_binary_status_tx: ServerStatusSender,
|
||||
}
|
||||
|
||||
struct LanguageRegistryState {
|
||||
|
@ -138,11 +138,28 @@ pub struct FakeLanguageServerEntry {
|
|||
pub _server: Option<lsp::FakeLanguageServer>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub enum LanguageServerStatusUpdate {
|
||||
Binary(BinaryStatus),
|
||||
Health(ServerHealth, Option<SharedString>),
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Deserialize, Serialize, Clone, Copy)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub enum ServerHealth {
|
||||
Ok,
|
||||
Warning,
|
||||
Error,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub enum BinaryStatus {
|
||||
None,
|
||||
CheckingForUpdate,
|
||||
Downloading,
|
||||
Starting,
|
||||
Stopping,
|
||||
Stopped,
|
||||
Failed { error: String },
|
||||
}
|
||||
|
||||
|
@ -212,7 +229,7 @@ pub const QUERY_FILENAME_PREFIXES: &[(
|
|||
("overrides", |q| &mut q.overrides),
|
||||
("redactions", |q| &mut q.redactions),
|
||||
("runnables", |q| &mut q.runnables),
|
||||
("debug_variables", |q| &mut q.debug_variables),
|
||||
("debugger", |q| &mut q.debugger),
|
||||
("textobjects", |q| &mut q.text_objects),
|
||||
];
|
||||
|
||||
|
@ -229,12 +246,12 @@ pub struct LanguageQueries {
|
|||
pub redactions: Option<Cow<'static, str>>,
|
||||
pub runnables: Option<Cow<'static, str>>,
|
||||
pub text_objects: Option<Cow<'static, str>>,
|
||||
pub debug_variables: Option<Cow<'static, str>>,
|
||||
pub debugger: Option<Cow<'static, str>>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
struct BinaryStatusSender {
|
||||
txs: Arc<Mutex<Vec<mpsc::UnboundedSender<(SharedString, BinaryStatus)>>>>,
|
||||
struct ServerStatusSender {
|
||||
txs: Arc<Mutex<Vec<mpsc::UnboundedSender<(LanguageServerName, BinaryStatus)>>>>,
|
||||
}
|
||||
|
||||
pub struct LoadedLanguage {
|
||||
|
@ -1071,8 +1088,8 @@ impl LanguageRegistry {
|
|||
self.state.read().all_lsp_adapters.get(name).cloned()
|
||||
}
|
||||
|
||||
pub fn update_lsp_status(&self, server_name: LanguageServerName, status: BinaryStatus) {
|
||||
self.lsp_binary_status_tx.send(server_name.0, status);
|
||||
pub fn update_lsp_binary_status(&self, server_name: LanguageServerName, status: BinaryStatus) {
|
||||
self.lsp_binary_status_tx.send(server_name, status);
|
||||
}
|
||||
|
||||
pub fn next_language_server_id(&self) -> LanguageServerId {
|
||||
|
@ -1127,7 +1144,7 @@ impl LanguageRegistry {
|
|||
|
||||
pub fn language_server_binary_statuses(
|
||||
&self,
|
||||
) -> mpsc::UnboundedReceiver<(SharedString, BinaryStatus)> {
|
||||
) -> mpsc::UnboundedReceiver<(LanguageServerName, BinaryStatus)> {
|
||||
self.lsp_binary_status_tx.subscribe()
|
||||
}
|
||||
|
||||
|
@ -1241,14 +1258,14 @@ impl LanguageRegistryState {
|
|||
}
|
||||
}
|
||||
|
||||
impl BinaryStatusSender {
|
||||
fn subscribe(&self) -> mpsc::UnboundedReceiver<(SharedString, BinaryStatus)> {
|
||||
impl ServerStatusSender {
|
||||
fn subscribe(&self) -> mpsc::UnboundedReceiver<(LanguageServerName, BinaryStatus)> {
|
||||
let (tx, rx) = mpsc::unbounded();
|
||||
self.txs.lock().push(tx);
|
||||
rx
|
||||
}
|
||||
|
||||
fn send(&self, name: SharedString, status: BinaryStatus) {
|
||||
fn send(&self, name: LanguageServerName, status: BinaryStatus) {
|
||||
let mut txs = self.txs.lock();
|
||||
txs.retain(|tx| tx.unbounded_send((name.clone(), status.clone())).is_ok());
|
||||
}
|
||||
|
|
|
@ -288,6 +288,8 @@ pub struct CopilotSettings {
|
|||
pub proxy: Option<String>,
|
||||
/// Disable certificate verification for proxy (not recommended).
|
||||
pub proxy_no_verify: Option<bool>,
|
||||
/// Enterprise URI for Copilot.
|
||||
pub enterprise_uri: Option<String>,
|
||||
}
|
||||
|
||||
/// The settings for all languages.
|
||||
|
@ -607,6 +609,11 @@ pub struct CopilotSettingsContent {
|
|||
/// Default: false
|
||||
#[serde(default)]
|
||||
pub proxy_no_verify: Option<bool>,
|
||||
/// Enterprise URI for Copilot.
|
||||
///
|
||||
/// Default: none
|
||||
#[serde(default)]
|
||||
pub enterprise_uri: Option<String>,
|
||||
}
|
||||
|
||||
/// The settings for enabling/disabling features.
|
||||
|
@ -1228,10 +1235,10 @@ impl settings::Settings for AllLanguageSettings {
|
|||
let mut copilot_settings = default_value
|
||||
.edit_predictions
|
||||
.as_ref()
|
||||
.map(|settings| settings.copilot.clone())
|
||||
.map(|copilot| CopilotSettings {
|
||||
proxy: copilot.proxy,
|
||||
proxy_no_verify: copilot.proxy_no_verify,
|
||||
.map(|settings| CopilotSettings {
|
||||
proxy: settings.copilot.proxy.clone(),
|
||||
proxy_no_verify: settings.copilot.proxy_no_verify,
|
||||
enterprise_uri: settings.copilot.enterprise_uri.clone(),
|
||||
})
|
||||
.unwrap_or_default();
|
||||
|
||||
|
@ -1287,6 +1294,14 @@ impl settings::Settings for AllLanguageSettings {
|
|||
copilot_settings.proxy_no_verify = Some(proxy_no_verify);
|
||||
}
|
||||
|
||||
if let Some(enterprise_uri) = user_settings
|
||||
.edit_predictions
|
||||
.as_ref()
|
||||
.and_then(|settings| settings.copilot.enterprise_uri.clone())
|
||||
{
|
||||
copilot_settings.enterprise_uri = Some(enterprise_uri);
|
||||
}
|
||||
|
||||
// A user's global settings override the default global settings and
|
||||
// all default language-specific settings.
|
||||
merge_settings(&mut defaults, &user_settings.defaults);
|
||||
|
|
|
@ -122,6 +122,7 @@ impl<T> Outline<T> {
|
|||
},
|
||||
query,
|
||||
smart_case,
|
||||
true,
|
||||
100,
|
||||
&Default::default(),
|
||||
executor.clone(),
|
||||
|
|
|
@ -11,6 +11,8 @@ use text::*;
|
|||
|
||||
pub use proto::{BufferState, File, Operation};
|
||||
|
||||
use super::{point_from_lsp, point_to_lsp};
|
||||
|
||||
/// Deserializes a `[text::LineEnding]` from the RPC representation.
|
||||
pub fn deserialize_line_ending(message: proto::LineEnding) -> text::LineEnding {
|
||||
match message {
|
||||
|
@ -582,3 +584,33 @@ pub fn serialize_version(version: &clock::Global) -> Vec<proto::VectorClockEntry
|
|||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn serialize_lsp_edit(edit: lsp::TextEdit) -> proto::TextEdit {
|
||||
let start = point_from_lsp(edit.range.start).0;
|
||||
let end = point_from_lsp(edit.range.end).0;
|
||||
proto::TextEdit {
|
||||
new_text: edit.new_text,
|
||||
lsp_range_start: Some(proto::PointUtf16 {
|
||||
row: start.row,
|
||||
column: start.column,
|
||||
}),
|
||||
lsp_range_end: Some(proto::PointUtf16 {
|
||||
row: end.row,
|
||||
column: end.column,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn deserialize_lsp_edit(edit: proto::TextEdit) -> Option<lsp::TextEdit> {
|
||||
let start = edit.lsp_range_start?;
|
||||
let start = PointUtf16::new(start.row, start.column);
|
||||
let end = edit.lsp_range_end?;
|
||||
let end = PointUtf16::new(end.row, end.column);
|
||||
Some(lsp::TextEdit {
|
||||
range: lsp::Range {
|
||||
start: point_to_lsp(start),
|
||||
end: point_to_lsp(end),
|
||||
},
|
||||
new_text: edit.new_text,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ pub struct SyntaxSnapshot {
|
|||
parsed_version: clock::Global,
|
||||
interpolated_version: clock::Global,
|
||||
language_registry_version: usize,
|
||||
update_count: usize,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
|
@ -257,7 +258,9 @@ impl SyntaxMap {
|
|||
}
|
||||
|
||||
pub fn clear(&mut self, text: &BufferSnapshot) {
|
||||
let update_count = self.snapshot.update_count + 1;
|
||||
self.snapshot = SyntaxSnapshot::new(text);
|
||||
self.snapshot.update_count = update_count;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -268,6 +271,7 @@ impl SyntaxSnapshot {
|
|||
parsed_version: clock::Global::default(),
|
||||
interpolated_version: clock::Global::default(),
|
||||
language_registry_version: 0,
|
||||
update_count: 0,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -275,6 +279,10 @@ impl SyntaxSnapshot {
|
|||
self.layers.is_empty()
|
||||
}
|
||||
|
||||
pub fn update_count(&self) -> usize {
|
||||
self.update_count
|
||||
}
|
||||
|
||||
pub fn interpolate(&mut self, text: &BufferSnapshot) {
|
||||
let edits = text
|
||||
.anchored_edits_since::<(usize, Point)>(&self.interpolated_version)
|
||||
|
@ -443,6 +451,8 @@ impl SyntaxSnapshot {
|
|||
self.language_registry_version = registry.version();
|
||||
}
|
||||
}
|
||||
|
||||
self.update_count += 1;
|
||||
}
|
||||
|
||||
fn reparse_with_ranges(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue