//! Highlights the files given on the command line, in parallel. //! Prints the highlighted output to stdout. use syntect::parsing::SyntaxSet; use syntect::highlighting::{ThemeSet, Style}; use syntect::easy::HighlightFile; use rayon::prelude::*; use std::fs::File; use std::io::{BufReader, BufRead}; fn main() { let files: Vec = std::env::args().skip(1).collect(); if files.is_empty() { println!("Please provide some files to highlight."); return; } let syntax_set = SyntaxSet::load_defaults_newlines(); let theme_set = ThemeSet::load_defaults(); // We first collect the contents of the files... let contents: Vec> = files.par_iter() .map(|filename| { let mut lines = Vec::new(); // We use `String::new()` and `read_line()` instead of `BufRead::lines()` // in order to preserve the newlines and get better highlighting. let mut line = String::new(); let mut reader = BufReader::new(File::open(filename).unwrap()); while reader.read_line(&mut line).unwrap() > 0 { lines.push(line); line = String::new(); } lines }) .collect(); // ...so that the highlighted regions have valid lifetimes... let regions: Vec> = files.par_iter() .zip(&contents) .map(|(filename, contents)| { let mut regions = Vec::new(); let theme = &theme_set.themes["base16-ocean.dark"]; let mut highlighter = HighlightFile::new(filename, &syntax_set, theme).unwrap(); for line in contents { for region in highlighter.highlight_lines.highlight_line(line, &syntax_set).unwrap() { regions.push(region); } } regions }) .collect(); // ...and then print them all out. for file_regions in regions { print!("{}", syntect::util::as_24_bit_terminal_escaped(&file_regions[..], true)); } }