@@ -7,37 +7,38 @@ use ansi_term::Style;
77
88use console::AnsiCodeIterator;
99
10−use syntect::highlighting::{self, Theme};
10+use syntect::easy::HighlightLines;
11+use syntect::highlighting::Theme;
1112
1213use app::Config;
14+use assets::HighlightingAssets;
1315use decorations::{Decoration, GridBorderDecoration, LineChangesDecoration, LineNumberDecoration};
16+use diff::get_git_diff;
1417use diff::LineChanges;
1518use errors::*;
1619use style::OutputWrap;
1720use terminal::{as_terminal_escaped, to_ansi_color};
1821
1922pub trait Printer {
20− fn print_header(&mut self, filename: Option<&str>) -> Result<()>;
21− fn print_footer(&mut self) -> Result<()>;
22− fn print_line(
23− &mut self,
24− line_number: usize,
25− regions: &[(highlighting::Style, &str)],
26− ) -> Result<()>;
23+ fn print_header(&mut self, handle: &mut Write, filename: Option<&str>) -> Result<()>;
24+ fn print_footer(&mut self, handle: &mut Write) -> Result<()>;
25+ fn print_line(&mut self, handle: &mut Write, line_number: usize, line: &str) -> Result<()>;
2726}
2827
2928pub struct InteractivePrinter<'a> {
30− handle: &'a mut Write,
3129 colors: Colors,
32− pub config: &'a Config<'a>,
30+ config: &'a Config<'a>,
3331 decorations: Vec<Box<Decoration>>,
3432 panel_width: usize,
35− pub ansi_prefix_sgr: String,
33+ ansi_prefix_sgr: String,
3634 pub line_changes: Option<LineChanges>,
35+ highlighter: HighlightLines<'a>,
3736}
3837
3938impl<'a> InteractivePrinter<'a> {
40− pub fn new(handle: &'a mut Write, config: &'a Config, theme: &Theme) -> Self {
39+ pub fn new(config: &'a Config, assets: &'a HighlightingAssets, filename: Option<&str>) -> Self {
40+ let theme = assets.get_theme(&config.theme);
41+
4142 let colors = if config.colored_output {
4243 Colors::colored(theme, config.true_color)
4344 } else {
@@ -74,29 +75,35 @@ impl<'a> InteractivePrinter<'a> {
7475 panel_width = 0;
7576 }
7677
77− // Create printer.
78+ // Get the Git modifications
79+ let line_changes = filename.and_then(|file| get_git_diff(file));
80+
81+ // Determine the type of syntax for highlighting
82+ let syntax = assets.get_syntax(config.language, filename);
83+ let highlighter = HighlightLines::new(syntax, theme);
84+
7885 InteractivePrinter {
7986 panel_width,
80− handle,
8187 colors,
8288 config,
8389 decorations,
8490 ansi_prefix_sgr: String::new(),
85− line_changes: None,
91+ line_changes,
92+ highlighter,
8693 }
8794 }
8895
89− fn print_horizontal_line(&mut self, grid_char: char) -> Result<()> {
96+ fn print_horizontal_line(&mut self, handle: &mut Write, grid_char: char) -> Result<()> {
9097 if self.panel_width == 0 {
9198 writeln!(
92− self.handle,
99+ handle,
93100 "{}",
94101 self.colors.grid.paint("─".repeat(self.config.term_width))
95102 )?;
96103 } else {
97104 let hline = "─".repeat(self.config.term_width - (self.panel_width + 1));
98105 let hline = format!("{}{}{}", "─".repeat(self.panel_width), grid_char, hline);
99− writeln!(self.handle, "{}", self.colors.grid.paint(hline))?;
106+ writeln!(handle, "{}", self.colors.grid.paint(hline))?;
100107 }
101108
102109 Ok(())
@@ -104,16 +111,16 @@ impl<'a> InteractivePrinter<'a> {
104111}
105112
106113impl<'a> Printer for InteractivePrinter<'a> {
107− fn print_header(&mut self, filename: Option<&str>) -> Result<()> {
114+ fn print_header(&mut self, handle: &mut Write, filename: Option<&str>) -> Result<()> {
108115 if !self.config.output_components.header() {
109116 return Ok(());
110117 }
111118
112119 if self.config.output_components.grid() {
113− self.print_horizontal_line('┬')?;
120+ self.print_horizontal_line(handle, '┬')?;
114121
115122 write!(
116− self.handle,
123+ handle,
117124 "{}{}",
118125 " ".repeat(self.panel_width),
119126 self.colors
@@ -121,36 +128,34 @@ impl<'a> Printer for InteractivePrinter<'a> {
121128 .paint(if self.panel_width > 0 { "│ " } else { "" }),
122129 )?;
123130 } else {
124− write!(self.handle, "{}", " ".repeat(self.panel_width))?;
131+ write!(handle, "{}", " ".repeat(self.panel_width))?;
125132 }
126133
127134 writeln!(
128− self.handle,
135+ handle,
129136 "{}{}",
130137 filename.map_or("", |_| "File: "),
131138 self.colors.filename.paint(filename.unwrap_or("STDIN"))
132139 )?;
133140
134141 if self.config.output_components.grid() {
135− self.print_horizontal_line('┼')?;
142+ self.print_horizontal_line(handle, '┼')?;
136143 }
137144
138145 Ok(())
139146 }
140147
141− fn print_footer(&mut self) -> Result<()> {
148+ fn print_footer(&mut self, handle: &mut Write) -> Result<()> {
142149 if self.config.output_components.grid() {
143− self.print_horizontal_line('┴')
150+ self.print_horizontal_line(handle, '┴')
144151 } else {
145152 Ok(())
146153 }
147154 }
148155
149− fn print_line(
150− &mut self,
151− line_number: usize,
152− regions: &[(highlighting::Style, &str)],
153− ) -> Result<()> {
156+ fn print_line(&mut self, handle: &mut Write, line_number: usize, line: &str) -> Result<()> {
157+ let regions = self.highlighter.highlight(line.as_ref());
158+
154159 let mut cursor: usize = 0;
155160 let mut cursor_max: usize = self.config.term_width;
156161 let mut panel_wrap: Option<String> = None;
@@ -164,7 +169,7 @@ impl<'a> Printer for InteractivePrinter<'a> {
164169 .collect::<Vec<_>>();
165170
166171 for deco in decorations {
167− write!(self.handle, "{} ", deco.text)?;
172+ write!(handle, "{} ", deco.text)?;
168173 cursor_max -= deco.width + 1;
169174 }
170175 }
@@ -175,7 +180,7 @@ impl<'a> Printer for InteractivePrinter<'a> {
175180 let colored_output = self.config.colored_output;
176181
177182 write!(
178− self.handle,
183+ handle,
179184 "{}",
180185 regions
181186 .iter()
@@ -222,7 +227,7 @@ impl<'a> Printer for InteractivePrinter<'a> {
222227 cursor += remaining;
223228
224229 write!(
225− self.handle,
230+ handle,
226231 "{}",
227232 as_terminal_escaped(
228233 style,
@@ -260,7 +265,7 @@ impl<'a> Printer for InteractivePrinter<'a> {
260265 remaining -= available;
261266
262267 write!(
263− self.handle,
268+ handle,
264269 "{}\n{}",
265270 as_terminal_escaped(
266271 style,
@@ -282,7 +287,7 @@ impl<'a> Printer for InteractivePrinter<'a> {
282287 }
283288 }
284289
285− write!(self.handle, "\n")?;
290+ write!(handle, "\n")?;
286291 }
287292
288293 Ok(())