@@ -7,37 +7,38 @@ use ansi_term::Style;
8use console::AnsiCodeIterator;
8use console::AnsiCodeIterator;
10+use syntect::easy::HighlightLines;
10−use syntect::highlighting::{self, Theme};
11+use syntect::highlighting::Theme;
12use app::Config;
13use app::Config;
14+use assets::HighlightingAssets;
13use decorations::{Decoration, GridBorderDecoration, LineChangesDecoration, LineNumberDecoration};
15use decorations::{Decoration, GridBorderDecoration, LineChangesDecoration, LineNumberDecoration};
16+use diff::get_git_diff;
14use diff::LineChanges;
17use diff::LineChanges;
15use errors::*;
18use errors::*;
16use style::OutputWrap;
19use style::OutputWrap;
17use terminal::{as_terminal_escaped, to_ansi_color};
20use terminal::{as_terminal_escaped, to_ansi_color};
19pub trait Printer {
22pub trait Printer {
20− fn print_header(&mut self, filename: Option<&str>) -> Result<()>;
23+ fn print_header(&mut self, handle: &mut Write, filename: Option<&str>) -> Result<()>;
21− fn print_footer(&mut self) -> Result<()>;
24+ fn print_footer(&mut self, handle: &mut Write) -> Result<()>;
24− line_number: usize,
25+ fn print_line(&mut self, handle: &mut Write, line_number: usize, line: &str) -> Result<()>;
25− regions: &[(highlighting::Style, &str)],
29pub struct InteractivePrinter<'a> {
28pub struct InteractivePrinter<'a> {
30− handle: &'a mut Write,
31 colors: Colors,
29 colors: Colors,
32− pub config: &'a Config<'a>,
30+ config: &'a Config<'a>,
33 decorations: Vec<Box<Decoration>>,
31 decorations: Vec<Box<Decoration>>,
34 panel_width: usize,
32 panel_width: usize,
35− pub ansi_prefix_sgr: String,
33+ ansi_prefix_sgr: String,
36 pub line_changes: Option<LineChanges>,
34 pub line_changes: Option<LineChanges>,
35+ highlighter: HighlightLines<'a>,
39impl<'a> InteractivePrinter<'a> {
38impl<'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 let colors = if config.colored_output {
42 let colors = if config.colored_output {
42 Colors::colored(theme, config.true_color)
43 Colors::colored(theme, config.true_color)
@@ -74,29 +75,35 @@ impl<'a> InteractivePrinter<'a> {
74 panel_width = 0;
75 panel_width = 0;
77− // Create printer.
78+ // Get the Git modifications
79+ let line_changes = filename.and_then(|file| get_git_diff(file));
81+ // Determine the type of syntax for highlighting
82+ let syntax = assets.get_syntax(config.language, filename);
83+ let highlighter = HighlightLines::new(syntax, theme);
78 InteractivePrinter {
85 InteractivePrinter {
79 panel_width,
86 panel_width,
83 decorations,
89 decorations,
84 ansi_prefix_sgr: String::new(),
90 ansi_prefix_sgr: String::new(),
85− line_changes: None,
91+ line_changes,
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<()> {
90 if self.panel_width == 0 {
97 if self.panel_width == 0 {
92− self.handle,
99+ handle,
94 self.colors.grid.paint("─".repeat(self.config.term_width))
101 self.colors.grid.paint("─".repeat(self.config.term_width))
97 let hline = "─".repeat(self.config.term_width - (self.panel_width + 1));
104 let hline = "─".repeat(self.config.term_width - (self.panel_width + 1));
98 let hline = format!("{}{}{}", "─".repeat(self.panel_width), grid_char, hline);
105 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))?;
@@ -104,16 +111,16 @@ impl<'a> InteractivePrinter<'a> {
106impl<'a> Printer for InteractivePrinter<'a> {
113impl<'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<()> {
108 if !self.config.output_components.header() {
115 if !self.config.output_components.header() {
109 return Ok(());
116 return Ok(());
112 if self.config.output_components.grid() {
119 if self.config.output_components.grid() {
113− self.print_horizontal_line('┬')?;
120+ self.print_horizontal_line(handle, '┬')?;
116− self.handle,
123+ handle,
118 " ".repeat(self.panel_width),
125 " ".repeat(self.panel_width),
119 self.colors
126 self.colors
@@ -121,36 +128,34 @@ impl<'a> Printer for InteractivePrinter<'a> {
121 .paint(if self.panel_width > 0 { "│ " } else { "" }),
128 .paint(if self.panel_width > 0 { "│ " } else { "" }),
124− write!(self.handle, "{}", " ".repeat(self.panel_width))?;
131+ write!(handle, "{}", " ".repeat(self.panel_width))?;
127 writeln!(
134 writeln!(
128− self.handle,
135+ handle,
130 filename.map_or("", |_| "File: "),
137 filename.map_or("", |_| "File: "),
131 self.colors.filename.paint(filename.unwrap_or("STDIN"))
138 self.colors.filename.paint(filename.unwrap_or("STDIN"))
134 if self.config.output_components.grid() {
141 if self.config.output_components.grid() {
135− self.print_horizontal_line('┼')?;
142+ self.print_horizontal_line(handle, '┼')?;
141− fn print_footer(&mut self) -> Result<()> {
148+ fn print_footer(&mut self, handle: &mut Write) -> Result<()> {
142 if self.config.output_components.grid() {
149 if self.config.output_components.grid() {
143− self.print_horizontal_line('┴')
150+ self.print_horizontal_line(handle, '┴')
151− line_number: usize,
156+ fn print_line(&mut self, handle: &mut Write, line_number: usize, line: &str) -> Result<()> {
152− regions: &[(highlighting::Style, &str)],
157+ let regions = self.highlighter.highlight(line.as_ref());
153− ) -> Result<()> {
158+
154 let mut cursor: usize = 0;
159 let mut cursor: usize = 0;
155 let mut cursor_max: usize = self.config.term_width;
160 let mut cursor_max: usize = self.config.term_width;
156 let mut panel_wrap: Option<String> = None;
161 let mut panel_wrap: Option<String> = None;
@@ -164,7 +169,7 @@ impl<'a> Printer for InteractivePrinter<'a> {
164 .collect::<Vec<_>>();
169 .collect::<Vec<_>>();
166 for deco in decorations {
171 for deco in decorations {
167− write!(self.handle, "{} ", deco.text)?;
172+ write!(handle, "{} ", deco.text)?;
168 cursor_max -= deco.width + 1;
173 cursor_max -= deco.width + 1;
@@ -175,7 +180,7 @@ impl<'a> Printer for InteractivePrinter<'a> {
175 let colored_output = self.config.colored_output;
180 let colored_output = self.config.colored_output;
178− self.handle,
183+ handle,
@@ -222,7 +227,7 @@ impl<'a> Printer for InteractivePrinter<'a> {
222 cursor += remaining;
227 cursor += remaining;
225− self.handle,
230+ handle,
227 as_terminal_escaped(
232 as_terminal_escaped(
@@ -260,7 +265,7 @@ impl<'a> Printer for InteractivePrinter<'a> {
260 remaining -= available;
265 remaining -= available;
263− self.handle,
268+ handle,
264 "{}\n{}",
269 "{}\n{}",
265 as_terminal_escaped(
270 as_terminal_escaped(
@@ -282,7 +287,7 @@ impl<'a> Printer for InteractivePrinter<'a> {
285− write!(self.handle, "\n")?;
290+ write!(handle, "\n")?;