@@ -1,4 +1,6 @@
1+use Colors;
12use app::Config;
3+use console::AnsiCodeIterator;
24use decorations::{Decoration, GridBorderDecoration, LineChangesDecoration, LineNumberDecoration};
35use diff::LineChanges;
46use errors::*;
@@ -8,7 +10,6 @@ use std::vec::Vec;
810use style::OutputWrap;
911use syntect::highlighting;
1012use terminal::as_terminal_escaped;
11−use Colors;
1213
1314pub struct Printer<'a> {
1415 handle: &'a mut Write,
@@ -118,8 +119,7 @@ impl<'a> Printer<'a> {
118119
119120 // Line decorations.
120121 if self.panel_width > 0 {
121− let decorations = self
122− .decorations
122+ let decorations = self.decorations
123123 .iter()
124124 .map(|ref d| d.generate(self.line_number, false, self))
125125 .collect::<Vec<_>>();
@@ -150,64 +150,79 @@ impl<'a> Printer<'a> {
150150 .join("")
151151 )?;
152152 } else {
153− for &(style, text) in regions.iter() {
154− let text = text.trim_right_matches(|c| c == '\r' || c == '\n');
155− let mut chars = text.chars();
156− let mut remaining = text.chars().count();
157−
158− while remaining > 0 {
159− let available = cursor_max - cursor;
160−
161− // It fits.
162− if remaining <= available {
163− let text = chars.by_ref().take(remaining).collect::<String>();
164− cursor += remaining;
165−
166− write!(
167− self.handle,
168− "{}",
169− as_terminal_escaped(
170− style,
171− &*text,
172− self.config.true_color,
173− self.config.colored_output,
174− )
175− )?;
176− break;
177− }
153+ for &(style, region) in regions.iter() {
154+ let mut ansi_iterator = AnsiCodeIterator::new(region);
155+ let mut ansi_prefix = "";
156+ while let Some(chunk) = ansi_iterator.next() {
157+ match chunk {
158+ // ANSI escape passthrough.
159+ (text, true) => {
160+ ansi_prefix = text;
161+ }
178162
179− // Generate wrap padding if not already generated.
180− if panel_wrap.is_none() {
181− panel_wrap = if self.panel_width > 0 {
182− Some(format!(
183− "{} ",
184− self.decorations
185− .iter()
186− .map(|ref d| d.generate(self.line_number, true, self).text)
187− .collect::<Vec<String>>()
188− .join(" ")
189− ))
190− } else {
191− Some("".to_string())
163+ // Regular text.
164+ (text, false) => {
165+ let text = text.trim_right_matches(|c| c == '\r' || c == '\n');
166+ let mut chars = text.chars();
167+ let mut remaining = text.chars().count();
168+
169+ while remaining > 0 {
170+ let available = cursor_max - cursor;
171+
172+ // It fits.
173+ if remaining <= available {
174+ let text = chars.by_ref().take(remaining).collect::<String>();
175+ cursor += remaining;
176+
177+ write!(
178+ self.handle,
179+ "{}",
180+ as_terminal_escaped(
181+ style,
182+ &*format!("{}{}", ansi_prefix, text),
183+ self.config.true_color,
184+ self.config.colored_output,
185+ )
186+ )?;
187+ break;
188+ }
189+
190+ // Generate wrap padding if not already generated.
191+ if panel_wrap.is_none() {
192+ panel_wrap = if self.panel_width > 0 {
193+ Some(format!(
194+ "{} ",
195+ self.decorations
196+ .iter()
197+ .map(|ref d| d.generate(self.line_number, true, self)
198+ .text)
199+ .collect::<Vec<String>>()
200+ .join(" ")
201+ ))
202+ } else {
203+ Some("".to_string())
204+ }
205+ }
206+
207+ // It wraps.
208+ let text = chars.by_ref().take(available).collect::<String>();
209+ cursor = 0;
210+ remaining -= available;
211+
212+ write!(
213+ self.handle,
214+ "{}\n{}",
215+ as_terminal_escaped(
216+ style,
217+ &*format!("{}{}", ansi_prefix, text),
218+ self.config.true_color,
219+ self.config.colored_output,
220+ ),
221+ panel_wrap.clone().unwrap()
222+ )?;
223+ }
192224 }
193225 }
194−
195− // It wraps.
196− let text = chars.by_ref().take(available).collect::<String>();
197− cursor = 0;
198− remaining -= available;
199−
200− write!(
201− self.handle,
202− "{}\n{}",
203− as_terminal_escaped(
204− style,
205− &*text,
206− self.config.true_color,
207− self.config.colored_output,
208− ),
209− panel_wrap.clone().unwrap()
210− )?;
211226 }
212227 }
213228