@@ -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
+ }
}
@@ -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)
- }
}