Remove unneccessary snapshot storing in the buffer chunks (#44972)

Release Notes:

- N/A

Co-authored-by: Lukas Wirth <me@lukaswirth.dev>
This commit is contained in:
Kirill BulatovandLukas Wirth authored and GitHub committed 2025-12-16 13:33:22 +02:00
1 parent b671db7ab8
commit 8a3ce24ee8
4 files changed
+50 -50

No files matched your search

+2 -4
View File
@@ -4317,14 +4317,12 @@ impl BufferSnapshot {
for chunk in self
.tree_sitter_data
.chunks
.applicable_chunks(&[self.anchor_before(range.start)..self.anchor_after(range.end)])
.applicable_chunks(&[range.to_point(self)])
{
if known_chunks.is_some_and(|chunks| chunks.contains(&chunk.row_range())) {
continue;
}
let Some(chunk_range) = self.tree_sitter_data.chunks.chunk_range(chunk) else {
continue;
};
let chunk_range = chunk.anchor_range();
let chunk_range = chunk_range.to_offset(&self);
if let Some(cached_brackets) =
+30 -32
View File
@@ -3,7 +3,6 @@
use std::{ops::Range, sync::Arc};
use clock::Global;
use text::{Anchor, OffsetRangeExt as _, Point};
use util::RangeExt;
@@ -19,14 +18,13 @@ use crate::BufferRow;
/// <https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#inlayHintParams>
#[derive(Clone)]
pub struct RowChunks {
snapshot: text::BufferSnapshot,
chunks: Arc<[RowChunk]>,
version: clock::Global,
}
impl std::fmt::Debug for RowChunks {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("RowChunks")
.field("version", self.snapshot.version())
.field("chunks", &self.chunks)
.finish()
}
@@ -38,34 +36,45 @@ impl RowChunks {
let last_row = buffer_point_range.end.row;
let chunks = (buffer_point_range.start.row..=last_row)
.step_by(max_rows_per_chunk as usize)
.collect::<Vec<_>>();
let last_chunk_id = chunks.len() - 1;
let chunks = chunks
.into_iter()
.enumerate()
.map(|(id, chunk_start)| RowChunk {
id,
start: chunk_start,
end_exclusive: (chunk_start + max_rows_per_chunk).min(last_row),
.map(|(id, chunk_start)| {
let start = Point::new(chunk_start, 0);
let end_exclusive = (chunk_start + max_rows_per_chunk).min(last_row);
let end = if id == last_chunk_id {
Point::new(end_exclusive, snapshot.line_len(end_exclusive))
} else {
Point::new(end_exclusive, 0)
};
RowChunk {
id,
start: chunk_start,
end_exclusive,
start_anchor: snapshot.anchor_before(start),
end_anchor: snapshot.anchor_after(end),
}
})
.collect::<Vec<_>>();
Self {
snapshot,
chunks: Arc::from(chunks),
version: snapshot.version().clone(),
}
}
pub fn version(&self) -> &Global {
self.snapshot.version()
pub fn version(&self) -> &clock::Global {
&self.version
}
pub fn len(&self) -> usize {
self.chunks.len()
}
pub fn applicable_chunks(
&self,
ranges: &[Range<text::Anchor>],
) -> impl Iterator<Item = RowChunk> {
pub fn applicable_chunks(&self, ranges: &[Range<Point>]) -> impl Iterator<Item = RowChunk> {
let row_ranges = ranges
.iter()
.map(|range| range.to_point(&self.snapshot))
// Be lenient and yield multiple chunks if they "touch" the exclusive part of the range.
// This will result in LSP hints [re-]queried for more ranges, but also more hints already visible when scrolling around.
.map(|point_range| point_range.start.row..point_range.end.row + 1)
@@ -81,23 +90,6 @@ impl RowChunks {
.copied()
}
pub fn chunk_range(&self, chunk: RowChunk) -> Option<Range<Anchor>> {
if !self.chunks.contains(&chunk) {
return None;
}
let start = Point::new(chunk.start, 0);
let end = if self.chunks.last() == Some(&chunk) {
Point::new(
chunk.end_exclusive,
self.snapshot.line_len(chunk.end_exclusive),
)
} else {
Point::new(chunk.end_exclusive, 0)
};
Some(self.snapshot.anchor_before(start)..self.snapshot.anchor_after(end))
}
pub fn previous_chunk(&self, chunk: RowChunk) -> Option<RowChunk> {
if chunk.id == 0 {
None
@@ -112,10 +104,16 @@ pub struct RowChunk {
pub id: usize,
pub start: BufferRow,
pub end_exclusive: BufferRow,
pub start_anchor: Anchor,
pub end_anchor: Anchor,
}
impl RowChunk {
pub fn row_range(&self) -> Range<BufferRow> {
self.start..self.end_exclusive
}
pub fn anchor_range(&self) -> Range<Anchor> {
self.start_anchor..self.end_anchor
}
}
+16 -5
View File
@@ -6849,9 +6849,15 @@ impl LspStore {
ranges: &[Range<text::Anchor>],
cx: &mut Context<Self>,
) -> Vec<Range<BufferRow>> {
let buffer_snapshot = buffer.read(cx).snapshot();
let ranges = ranges
.iter()
.map(|range| range.to_point(&buffer_snapshot))
.collect::<Vec<_>>();
self.latest_lsp_data(buffer, cx)
.inlay_hints
.applicable_chunks(ranges)
.applicable_chunks(ranges.as_slice())
.map(|chunk| chunk.row_range())
.collect()
}
@@ -6898,6 +6904,12 @@ impl LspStore {
.map(|(_, known_chunks)| known_chunks)
.unwrap_or_default();
let buffer_snapshot = buffer.read(cx).snapshot();
let ranges = ranges
.iter()
.map(|range| range.to_point(&buffer_snapshot))
.collect::<Vec<_>>();
let mut hint_fetch_tasks = Vec::new();
let mut cached_inlay_hints = None;
let mut ranges_to_query = None;
@@ -6922,9 +6934,7 @@ impl LspStore {
.cloned(),
) {
(None, None) => {
let Some(chunk_range) = existing_inlay_hints.chunk_range(row_chunk) else {
continue;
};
let chunk_range = row_chunk.anchor_range();
ranges_to_query
.get_or_insert_with(Vec::new)
.push((row_chunk, chunk_range));
@@ -12726,10 +12736,11 @@ impl LspStore {
.update(cx, |buffer, _| buffer.wait_for_version(version))?
.await?;
lsp_store.update(cx, |lsp_store, cx| {
let buffer_snapshot = buffer.read(cx).snapshot();
let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
let chunks_queried_for = lsp_data
.inlay_hints
.applicable_chunks(&[range])
.applicable_chunks(&[range.to_point(&buffer_snapshot)])
.collect::<Vec<_>>();
match chunks_queried_for.as_slice() {
&[chunk] => {
@@ -8,7 +8,7 @@ use language::{
row_chunk::{RowChunk, RowChunks},
};
use lsp::LanguageServerId;
use text::Anchor;
use text::Point;
use crate::{InlayHint, InlayId};
@@ -90,10 +90,7 @@ impl BufferInlayHints {
}
}
pub fn applicable_chunks(
&self,
ranges: &[Range<text::Anchor>],
) -> impl Iterator<Item = RowChunk> {
pub fn applicable_chunks(&self, ranges: &[Range<Point>]) -> impl Iterator<Item = RowChunk> {
self.chunks.applicable_chunks(ranges)
}
@@ -226,8 +223,4 @@ impl BufferInlayHints {
}
}
}
pub fn chunk_range(&self, chunk: RowChunk) -> Option<Range<Anchor>> {
self.chunks.chunk_range(chunk)
}
}