Skip to content

Commit

Permalink
store original path when syntax is loaded, and use that in syntest
Browse files Browse the repository at this point in the history
  • Loading branch information
keith-hall committed Mar 12, 2017
1 parent df23792 commit b03fe13
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 6 deletions.
Binary file modified assets/default_newlines.packdump
Binary file not shown.
Binary file modified assets/default_nonewlines.packdump
Binary file not shown.
5 changes: 2 additions & 3 deletions examples/syntest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,10 +132,9 @@ fn test_file(ss: &SyntaxSet, path: &Path, parse_test_lines: bool) -> Result<Synt
let testtoken_end = captures.name("testtoken_end").map_or(None, |c|Some(c.as_str()));
let syntax_file = captures.name("syntax_file").unwrap().as_str();

// find the relevant syntax definition to parse the file with
// TODO: use the syntax definition file specified in the test file header, rather than relying on file extension
// find the relevant syntax definition to parse the file with - case is important!
println!("The test file references syntax definition file: {}", syntax_file);
let syntax = match ss.find_syntax_for_file(path).unwrap_or(None) {
let syntax = match ss.find_syntax_by_path(syntax_file) {
Some(syntax) => syntax,
None => return Err(SyntaxTestHeaderError::SyntaxDefinitionNotFound)
};
Expand Down
22 changes: 19 additions & 3 deletions src/parsing/syntax_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use std::mem;
use std::rc::Rc;
use std::ascii::AsciiExt;
use std::sync::Mutex;
use std::collections::HashMap;
use onig::Regex;
use rustc_serialize::{Encodable, Encoder, Decodable, Decoder};

Expand All @@ -26,6 +27,7 @@ pub struct SyntaxSet {
syntaxes: Vec<SyntaxDefinition>,
pub is_linked: bool,
first_line_cache: Mutex<FirstLineCache>,
path_scope_map: HashMap<String, Scope>,
}

fn load_syntax_file(p: &Path,
Expand All @@ -44,6 +46,7 @@ impl Default for SyntaxSet {
syntaxes: Vec::new(),
is_linked: true,
first_line_cache: Mutex::new(FirstLineCache::new()),
path_scope_map: HashMap::new(),
}
}
}
Expand Down Expand Up @@ -85,7 +88,9 @@ impl SyntaxSet {
let entry = try!(entry.map_err(LoadingError::WalkDir));
if entry.path().extension().map_or(false, |e| e == "sublime-syntax") {
// println!("{}", entry.path().display());
self.syntaxes.push(try!(load_syntax_file(entry.path(), lines_include_newline)));
let syntax = try!(load_syntax_file(entry.path(), lines_include_newline));
self.path_scope_map.insert(entry.path().to_str().unwrap().to_string(), syntax.scope);
self.syntaxes.push(syntax);
}
}
Ok(())
Expand Down Expand Up @@ -156,6 +161,15 @@ impl SyntaxSet {
None
}

/// Searches for a syntax by it's original file path when it was first loaded from disk
/// primarily useful for syntax tests
/// some may specify a Packages/PackageName/SyntaxName.sublime-syntax path
/// others may just have SyntaxName.sublime-syntax
/// this caters for these by matching the end of the path of the loaded syntax definition files
pub fn find_syntax_by_path<'a>(&'a self, path: &str) -> Option<&'a SyntaxDefinition> {
return self.path_scope_map.keys().find(|p| p.ends_with(path)).and_then(|p| self.syntaxes.iter().find(|&s| &s.scope == self.path_scope_map.get(p).unwrap()));
}

/// Convenience method that tries to find the syntax for a file path,
/// first by extension and then by first line of the file if that doesn't work.
/// May IO Error because it sometimes tries to read the first line of the file.
Expand Down Expand Up @@ -372,21 +386,23 @@ impl FirstLineCache {

impl Encodable for SyntaxSet {
fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
s.emit_struct("SyntaxSet", 2, |s| {
s.emit_struct("SyntaxSet", 3, |s| {
try!(s.emit_struct_field("syntaxes", 0, |s| self.syntaxes.encode(s)));
try!(s.emit_struct_field("is_linked", 1, |s| self.is_linked.encode(s)));
try!(s.emit_struct_field("path_scope_map", 2, |s| self.path_scope_map.encode(s)));
Ok(())
})
}
}

impl Decodable for SyntaxSet {
fn decode<D: Decoder>(d: &mut D) -> Result<Self, D::Error> {
d.read_struct("SyntaxSet", 2, |d| {
d.read_struct("SyntaxSet", 3, |d| {
let ss = SyntaxSet {
syntaxes: try!(d.read_struct_field("syntaxes", 0, Decodable::decode)),
is_linked: try!(d.read_struct_field("is_linked", 1, Decodable::decode)),
first_line_cache: Mutex::new(FirstLineCache::new()),
path_scope_map: try!(d.read_struct_field("path_scope_map", 2, Decodable::decode)),
};

Ok(ss)
Expand Down

0 comments on commit b03fe13

Please sign in to comment.