Rename scope -> highlight in highlighting property sheets
We need to use the word `scope` for a different purpose: tracking local scopes.
This commit is contained in:
parent
31c2086273
commit
d78ac581f3
4 changed files with 207 additions and 178 deletions
|
|
@ -9,7 +9,7 @@ use std::collections::HashMap;
|
|||
use std::time::Instant;
|
||||
use std::{fmt, fs, io, path};
|
||||
use tree_sitter::{Language, PropertySheet};
|
||||
use tree_sitter_highlight::{highlight, highlight_html, HighlightEvent, Properties, Scope};
|
||||
use tree_sitter_highlight::{highlight, highlight_html, Highlight, HighlightEvent, Properties};
|
||||
|
||||
lazy_static! {
|
||||
static ref CSS_STYLES_BY_COLOR_ID: Vec<String> =
|
||||
|
|
@ -27,12 +27,14 @@ impl Theme {
|
|||
Ok(serde_json::from_str(&json).unwrap_or_default())
|
||||
}
|
||||
|
||||
fn ansi_style(&self, scope: Scope) -> Option<&Style> {
|
||||
self.ansi_styles[scope as usize].as_ref()
|
||||
fn ansi_style(&self, highlight: Highlight) -> Option<&Style> {
|
||||
self.ansi_styles[highlight as usize].as_ref()
|
||||
}
|
||||
|
||||
fn css_style(&self, scope: Scope) -> Option<&str> {
|
||||
self.css_styles[scope as usize].as_ref().map(|s| s.as_str())
|
||||
fn css_style(&self, highlight: Highlight) -> Option<&str> {
|
||||
self.css_styles[highlight as usize]
|
||||
.as_ref()
|
||||
.map(|s| s.as_str())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -41,15 +43,15 @@ impl<'de> Deserialize<'de> for Theme {
|
|||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let scope_count = Scope::Unknown as usize + 1;
|
||||
let mut ansi_styles = vec![None; scope_count];
|
||||
let mut css_styles = vec![None; scope_count];
|
||||
if let Ok(colors) = HashMap::<Scope, Value>::deserialize(deserializer) {
|
||||
for (scope, style_value) in colors {
|
||||
let highlight_count = Highlight::Unknown as usize + 1;
|
||||
let mut ansi_styles = vec![None; highlight_count];
|
||||
let mut css_styles = vec![None; highlight_count];
|
||||
if let Ok(colors) = HashMap::<Highlight, Value>::deserialize(deserializer) {
|
||||
for (highlight, style_value) in colors {
|
||||
let mut style = Style::default();
|
||||
parse_style(&mut style, style_value);
|
||||
ansi_styles[scope as usize] = Some(style);
|
||||
css_styles[scope as usize] = Some(style_to_css(style));
|
||||
ansi_styles[highlight as usize] = Some(style);
|
||||
css_styles[highlight as usize] = Some(style_to_css(style));
|
||||
}
|
||||
}
|
||||
Ok(Self {
|
||||
|
|
@ -67,8 +69,8 @@ impl Serialize for Theme {
|
|||
let entry_count = self.ansi_styles.iter().filter(|i| i.is_some()).count();
|
||||
let mut map = serializer.serialize_map(Some(entry_count))?;
|
||||
for (i, style) in self.ansi_styles.iter().enumerate() {
|
||||
let scope = Scope::from_usize(i).unwrap();
|
||||
if scope == Scope::Unknown {
|
||||
let highlight = Highlight::from_usize(i).unwrap();
|
||||
if highlight == Highlight::Unknown {
|
||||
break;
|
||||
}
|
||||
if let Some(style) = style {
|
||||
|
|
@ -98,14 +100,14 @@ impl Serialize for Theme {
|
|||
if style.is_underline {
|
||||
entry.insert("underline", Value::Bool(true));
|
||||
}
|
||||
map.serialize_entry(&scope, &entry)?;
|
||||
map.serialize_entry(&highlight, &entry)?;
|
||||
} else if let Some(color) = color {
|
||||
map.serialize_entry(&scope, &color)?;
|
||||
map.serialize_entry(&highlight, &color)?;
|
||||
} else {
|
||||
map.serialize_entry(&scope, &Value::Null)?;
|
||||
map.serialize_entry(&highlight, &Value::Null)?;
|
||||
}
|
||||
} else {
|
||||
map.serialize_entry(&scope, &Value::Null)?;
|
||||
map.serialize_entry(&highlight, &Value::Null)?;
|
||||
}
|
||||
}
|
||||
map.end()
|
||||
|
|
@ -150,11 +152,11 @@ impl fmt::Debug for Theme {
|
|||
let mut first = true;
|
||||
for (i, style) in self.ansi_styles.iter().enumerate() {
|
||||
if let Some(style) = style {
|
||||
let scope = Scope::from_usize(i).unwrap();
|
||||
let highlight = Highlight::from_usize(i).unwrap();
|
||||
if !first {
|
||||
write!(f, ", ")?;
|
||||
}
|
||||
write!(f, "{:?}: {:?}", scope, style)?;
|
||||
write!(f, "{:?}: {:?}", highlight, style)?;
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
|
|
@ -262,23 +264,23 @@ pub fn ansi(
|
|||
let mut stdout = stdout.lock();
|
||||
|
||||
let time = Instant::now();
|
||||
let mut scope_stack = Vec::new();
|
||||
let mut highlight_stack = Vec::new();
|
||||
for event in highlight(source, language, property_sheet, |s| {
|
||||
language_for_injection_string(loader, s)
|
||||
})? {
|
||||
match event {
|
||||
HighlightEvent::Source(s) => {
|
||||
if let Some(style) = scope_stack.last().and_then(|s| theme.ansi_style(*s)) {
|
||||
if let Some(style) = highlight_stack.last().and_then(|s| theme.ansi_style(*s)) {
|
||||
write!(&mut stdout, "{}", style.paint(s))?;
|
||||
} else {
|
||||
write!(&mut stdout, "{}", s)?;
|
||||
}
|
||||
}
|
||||
HighlightEvent::ScopeStart(s) => {
|
||||
scope_stack.push(s);
|
||||
HighlightEvent::HighlightStart(h) => {
|
||||
highlight_stack.push(h);
|
||||
}
|
||||
HighlightEvent::ScopeEnd => {
|
||||
scope_stack.pop();
|
||||
HighlightEvent::HighlightEnd => {
|
||||
highlight_stack.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -334,8 +336,8 @@ pub fn html(
|
|||
language,
|
||||
property_sheet,
|
||||
|s| language_for_injection_string(loader, s),
|
||||
|scope| {
|
||||
if let Some(css_style) = theme.css_style(scope) {
|
||||
|highlight| {
|
||||
if let Some(css_style) = theme.css_style(highlight) {
|
||||
css_style
|
||||
} else {
|
||||
""
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ use lazy_static::lazy_static;
|
|||
use std::ffi::CString;
|
||||
use std::{ptr, slice, str};
|
||||
use tree_sitter::{Language, PropertySheet};
|
||||
use tree_sitter_highlight::{c, highlight, highlight_html, HighlightEvent, Properties, Scope};
|
||||
use tree_sitter_highlight::{c, highlight, highlight_html, Highlight, HighlightEvent, Properties};
|
||||
|
||||
lazy_static! {
|
||||
static ref JS_SHEET: PropertySheet<Properties> =
|
||||
|
|
@ -15,8 +15,8 @@ lazy_static! {
|
|||
static ref SCOPE_CLASS_STRINGS: Vec<String> = {
|
||||
let mut result = Vec::new();
|
||||
let mut i = 0;
|
||||
while let Some(scope) = Scope::from_usize(i) {
|
||||
result.push(format!("class={:?}", scope));
|
||||
while let Some(highlight) = Highlight::from_usize(i) {
|
||||
result.push(format!("class={:?}", highlight));
|
||||
i += 1;
|
||||
}
|
||||
result
|
||||
|
|
@ -30,34 +30,51 @@ fn test_highlighting_injected_html_in_javascript() {
|
|||
assert_eq!(
|
||||
&to_token_vector(&source, get_language("javascript"), &JS_SHEET).unwrap(),
|
||||
&[vec![
|
||||
("const", vec![Scope::Keyword]),
|
||||
("const", vec![Highlight::Keyword]),
|
||||
(" ", vec![]),
|
||||
("s", vec![Scope::Variable]),
|
||||
("s", vec![Highlight::Variable]),
|
||||
(" ", vec![]),
|
||||
("=", vec![Scope::Operator]),
|
||||
("=", vec![Highlight::Operator]),
|
||||
(" ", vec![]),
|
||||
("html", vec![Scope::Function]),
|
||||
("html", vec![Highlight::Function]),
|
||||
(" ", vec![]),
|
||||
("`<", vec![Scope::String]),
|
||||
("div", vec![Scope::String, Scope::Tag]),
|
||||
(">", vec![Scope::String]),
|
||||
("`<", vec![Highlight::String]),
|
||||
("div", vec![Highlight::String, Highlight::Tag]),
|
||||
(">", vec![Highlight::String]),
|
||||
(
|
||||
"${",
|
||||
vec![Scope::String, Scope::Embedded, Scope::PunctuationSpecial]
|
||||
vec![
|
||||
Highlight::String,
|
||||
Highlight::Embedded,
|
||||
Highlight::PunctuationSpecial
|
||||
]
|
||||
),
|
||||
(
|
||||
"a",
|
||||
vec![Highlight::String, Highlight::Embedded, Highlight::Variable]
|
||||
),
|
||||
(" ", vec![Highlight::String, Highlight::Embedded]),
|
||||
(
|
||||
"<",
|
||||
vec![Highlight::String, Highlight::Embedded, Highlight::Operator]
|
||||
),
|
||||
(" ", vec![Highlight::String, Highlight::Embedded]),
|
||||
(
|
||||
"b",
|
||||
vec![Highlight::String, Highlight::Embedded, Highlight::Variable]
|
||||
),
|
||||
("a", vec![Scope::String, Scope::Embedded, Scope::Variable]),
|
||||
(" ", vec![Scope::String, Scope::Embedded]),
|
||||
("<", vec![Scope::String, Scope::Embedded, Scope::Operator]),
|
||||
(" ", vec![Scope::String, Scope::Embedded]),
|
||||
("b", vec![Scope::String, Scope::Embedded, Scope::Variable]),
|
||||
(
|
||||
"}",
|
||||
vec![Scope::String, Scope::Embedded, Scope::PunctuationSpecial]
|
||||
vec![
|
||||
Highlight::String,
|
||||
Highlight::Embedded,
|
||||
Highlight::PunctuationSpecial
|
||||
]
|
||||
),
|
||||
("</", vec![Scope::String]),
|
||||
("div", vec![Scope::String, Scope::Tag]),
|
||||
(">`", vec![Scope::String]),
|
||||
(";", vec![Scope::PunctuationDelimiter]),
|
||||
("</", vec![Highlight::String]),
|
||||
("div", vec![Highlight::String, Highlight::Tag]),
|
||||
(">`", vec![Highlight::String]),
|
||||
(";", vec![Highlight::PunctuationDelimiter]),
|
||||
]]
|
||||
);
|
||||
}
|
||||
|
|
@ -76,35 +93,43 @@ fn test_highlighting_injected_javascript_in_html() {
|
|||
assert_eq!(
|
||||
&to_token_vector(&source, get_language("html"), &HTML_SHEET).unwrap(),
|
||||
&[
|
||||
vec![("<", vec![]), ("body", vec![Scope::Tag]), (">", vec![]),],
|
||||
vec![(" <", vec![]), ("script", vec![Scope::Tag]), (">", vec![]),],
|
||||
vec![("<", vec![]), ("body", vec![Highlight::Tag]), (">", vec![]),],
|
||||
vec![
|
||||
(" <", vec![]),
|
||||
("script", vec![Highlight::Tag]),
|
||||
(">", vec![]),
|
||||
],
|
||||
vec![
|
||||
(" ", vec![]),
|
||||
("const", vec![Scope::Keyword]),
|
||||
("const", vec![Highlight::Keyword]),
|
||||
(" ", vec![]),
|
||||
("x", vec![Scope::Variable]),
|
||||
("x", vec![Highlight::Variable]),
|
||||
(" ", vec![]),
|
||||
("=", vec![Scope::Operator]),
|
||||
("=", vec![Highlight::Operator]),
|
||||
(" ", vec![]),
|
||||
("new", vec![Scope::Keyword]),
|
||||
("new", vec![Highlight::Keyword]),
|
||||
(" ", vec![]),
|
||||
("Thing", vec![Scope::Constructor]),
|
||||
("(", vec![Scope::PunctuationBracket]),
|
||||
(")", vec![Scope::PunctuationBracket]),
|
||||
(";", vec![Scope::PunctuationDelimiter]),
|
||||
("Thing", vec![Highlight::Constructor]),
|
||||
("(", vec![Highlight::PunctuationBracket]),
|
||||
(")", vec![Highlight::PunctuationBracket]),
|
||||
(";", vec![Highlight::PunctuationDelimiter]),
|
||||
],
|
||||
vec![
|
||||
(" </", vec![]),
|
||||
("script", vec![Scope::Tag]),
|
||||
("script", vec![Highlight::Tag]),
|
||||
(">", vec![]),
|
||||
],
|
||||
vec![
|
||||
("</", vec![]),
|
||||
("body", vec![Highlight::Tag]),
|
||||
(">", vec![]),
|
||||
],
|
||||
vec![("</", vec![]), ("body", vec![Scope::Tag]), (">", vec![]),],
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_highlighting_multiline_scopes_to_html() {
|
||||
fn test_highlighting_multiline_nodes_to_html() {
|
||||
let source = vec![
|
||||
"const SOMETHING = `",
|
||||
" one ${",
|
||||
|
|
@ -166,17 +191,17 @@ fn test_highlighting_ejs() {
|
|||
&to_token_vector(&source, get_language("embedded-template"), &EJS_SHEET).unwrap(),
|
||||
&[[
|
||||
("<", vec![]),
|
||||
("div", vec![Scope::Tag]),
|
||||
("div", vec![Highlight::Tag]),
|
||||
(">", vec![]),
|
||||
("<%", vec![Scope::Keyword]),
|
||||
("<%", vec![Highlight::Keyword]),
|
||||
(" ", vec![]),
|
||||
("foo", vec![Scope::Function]),
|
||||
("(", vec![Scope::PunctuationBracket]),
|
||||
(")", vec![Scope::PunctuationBracket]),
|
||||
("foo", vec![Highlight::Function]),
|
||||
("(", vec![Highlight::PunctuationBracket]),
|
||||
(")", vec![Highlight::PunctuationBracket]),
|
||||
(" ", vec![]),
|
||||
("%>", vec![Scope::Keyword]),
|
||||
("%>", vec![Highlight::Keyword]),
|
||||
("</", vec![]),
|
||||
("div", vec![Scope::Tag]),
|
||||
("div", vec![Highlight::Tag]),
|
||||
(">", vec![])
|
||||
]],
|
||||
);
|
||||
|
|
@ -201,11 +226,11 @@ fn test_highlighting_via_c_api() {
|
|||
let injection_regex = c_string("^(javascript|js)$");
|
||||
let source_code = c_string("<script>\nconst a = b('c');\nc.d();\n</script>");
|
||||
|
||||
let attribute_strings = &mut [ptr::null(); Scope::Unknown as usize + 1];
|
||||
attribute_strings[Scope::Tag as usize] = class_tag.as_ptr();
|
||||
attribute_strings[Scope::String as usize] = class_string.as_ptr();
|
||||
attribute_strings[Scope::Keyword as usize] = class_keyword.as_ptr();
|
||||
attribute_strings[Scope::Function as usize] = class_function.as_ptr();
|
||||
let attribute_strings = &mut [ptr::null(); Highlight::Unknown as usize + 1];
|
||||
attribute_strings[Highlight::Tag as usize] = class_tag.as_ptr();
|
||||
attribute_strings[Highlight::String as usize] = class_string.as_ptr();
|
||||
attribute_strings[Highlight::Keyword as usize] = class_keyword.as_ptr();
|
||||
attribute_strings[Highlight::Function as usize] = class_function.as_ptr();
|
||||
|
||||
let highlighter = c::ts_highlighter_new(attribute_strings.as_ptr());
|
||||
let buffer = c::ts_highlight_buffer_new();
|
||||
|
|
@ -290,7 +315,7 @@ fn to_html<'a>(
|
|||
language,
|
||||
property_sheet,
|
||||
&test_language_for_injection_string,
|
||||
&|scope| SCOPE_CLASS_STRINGS[scope as usize].as_str(),
|
||||
&|highlight| SCOPE_CLASS_STRINGS[highlight as usize].as_str(),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -298,9 +323,9 @@ fn to_token_vector<'a>(
|
|||
src: &'a str,
|
||||
language: Language,
|
||||
property_sheet: &'a PropertySheet<Properties>,
|
||||
) -> Result<Vec<Vec<(&'a str, Vec<Scope>)>>, String> {
|
||||
) -> Result<Vec<Vec<(&'a str, Vec<Highlight>)>>, String> {
|
||||
let mut lines = Vec::new();
|
||||
let mut scopes = Vec::new();
|
||||
let mut highlights = Vec::new();
|
||||
let mut line = Vec::new();
|
||||
for event in highlight(
|
||||
src.as_bytes(),
|
||||
|
|
@ -309,9 +334,9 @@ fn to_token_vector<'a>(
|
|||
&test_language_for_injection_string,
|
||||
)? {
|
||||
match event {
|
||||
HighlightEvent::ScopeStart(s) => scopes.push(s),
|
||||
HighlightEvent::ScopeEnd => {
|
||||
scopes.pop();
|
||||
HighlightEvent::HighlightStart(s) => highlights.push(s),
|
||||
HighlightEvent::HighlightEnd => {
|
||||
highlights.pop();
|
||||
}
|
||||
HighlightEvent::Source(s) => {
|
||||
for (i, l) in s.lines().enumerate() {
|
||||
|
|
@ -320,7 +345,7 @@ fn to_token_vector<'a>(
|
|||
line = Vec::new();
|
||||
}
|
||||
if l.len() > 0 {
|
||||
line.push((l, scopes.clone()));
|
||||
line.push((l, highlights.clone()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue