diff --git a/Readme.md b/Readme.md index 1e9096e4..a972fb49 100644 --- a/Readme.md +++ b/Readme.md @@ -11,7 +11,7 @@ It is currently mostly complete and can parse, interpret and highlight based on - [x] Work with many languages (accomplished through using existing grammar formats) - [ ] Highlight super quickly, as fast as Sublime Text (not there yet but matching most editors) - [x] Load up quickly, currently in around 23ms but could potentially be even faster. -- [ ] Include easy to use API for basic cases +- [x] Include easy to use API for basic cases - [x] API allows use in fancy text editors with piece tables and incremental re-highlighting and the like. - [x] Expose internals of the parsing process so text editors can do things like cache parse states and use semantic info for code intelligence - [x] High quality highlighting, supporting things like heredocs and complex syntaxes (like Rust's). @@ -34,7 +34,7 @@ There's currently an example program called `syncat` that prints one of the sour - [x] Highlight a scope-annotated iterator into a colour-annotated iterator for display. - [x] Ability to dump loaded packages as binary file and load them with lazy regex compilation for fast start up times. - [x] Bundle dumped default syntaxes into the library binary so library users don't need an assets folder with Sublime Text packages. -- [ ] Add nice API wrappers for simple use cases. The base APIs are designed for deep high performance integration with arbitrary text editor data structures. +- [x] Add nice API wrappers for simple use cases. The base APIs are designed for deep high performance integration with arbitrary text editor data structures. - [ ] Make syncat a better demo, and maybe more demo programs - [ ] Document the API better and make things private that don't need to be public - [ ] Add sRGB colour correction (not sure if this is necessary, could be the job of the text editor) diff --git a/examples/syncat.rs b/examples/syncat.rs index e03a11a6..e4bb9e46 100644 --- a/examples/syncat.rs +++ b/examples/syncat.rs @@ -2,15 +2,12 @@ extern crate syntect; use syntect::parsing::SyntaxSet; use syntect::highlighting::{ThemeSet, Style}; use syntect::util::as_24_bit_terminal_escaped; -use syntect::easy::HighlightLines; +use syntect::easy::HighlightFile; -use std::io::BufReader; use std::io::BufRead; -use std::path::Path; -use std::fs::File; fn main() { - let ps = SyntaxSet::load_defaults_nonewlines(); + let ss = SyntaxSet::load_defaults_nonewlines(); let ts = ThemeSet::load_defaults(); let args: Vec = std::env::args().collect(); @@ -19,17 +16,10 @@ fn main() { return; } - let path = Path::new(&args[1]); - let extension = path.extension().unwrap().to_str().unwrap(); - let f = File::open(path).unwrap(); - let file = BufReader::new(&f); - - let syntax = ps.find_syntax_by_extension(extension).unwrap(); - let mut highlighter = HighlightLines::new(syntax, &ts.themes["base16-ocean.dark"]); - for maybe_line in file.lines() { + let mut highlighter = HighlightFile::new(&args[1], &ss, &ts.themes["base16-ocean.dark"]).unwrap(); + for maybe_line in highlighter.reader.lines() { let line = maybe_line.unwrap(); - let regions: Vec<(Style, &str)> = highlighter.highlight(&line); - let escaped = as_24_bit_terminal_escaped(®ions[..], true); - println!("{}", escaped); + let regions: Vec<(Style, &str)> = highlighter.highlight_lines.highlight(&line); + println!("{}", as_24_bit_terminal_escaped(®ions[..], true)); } } diff --git a/src/easy.rs b/src/easy.rs index eb359261..be24af02 100644 --- a/src/easy.rs +++ b/src/easy.rs @@ -61,21 +61,47 @@ impl<'a> HighlightLines<'a> { } } +/// Convenience struct containing everything you need to highlight a file. +/// Use the `reader` to get the lines of the file and the `highlight_lines` to highlight them. +/// See the `new` method docs for more information. pub struct HighlightFile<'a> { - reader: BufReader, - line_highlighter: HighlightLines<'a>, + pub reader: BufReader, + pub highlight_lines: HighlightLines<'a>, } impl<'a> HighlightFile<'a> { + /// Constructs a file reader and a line highlighter to get you reading files as fast as possible. + /// Auto-detects the syntax from the extension and constructs a `HighlightLines` with the correct syntax and theme. + /// + /// # Examples + /// + /// ``` + /// use syntect::parsing::SyntaxSet; + /// use syntect::highlighting::{ThemeSet, Style}; + /// use syntect::util::as_24_bit_terminal_escaped; + /// use syntect::easy::HighlightFile; + /// use std::io::BufRead; + /// + /// let ss = SyntaxSet::load_defaults_nonewlines(); + /// let ts = ThemeSet::load_defaults(); + /// + /// let mut highlighter = HighlightFile::new("testdata/highlight_test.erb", &ss, &ts.themes["base16-ocean.dark"]).unwrap(); + /// for maybe_line in highlighter.reader.lines() { + /// let line = maybe_line.unwrap(); + /// let regions: Vec<(Style, &str)> = highlighter.highlight_lines.highlight(&line); + /// println!("{}", as_24_bit_terminal_escaped(®ions[..], true)); + /// } + /// ``` pub fn new>(path_obj: P, ss: &SyntaxSet, theme: &'a Theme) -> io::Result> { let path: &Path = path_obj.as_ref(); let extension = path.extension().and_then(|x| x.to_str()).unwrap_or(""); - let mut f = try!(File::open(path)); + let f = try!(File::open(path)); let reader = BufReader::new(f); + // TODO use first line detection and don't panic let syntax = ss.find_syntax_by_extension(extension).unwrap(); Ok(HighlightFile { reader: reader, - line_highlighter: HighlightLines::new(syntax, theme), + highlight_lines: HighlightLines::new(syntax, theme), }) } } @@ -94,4 +120,11 @@ mod tests { let ranges = h.highlight("pub struct Wow { hi: u64 }"); assert!(ranges.len() > 4); } + + #[test] + fn can_highlight_file() { + let ss = SyntaxSet::load_defaults_nonewlines(); + let ts = ThemeSet::load_defaults(); + HighlightFile::new("testdata/highlight_test.erb", &ss, &ts.themes["base16-ocean.dark"]).unwrap(); + } }