Include diagnostic info in HighlightedChunks iterator

Co-Authored-By: Nathan Sobo <nathan@zed.dev>
This commit is contained in:
Max Brunsfeld
2021-10-26 17:57:50 -07:00
co-authored by Nathan Sobo
parent f1db618be2
commit c539069cbb
12 changed files with 248 additions and 90 deletions
+17 -14
View File
@@ -1,5 +1,7 @@
use gpui::{AppContext, ModelHandle};
use language::{Anchor, AnchorRangeExt, Buffer, HighlightId, Point, TextSummary, ToOffset};
use language::{
Anchor, AnchorRangeExt, Buffer, HighlightId, HighlightedChunk, Point, TextSummary, ToOffset,
};
use parking_lot::Mutex;
use std::{
cmp::{self, Ordering},
@@ -995,12 +997,12 @@ impl<'a> Iterator for Chunks<'a> {
pub struct HighlightedChunks<'a> {
transform_cursor: Cursor<'a, Transform, (FoldOffset, usize)>,
buffer_chunks: language::HighlightedChunks<'a>,
buffer_chunk: Option<(usize, &'a str, HighlightId)>,
buffer_chunk: Option<(usize, HighlightedChunk<'a>)>,
buffer_offset: usize,
}
impl<'a> Iterator for HighlightedChunks<'a> {
type Item = (&'a str, HighlightId);
type Item = HighlightedChunk<'a>;
fn next(&mut self) -> Option<Self::Item> {
let transform = if let Some(item) = self.transform_cursor.item() {
@@ -1022,34 +1024,35 @@ impl<'a> Iterator for HighlightedChunks<'a> {
self.transform_cursor.next(&());
}
return Some((output_text, HighlightId::default()));
return Some(HighlightedChunk {
text: output_text,
highlight_id: HighlightId::default(),
diagnostic: None,
});
}
// Retrieve a chunk from the current location in the buffer.
if self.buffer_chunk.is_none() {
let chunk_offset = self.buffer_chunks.offset();
self.buffer_chunk = self
.buffer_chunks
.next()
.map(|(chunk, capture_ix)| (chunk_offset, chunk, capture_ix));
self.buffer_chunk = self.buffer_chunks.next().map(|chunk| (chunk_offset, chunk));
}
// Otherwise, take a chunk from the buffer's text.
if let Some((chunk_offset, mut chunk, capture_ix)) = self.buffer_chunk {
if let Some((chunk_offset, mut chunk)) = self.buffer_chunk {
let offset_in_chunk = self.buffer_offset - chunk_offset;
chunk = &chunk[offset_in_chunk..];
chunk.text = &chunk.text[offset_in_chunk..];
// Truncate the chunk so that it ends at the next fold.
let region_end = self.transform_cursor.end(&()).1 - self.buffer_offset;
if chunk.len() >= region_end {
chunk = &chunk[0..region_end];
if chunk.text.len() >= region_end {
chunk.text = &chunk.text[0..region_end];
self.transform_cursor.next(&());
} else {
self.buffer_chunk.take();
}
self.buffer_offset += chunk.len();
return Some((chunk, capture_ix));
self.buffer_offset += chunk.text.len();
return Some(chunk);
}
None
+23 -17
View File
@@ -1,5 +1,5 @@
use super::fold_map::{self, FoldEdit, FoldPoint, Snapshot as FoldSnapshot};
use language::{rope, HighlightId};
use language::{rope, HighlightedChunk};
use parking_lot::Mutex;
use std::{mem, ops::Range};
use sum_tree::Bias;
@@ -173,9 +173,11 @@ impl Snapshot {
.highlighted_chunks(input_start..input_end),
column: expanded_char_column,
tab_size: self.tab_size,
chunk: &SPACES[0..to_next_stop],
chunk: HighlightedChunk {
text: &SPACES[0..to_next_stop],
..Default::default()
},
skip_leading_tab: to_next_stop > 0,
style_id: Default::default(),
}
}
@@ -415,23 +417,21 @@ impl<'a> Iterator for Chunks<'a> {
pub struct HighlightedChunks<'a> {
fold_chunks: fold_map::HighlightedChunks<'a>,
chunk: &'a str,
style_id: HighlightId,
chunk: HighlightedChunk<'a>,
column: usize,
tab_size: usize,
skip_leading_tab: bool,
}
impl<'a> Iterator for HighlightedChunks<'a> {
type Item = (&'a str, HighlightId);
type Item = HighlightedChunk<'a>;
fn next(&mut self) -> Option<Self::Item> {
if self.chunk.is_empty() {
if let Some((chunk, style_id)) = self.fold_chunks.next() {
if self.chunk.text.is_empty() {
if let Some(chunk) = self.fold_chunks.next() {
self.chunk = chunk;
self.style_id = style_id;
if self.skip_leading_tab {
self.chunk = &self.chunk[1..];
self.chunk.text = &self.chunk.text[1..];
self.skip_leading_tab = false;
}
} else {
@@ -439,18 +439,24 @@ impl<'a> Iterator for HighlightedChunks<'a> {
}
}
for (ix, c) in self.chunk.char_indices() {
for (ix, c) in self.chunk.text.char_indices() {
match c {
'\t' => {
if ix > 0 {
let (prefix, suffix) = self.chunk.split_at(ix);
self.chunk = suffix;
return Some((prefix, self.style_id));
let (prefix, suffix) = self.chunk.text.split_at(ix);
self.chunk.text = suffix;
return Some(HighlightedChunk {
text: prefix,
..self.chunk
});
} else {
self.chunk = &self.chunk[1..];
self.chunk.text = &self.chunk.text[1..];
let len = self.tab_size - self.column % self.tab_size;
self.column += len;
return Some((&SPACES[0..len], self.style_id));
return Some(HighlightedChunk {
text: &SPACES[0..len],
..self.chunk
});
}
}
'\n' => self.column = 0,
@@ -458,7 +464,7 @@ impl<'a> Iterator for HighlightedChunks<'a> {
}
}
Some((mem::take(&mut self.chunk), mem::take(&mut self.style_id)))
Some(mem::take(&mut self.chunk))
}
}
+18 -16
View File
@@ -3,7 +3,7 @@ use super::{
tab_map::{self, Edit as TabEdit, Snapshot as TabSnapshot, TabPoint, TextSummary},
};
use gpui::{fonts::FontId, text_layout::LineWrapper, Entity, ModelContext, Task};
use language::{HighlightId, Point};
use language::{HighlightedChunk, Point};
use lazy_static::lazy_static;
use smol::future::yield_now;
use std::{collections::VecDeque, ops::Range, time::Duration};
@@ -52,8 +52,7 @@ pub struct Chunks<'a> {
pub struct HighlightedChunks<'a> {
input_chunks: tab_map::HighlightedChunks<'a>,
input_chunk: &'a str,
style_id: HighlightId,
input_chunk: HighlightedChunk<'a>,
output_position: WrapPoint,
max_output_row: u32,
transforms: Cursor<'a, Transform, (WrapPoint, TabPoint)>,
@@ -490,8 +489,7 @@ impl Snapshot {
.min(self.tab_snapshot.max_point());
HighlightedChunks {
input_chunks: self.tab_snapshot.highlighted_chunks(input_start..input_end),
input_chunk: "",
style_id: HighlightId::default(),
input_chunk: Default::default(),
output_position: output_start,
max_output_row: rows.end,
transforms,
@@ -674,7 +672,7 @@ impl<'a> Iterator for Chunks<'a> {
}
impl<'a> Iterator for HighlightedChunks<'a> {
type Item = (&'a str, HighlightId);
type Item = HighlightedChunk<'a>;
fn next(&mut self) -> Option<Self::Item> {
if self.output_position.row() >= self.max_output_row {
@@ -699,18 +697,19 @@ impl<'a> Iterator for HighlightedChunks<'a> {
self.output_position.0 += summary;
self.transforms.next(&());
return Some((&display_text[start_ix..end_ix], self.style_id));
return Some(HighlightedChunk {
text: &display_text[start_ix..end_ix],
..self.input_chunk
});
}
if self.input_chunk.is_empty() {
let (chunk, style_id) = self.input_chunks.next().unwrap();
self.input_chunk = chunk;
self.style_id = style_id;
if self.input_chunk.text.is_empty() {
self.input_chunk = self.input_chunks.next().unwrap();
}
let mut input_len = 0;
let transform_end = self.transforms.end(&()).0;
for c in self.input_chunk.chars() {
for c in self.input_chunk.text.chars() {
let char_len = c.len_utf8();
input_len += char_len;
if c == '\n' {
@@ -726,9 +725,12 @@ impl<'a> Iterator for HighlightedChunks<'a> {
}
}
let (prefix, suffix) = self.input_chunk.split_at(input_len);
self.input_chunk = suffix;
Some((prefix, self.style_id))
let (prefix, suffix) = self.input_chunk.text.split_at(input_len);
self.input_chunk.text = suffix;
Some(HighlightedChunk {
text: prefix,
..self.input_chunk
})
}
}
@@ -1090,7 +1092,7 @@ mod tests {
let actual_text = self
.highlighted_chunks_for_rows(start_row..end_row)
.map(|c| c.0)
.map(|c| c.text)
.collect::<String>();
assert_eq!(
expected_text,