Replace LanguageRegistry trait with a simple callback

This commit is contained in:
Max Brunsfeld 2019-02-19 17:07:12 -08:00
parent e89b6b2402
commit a46515b80f
4 changed files with 96 additions and 87 deletions

View file

@ -4,7 +4,7 @@ use ansi_term::{Color, Style};
use lazy_static::lazy_static;
use serde_json::Value;
use std::collections::HashMap;
use std::{fmt, fs, io, mem, path};
use std::{fmt, fs, io, path};
use tree_sitter::{Language, PropertySheet};
use tree_sitter_highlight::{highlight, highlight_html, HighlightEvent, Properties, Scope};
@ -195,7 +195,9 @@ pub fn ansi(
let stdout = io::stdout();
let mut stdout = stdout.lock();
let mut scope_stack = Vec::new();
for event in highlight(loader, source, language, property_sheet)? {
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)) {
@ -252,13 +254,19 @@ pub fn html(
let stdout = io::stdout();
let mut stdout = stdout.lock();
write!(&mut stdout, "<table>\n")?;
let lines = highlight_html(loader, source, language, property_sheet, |scope| {
if let Some(css_style) = theme.css_style(scope) {
css_style
} else {
""
}
})?;
let lines = highlight_html(
source,
language,
property_sheet,
&|s| language_for_injection_string(loader, s),
&|scope| {
if let Some(css_style) = theme.css_style(scope) {
css_style
} else {
""
}
},
)?;
for (i, line) in lines.into_iter().enumerate() {
write!(
&mut stdout,
@ -270,3 +278,32 @@ pub fn html(
write!(&mut stdout, "</table>\n")?;
Ok(())
}
fn language_for_injection_string<'a>(
loader: &'a Loader,
string: &str,
) -> Option<(Language, &'a PropertySheet<Properties>)> {
match loader.language_configuration_for_injection_string(string) {
Err(message) => {
eprintln!(
"Failed to load language for injection string '{}': {}",
string, message.0
);
None
}
Ok(None) => None,
Ok(Some((language, configuration))) => {
match configuration.highlight_property_sheet(language) {
Err(message) => {
eprintln!(
"Failed to load property sheet for injection string '{}': {}",
string, message.0
);
None
}
Ok(None) => None,
Ok(Some(sheet)) => Some((language, sheet)),
}
}
}
}

View file

@ -10,7 +10,7 @@ use std::process::Command;
use std::time::SystemTime;
use std::{fs, mem};
use tree_sitter::{Language, PropertySheet};
use tree_sitter_highlight::{load_property_sheet, LanguageRegistry, Properties};
use tree_sitter_highlight::{load_property_sheet, Properties};
#[cfg(unix)]
const DYLIB_EXTENSION: &'static str = "so";
@ -320,37 +320,6 @@ impl Loader {
}
}
impl LanguageRegistry for Loader {
fn language_for_injection_string<'a>(
&'a self,
string: &str,
) -> Option<(Language, &'a PropertySheet<Properties>)> {
match self.language_configuration_for_injection_string(string) {
Err(message) => {
eprintln!(
"Failed to load language for injection string '{}': {}",
string, message.0
);
None
}
Ok(None) => None,
Ok(Some((language, configuration))) => {
match configuration.highlight_property_sheet(language) {
Err(message) => {
eprintln!(
"Failed to load property sheet for injection string '{}': {}",
string, message.0
);
None
}
Ok(None) => None,
Ok(Some(sheet)) => Some((language, sheet)),
}
}
}
}
}
impl LanguageConfiguration {
pub fn highlight_property_sheet(
&self,

View file

@ -1,9 +1,7 @@
use super::helpers::fixtures::{get_language, get_property_sheet};
use lazy_static::lazy_static;
use tree_sitter::{Language, PropertySheet};
use tree_sitter_highlight::{
highlight, highlight_html, HighlightEvent, LanguageRegistry, Properties, Scope,
};
use tree_sitter_highlight::{highlight, highlight_html, HighlightEvent, Properties, Scope};
lazy_static! {
static ref JS_SHEET: PropertySheet<Properties> =
@ -124,18 +122,13 @@ fn test_highlighting_multiline_scopes_to_html() {
);
}
struct TestLanguageRegistry;
impl LanguageRegistry for TestLanguageRegistry {
fn language_for_injection_string(
&self,
string: &str,
) -> Option<(Language, &PropertySheet<Properties>)> {
match string {
"javascript" => Some((get_language("javascript"), &JS_SHEET)),
"html" => Some((get_language("html"), &HTML_SHEET)),
_ => None,
}
fn test_language_for_injection_string<'a>(
string: &str,
) -> Option<(Language, &'a PropertySheet<Properties>)> {
match string {
"javascript" => Some((get_language("javascript"), &JS_SHEET)),
"html" => Some((get_language("html"), &HTML_SHEET)),
_ => None,
}
}
@ -145,11 +138,11 @@ fn to_html<'a>(
property_sheet: &'a PropertySheet<Properties>,
) -> Result<Vec<String>, String> {
highlight_html(
&TestLanguageRegistry,
src.as_bytes(),
language,
property_sheet,
|scope| SCOPE_CLASS_STRINGS[scope as usize].as_str(),
&test_language_for_injection_string,
&|scope| SCOPE_CLASS_STRINGS[scope as usize].as_str(),
)
}
@ -162,10 +155,10 @@ fn to_token_vector<'a>(
let mut scopes = Vec::new();
let mut line = Vec::new();
for event in highlight(
&TestLanguageRegistry,
src.as_bytes(),
language,
property_sheet,
&test_language_for_injection_string,
)? {
match event {
HighlightEvent::ScopeStart(s) => scopes.push(s),