Convert query capture indices to style ids

* Introduce a Theme struct as a new part of the app's settings
* Store on each Language a ThemeMap, which converts the capture ids
  from that language's highlight query into StyleIds, which identify
  styles in the current Theme.
* Update `highlighted_chunks` methods to provide StyleIds instead of
  capture ids.
This commit is contained in:
Max Brunsfeld
2021-05-24 16:44:14 -07:00
parent bc8d2b2f1d
commit 8340958b33
11 changed files with 389 additions and 26 deletions
+11 -8
View File
@@ -16,6 +16,7 @@ use crate::{
editor::Bias,
language::{Language, Tree},
operation_queue::{self, OperationQueue},
settings::{StyleId, ThemeMap},
sum_tree::{self, FilterCursor, SeekBias, SumTree},
time::{self, ReplicaId},
worktree::FileHandle,
@@ -617,6 +618,7 @@ impl Buffer {
handle.update(&mut ctx, |this, ctx| {
this.tree = Some((new_tree, new_version));
ctx.emit(Event::Reparsed);
ctx.notify();
});
}
handle.update(&mut ctx, |this, _| this.is_parsing = false);
@@ -778,6 +780,7 @@ impl Buffer {
highlights: Some(Highlights {
captures: captures.peekable(),
stack: Default::default(),
theme_mapping: language.theme_mapping(),
cursor,
}),
buffer: self,
@@ -2200,8 +2203,9 @@ impl<'a> tree_sitter::TextProvider<'a> for TextProvider<'a> {
struct Highlights<'a> {
captures: iter::Peekable<tree_sitter::QueryCaptures<'a, 'a, TextProvider<'a>>>,
stack: Vec<(usize, usize)>,
stack: Vec<(usize, StyleId)>,
cursor: QueryCursor,
theme_mapping: ThemeMap,
}
pub struct HighlightedChunks<'a> {
@@ -2240,7 +2244,7 @@ impl<'a> HighlightedChunks<'a> {
}
impl<'a> Iterator for HighlightedChunks<'a> {
type Item = (&'a str, Option<usize>);
type Item = (&'a str, StyleId);
fn next(&mut self) -> Option<Self::Item> {
let mut next_capture_start = usize::MAX;
@@ -2260,9 +2264,8 @@ impl<'a> Iterator for HighlightedChunks<'a> {
next_capture_start = capture.node.start_byte();
break;
} else {
highlights
.stack
.push((capture.node.end_byte(), capture.index as usize));
let style_id = highlights.theme_mapping.get(capture.index);
highlights.stack.push((capture.node.end_byte(), style_id));
highlights.captures.next().unwrap();
}
}
@@ -2271,12 +2274,12 @@ impl<'a> Iterator for HighlightedChunks<'a> {
if let Some(chunk) = self.chunks.peek() {
let chunk_start = self.range.start;
let mut chunk_end = (self.chunks.offset() + chunk.len()).min(next_capture_start);
let mut capture_ix = None;
if let Some((parent_capture_end, parent_capture_ix)) =
let mut capture_ix = StyleId::default();
if let Some((parent_capture_end, parent_style_id)) =
self.highlights.as_ref().and_then(|h| h.stack.last())
{
chunk_end = chunk_end.min(*parent_capture_end);
capture_ix = Some(*parent_capture_ix);
capture_ix = *parent_style_id;
}
let slice =
+9 -3
View File
@@ -2,7 +2,12 @@ use super::{
buffer, movement, Anchor, Bias, Buffer, BufferElement, DisplayMap, DisplayPoint, Point,
Selection, SelectionGoal, SelectionSetId, ToOffset, ToPoint,
};
use crate::{settings::Settings, util::post_inc, workspace, worktree::FileHandle};
use crate::{
settings::{Settings, StyleId},
util::post_inc,
workspace,
worktree::FileHandle,
};
use anyhow::Result;
use gpui::{
color::ColorU, fonts::Properties as FontProperties, geometry::vector::Vector2F,
@@ -2145,8 +2150,9 @@ impl BufferView {
let mut row = rows.start;
let snapshot = self.display_map.snapshot(ctx);
let chunks = snapshot.highlighted_chunks_at(rows.start, ctx);
let theme = settings.theme.clone();
'outer: for (chunk, capture_ix) in chunks.chain(Some(("\n", None))) {
'outer: for (chunk, style_ix) in chunks.chain(Some(("\n", StyleId::default()))) {
for (ix, line_chunk) in chunk.split('\n').enumerate() {
if ix > 0 {
layouts.push(layout_cache.layout_str(&line, font_size, &styles));
@@ -2160,7 +2166,7 @@ impl BufferView {
if !line_chunk.is_empty() {
line.push_str(line_chunk);
styles.push((line_chunk.len(), font_id, ColorU::black()));
styles.push((line_chunk.len(), font_id, theme.syntax_style(style_ix).0));
}
}
}
+4 -3
View File
@@ -4,6 +4,7 @@ use super::{
};
use crate::{
editor::buffer,
settings::StyleId,
sum_tree::{self, Cursor, FilterCursor, SeekBias, SumTree},
time,
};
@@ -741,12 +742,12 @@ impl<'a> Iterator for Chunks<'a> {
pub struct HighlightedChunks<'a> {
transform_cursor: Cursor<'a, Transform, DisplayOffset, TransformSummary>,
buffer_chunks: buffer::HighlightedChunks<'a>,
buffer_chunk: Option<(usize, &'a str, Option<usize>)>,
buffer_chunk: Option<(usize, &'a str, StyleId)>,
buffer_offset: usize,
}
impl<'a> Iterator for HighlightedChunks<'a> {
type Item = (&'a str, Option<usize>);
type Item = (&'a str, StyleId);
fn next(&mut self) -> Option<Self::Item> {
let transform = if let Some(item) = self.transform_cursor.item() {
@@ -768,7 +769,7 @@ impl<'a> Iterator for HighlightedChunks<'a> {
self.transform_cursor.next();
}
return Some((display_text, None));
return Some((display_text, StyleId::default()));
}
// Retrieve a chunk from the current location in the buffer.
+12 -8
View File
@@ -1,5 +1,7 @@
mod fold_map;
use crate::settings::StyleId;
use super::{buffer, Anchor, Bias, Buffer, Edit, Point, ToOffset, ToPoint};
pub use fold_map::BufferRows;
use fold_map::{FoldMap, FoldMapSnapshot};
@@ -163,7 +165,7 @@ impl DisplayMapSnapshot {
column: 0,
tab_size: self.tab_size,
chunk: "",
capture_ix: None,
style_id: Default::default(),
}
}
@@ -355,19 +357,19 @@ impl<'a> Iterator for Chunks<'a> {
pub struct HighlightedChunks<'a> {
fold_chunks: fold_map::HighlightedChunks<'a>,
chunk: &'a str,
capture_ix: Option<usize>,
style_id: StyleId,
column: usize,
tab_size: usize,
}
impl<'a> Iterator for HighlightedChunks<'a> {
type Item = (&'a str, Option<usize>);
type Item = (&'a str, StyleId);
fn next(&mut self) -> Option<Self::Item> {
if self.chunk.is_empty() {
if let Some((chunk, capture_ix)) = self.fold_chunks.next() {
if let Some((chunk, style_id)) = self.fold_chunks.next() {
self.chunk = chunk;
self.capture_ix = capture_ix;
self.style_id = style_id;
} else {
return None;
}
@@ -379,12 +381,12 @@ impl<'a> Iterator for HighlightedChunks<'a> {
if ix > 0 {
let (prefix, suffix) = self.chunk.split_at(ix);
self.chunk = suffix;
return Some((prefix, self.capture_ix));
return Some((prefix, self.style_id));
} else {
self.chunk = &self.chunk[1..];
let len = self.tab_size - self.column % self.tab_size;
self.column += len;
return Some((&SPACES[0..len], self.capture_ix));
return Some((&SPACES[0..len], self.style_id));
}
}
'\n' => self.column = 0,
@@ -392,7 +394,9 @@ impl<'a> Iterator for HighlightedChunks<'a> {
}
}
Some((mem::take(&mut self.chunk), self.capture_ix.take()))
let style_id = self.style_id;
self.style_id = StyleId::default();
Some((mem::take(&mut self.chunk), style_id))
}
}