@@ -32,7 +32,7 @@ use gpui::{
};
use lsp::{LanguageServerId, NumberOrString};
-use parking_lot::Mutex;
+use parking_lot::{Mutex, RawMutex, lock_api::MutexGuard};
use serde::{Deserialize, Serialize};
use serde_json::Value;
use settings::WorktreeId;
@@ -132,7 +132,7 @@ pub struct Buffer {
tree_sitter_data: Arc<Mutex<TreeSitterData>>,
}
-#[derive(Debug)]
+#[derive(Debug, Clone)]
pub struct TreeSitterData {
chunks: RowChunks,
brackets_by_chunks: Vec<Option<Vec<BracketMatch>>>,
@@ -4149,23 +4149,16 @@ impl BufferSnapshot {
///
/// The resulting collection is not ordered.
fn fetch_bracket_ranges(&self, range: Range<usize>) -> Vec<BracketMatch> {
- let mut tree_sitter_data = self.tree_sitter_data.lock();
- if self
- .version
- .changed_since(&tree_sitter_data.chunks.version())
- {
- *tree_sitter_data = TreeSitterData::new(self.text.clone());
- }
-
+ let mut tree_sitter_data = self.latest_tree_sitter_data().clone();
+ let mut new_bracket_matches = HashMap::default();
let mut all_bracket_matches = Vec::new();
for chunk in tree_sitter_data
.chunks
.applicable_chunks(&[self.anchor_before(range.start)..self.anchor_after(range.end)])
- .collect::<Vec<_>>()
{
- let chunk_brackets = &mut tree_sitter_data.brackets_by_chunks[chunk.id];
+ let chunk_brackets = tree_sitter_data.brackets_by_chunks.remove(chunk.id);
let bracket_matches = match chunk_brackets {
- Some(cached_brackets) => cached_brackets.clone(),
+ Some(cached_brackets) => cached_brackets,
None => {
let mut matches = self.syntax.matches(range.clone(), &self.text, |grammar| {
grammar.brackets_config.as_ref().map(|c| &c.query)
@@ -4216,16 +4209,38 @@ impl BufferSnapshot {
None
})
.collect::<Vec<_>>();
- *chunk_brackets = Some(new_matches.clone());
+
+ new_bracket_matches.insert(chunk.id, new_matches.clone());
new_matches
}
};
all_bracket_matches.extend(bracket_matches);
}
+ let mut latest_tree_sitter_data = self.latest_tree_sitter_data();
+ if latest_tree_sitter_data.chunks.version() == &self.version {
+ for (chunk_id, new_matches) in new_bracket_matches {
+ let old_chunks = &mut latest_tree_sitter_data.brackets_by_chunks[chunk_id];
+ if old_chunks.is_none() {
+ *old_chunks = Some(new_matches);
+ }
+ }
+ }
+
all_bracket_matches
}
+ fn latest_tree_sitter_data(&self) -> MutexGuard<'_, RawMutex, TreeSitterData> {
+ let mut tree_sitter_data = self.tree_sitter_data.lock();
+ if self
+ .version
+ .changed_since(tree_sitter_data.chunks.version())
+ {
+ *tree_sitter_data = TreeSitterData::new(self.text.clone());
+ }
+ tree_sitter_data
+ }
+
pub fn all_bracket_ranges(&self, range: Range<usize>) -> Vec<BracketMatch> {
self.fetch_bracket_ranges(range)
}
@@ -1,7 +1,7 @@
//! A row chunk is an exclusive range of rows, [`BufferRow`] within a buffer of a certain version, [`Global`].
//! All but the last chunk are of a constant, given size.
-use std::ops::Range;
+use std::{ops::Range, sync::Arc};
use clock::Global;
use text::OffsetRangeExt as _;
@@ -16,9 +16,10 @@ use crate::BufferRow;
/// Together, chunks form entire document at a particular version [`Global`].
/// Each chunk is queried for inlays as `(start_row, 0)..(end_exclusive, 0)` via
/// <https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#inlayHintParams>
+#[derive(Clone)]
pub struct RowChunks {
pub snapshot: text::BufferSnapshot,
- pub chunks: Vec<RowChunk>,
+ pub chunks: Arc<[RowChunk]>,
}
impl std::fmt::Debug for RowChunks {
@@ -42,8 +43,11 @@ impl RowChunks {
start: chunk_start,
end_exclusive: (chunk_start + max_rows_per_chunk).min(last_row),
})
- .collect();
- Self { snapshot, chunks }
+ .collect::<Vec<_>>();
+ Self {
+ snapshot,
+ chunks: Arc::from(chunks),
+ }
}
pub fn version(&self) -> &Global {