Skip to content

Commit 6c7980e

Browse files
committed
perf(syntax): optimize viewport highlighting
1 parent 638a7ab commit 6c7980e

8 files changed

Lines changed: 501 additions & 65 deletions

File tree

crates/phosphor/src/language.rs

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ use tree_sitter::StreamingIterator;
1212
use carbon::{TextByteRange, u32_to_usize_saturating, usize_to_u32_saturating};
1313

1414
use crate::error::{PhosphorError, Result};
15-
use crate::{HighlightKind, HighlightLineBuffer, HighlightSpan, LanguageId, LanguageMetadata};
15+
use crate::{
16+
HighlightKind, HighlightLineBuffer, HighlightSpan, LanguageId, LanguageMetadata, ParsedSyntax,
17+
};
1618

1719
#[derive(Debug)]
1820
struct CompiledLanguage {
@@ -140,6 +142,16 @@ pub(crate) fn highlight(language: LanguageId, source: &str) -> Result<Vec<Highli
140142
compact_spans(language, raw_spans)
141143
}
142144

145+
pub(crate) fn parse(language: LanguageId, source: &str) -> Result<ParsedSyntax> {
146+
if !is_parser_available(language) {
147+
return Err(PhosphorError::MissingParser { language });
148+
}
149+
150+
let compiled = compiled_language(language)?;
151+
let tree = parse_source(&compiled, source)?;
152+
Ok(ParsedSyntax { language, tree })
153+
}
154+
143155
pub(crate) fn highlight_text_ranges(
144156
language: LanguageId,
145157
source: &str,
@@ -163,6 +175,24 @@ pub(crate) fn highlight_text_ranges(
163175
compact_spans(language, raw_spans)
164176
}
165177

178+
pub(crate) fn highlight_text_ranges_with_parse(
179+
parsed: &ParsedSyntax,
180+
source: &str,
181+
byte_ranges: &[TextByteRange],
182+
) -> Result<Vec<HighlightSpan>> {
183+
if source.is_empty() || byte_ranges.is_empty() {
184+
return Ok(Vec::new());
185+
}
186+
let ranges = merged_text_ranges(byte_ranges, source.len());
187+
if ranges.is_empty() {
188+
return Ok(Vec::new());
189+
}
190+
191+
let compiled = compiled_language(parsed.language)?;
192+
let raw_spans = collect_spans_in_ranges(&compiled, &parsed.tree, source, &ranges);
193+
compact_spans(parsed.language, raw_spans)
194+
}
195+
166196
pub(crate) fn highlight_text_lines(
167197
language: LanguageId,
168198
source: &str,

crates/phosphor/src/lib.rs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ pub use error::{PhosphorError, Result};
1414
pub use pack::PackInstaller;
1515
pub use types::{
1616
HighlightKind, HighlightLine, HighlightLineBuffer, HighlightSpan, HighlightSpanRange,
17-
LanguageId, LanguageMetadata,
17+
LanguageId, LanguageMetadata, ParsedSyntax,
1818
};
1919

2020
#[derive(Debug, Default, Clone, Copy)]
@@ -77,6 +77,25 @@ impl Highlighter {
7777
language::highlight_text_ranges(language, source, byte_ranges)
7878
}
7979

80+
pub fn parse_text_store_language(
81+
&self,
82+
language: LanguageId,
83+
text: &TextStore,
84+
) -> Result<ParsedSyntax> {
85+
let source = text.as_str().ok_or(PhosphorError::InvalidUtf8)?;
86+
language::parse(language, source)
87+
}
88+
89+
pub fn highlight_text_store_language_ranges_with_parse(
90+
&self,
91+
parsed: &ParsedSyntax,
92+
text: &TextStore,
93+
byte_ranges: &[TextByteRange],
94+
) -> Result<Vec<HighlightSpan>> {
95+
let source = text.as_str().ok_or(PhosphorError::InvalidUtf8)?;
96+
language::highlight_text_ranges_with_parse(parsed, source, byte_ranges)
97+
}
98+
8099
pub fn highlight_text_store_language_lines(
81100
&self,
82101
language: LanguageId,

crates/phosphor/src/types.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use carbon::{TextByteRange, u32_to_usize_saturating, usize_to_u32_saturating};
2+
use tree_sitter as ts;
23

34
#[repr(u8)]
45
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
@@ -110,6 +111,12 @@ impl HighlightLineBuffer {
110111
}
111112
}
112113

114+
#[derive(Debug, Clone)]
115+
pub struct ParsedSyntax {
116+
pub(crate) language: LanguageId,
117+
pub(crate) tree: ts::Tree,
118+
}
119+
113120
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
114121
pub enum LanguageId {
115122
Bash,

0 commit comments

Comments
 (0)