Skip to content

Commit 8174e02

Browse files
committed
Remove code that tries to handle ANSI escape inputs
Syntax highlighting is broken when input contains ANSI escape characters anyway, so there is not much point in trying to handle ANSI escapes in input.
1 parent a6297b2 commit 8174e02

File tree

6 files changed

+121
-397
lines changed

6 files changed

+121
-397
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
- Relaxed glibc requirements on amd64, see #2106 and #2194 (@sharkdp)
1616
- Improved fish completions. See #2275 (@zgracem)
17+
- Stop pre-processing ANSI escape characters. Syntax highlighting on ANSI escaped input is not supported. See #2185 and #2189 (@Enselic)
1718

1819
## Syntaxes
1920

src/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ pub(crate) mod printer;
4646
pub mod style;
4747
pub(crate) mod syntax_mapping;
4848
mod terminal;
49-
mod vscreen;
5049
pub(crate) mod wrapping;
5150

5251
pub use pretty_printer::{Input, PrettyPrinter};

src/preprocessor.rs

+18-27
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,26 @@
1-
use console::AnsiCodeIterator;
2-
31
/// Expand tabs like an ANSI-enabled expand(1).
4-
pub fn expand_tabs(line: &str, width: usize, cursor: &mut usize) -> String {
5-
let mut buffer = String::with_capacity(line.len() * 2);
6-
7-
for chunk in AnsiCodeIterator::new(line) {
8-
match chunk {
9-
(text, true) => buffer.push_str(text),
10-
(mut text, false) => {
11-
while let Some(index) = text.find('\t') {
12-
// Add previous text.
13-
if index > 0 {
14-
*cursor += index;
15-
buffer.push_str(&text[0..index]);
16-
}
17-
18-
// Add tab.
19-
let spaces = width - (*cursor % width);
20-
*cursor += spaces;
21-
buffer.push_str(&*" ".repeat(spaces));
2+
pub fn expand_tabs(mut text: &str, width: usize, cursor: &mut usize) -> String {
3+
let mut buffer = String::with_capacity(text.len() * 2);
4+
5+
while let Some(index) = text.find('\t') {
6+
// Add previous text.
7+
if index > 0 {
8+
*cursor += index;
9+
buffer.push_str(&text[0..index]);
10+
}
2211

23-
// Next.
24-
text = &text[index + 1..text.len()];
25-
}
12+
// Add tab.
13+
let spaces = width - (*cursor % width);
14+
*cursor += spaces;
15+
buffer.push_str(&*" ".repeat(spaces));
2616

27-
*cursor += text.len();
28-
buffer.push_str(text);
29-
}
30-
}
17+
// Next.
18+
text = &text[index + 1..text.len()];
3119
}
3220

21+
*cursor += text.len();
22+
buffer.push_str(text);
23+
3324
buffer
3425
}
3526

src/printer.rs

+102-138
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ use ansi_term::Style;
66

77
use bytesize::ByteSize;
88

9-
use console::AnsiCodeIterator;
10-
119
use syntect::easy::HighlightLines;
1210
use syntect::highlighting::Color;
1311
use syntect::highlighting::Theme;
@@ -33,7 +31,6 @@ use crate::line_range::RangeCheckResult;
3331
use crate::preprocessor::{expand_tabs, replace_nonprintable};
3432
use crate::style::StyleComponent;
3533
use crate::terminal::{as_terminal_escaped, to_ansi_color};
36-
use crate::vscreen::AnsiStyle;
3734
use crate::wrapping::WrappingMode;
3835

3936
pub(crate) trait Printer {
@@ -122,7 +119,6 @@ pub(crate) struct InteractivePrinter<'a> {
122119
config: &'a Config<'a>,
123120
decorations: Vec<Box<dyn Decoration>>,
124121
panel_width: usize,
125-
ansi_style: AnsiStyle,
126122
content_type: Option<ContentType>,
127123
#[cfg(feature = "git")]
128124
pub line_changes: &'a Option<LineChanges>,
@@ -206,7 +202,6 @@ impl<'a> InteractivePrinter<'a> {
206202
config,
207203
decorations,
208204
content_type: input.reader.content_type,
209-
ansi_style: AnsiStyle::new(),
210205
#[cfg(feature = "git")]
211206
line_changes,
212207
highlighter_from_set,
@@ -476,7 +471,7 @@ impl<'a> Printer for InteractivePrinter<'a> {
476471
self.config.highlighted_lines.0.check(line_number) == RangeCheckResult::InRange;
477472

478473
if highlight_this_line && self.config.theme == "ansi" {
479-
self.ansi_style.update("^[4m");
474+
write!(handle, "\x1B[4m")?;
480475
}
481476

482477
let background_color = self
@@ -503,51 +498,37 @@ impl<'a> Printer for InteractivePrinter<'a> {
503498
let italics = self.config.use_italic_text;
504499

505500
for &(style, region) in &regions {
506-
let ansi_iterator = AnsiCodeIterator::new(region);
507-
for chunk in ansi_iterator {
508-
match chunk {
509-
// ANSI escape passthrough.
510-
(ansi, true) => {
511-
self.ansi_style.update(ansi);
512-
write!(handle, "{}", ansi)?;
513-
}
501+
let text = &*self.preprocess(region, &mut cursor_total);
502+
let text_trimmed = text.trim_end_matches(|c| c == '\r' || c == '\n');
514503

515-
// Regular text.
516-
(text, false) => {
517-
let text = &*self.preprocess(text, &mut cursor_total);
518-
let text_trimmed = text.trim_end_matches(|c| c == '\r' || c == '\n');
519-
520-
write!(
521-
handle,
522-
"{}",
523-
as_terminal_escaped(
524-
style,
525-
&format!("{}{}", self.ansi_style, text_trimmed),
526-
true_color,
527-
colored_output,
528-
italics,
529-
background_color
530-
)
531-
)?;
532-
533-
if text.len() != text_trimmed.len() {
534-
if let Some(background_color) = background_color {
535-
let ansi_style = Style {
536-
background: to_ansi_color(background_color, true_color),
537-
..Default::default()
538-
};
539-
540-
let width = if cursor_total <= cursor_max {
541-
cursor_max - cursor_total + 1
542-
} else {
543-
0
544-
};
545-
write!(handle, "{}", ansi_style.paint(" ".repeat(width)))?;
546-
}
547-
write!(handle, "{}", &text[text_trimmed.len()..])?;
548-
}
549-
}
504+
write!(
505+
handle,
506+
"{}",
507+
as_terminal_escaped(
508+
style,
509+
text_trimmed,
510+
true_color,
511+
colored_output,
512+
italics,
513+
background_color
514+
)
515+
)?;
516+
517+
if text.len() != text_trimmed.len() {
518+
if let Some(background_color) = background_color {
519+
let ansi_style = Style {
520+
background: to_ansi_color(background_color, true_color),
521+
..Default::default()
522+
};
523+
524+
let width = if cursor_total <= cursor_max {
525+
cursor_max - cursor_total + 1
526+
} else {
527+
0
528+
};
529+
write!(handle, "{}", ansi_style.paint(" ".repeat(width)))?;
550530
}
531+
write!(handle, "{}", &text[text_trimmed.len()..])?;
551532
}
552533
}
553534

@@ -556,98 +537,82 @@ impl<'a> Printer for InteractivePrinter<'a> {
556537
}
557538
} else {
558539
for &(style, region) in &regions {
559-
let ansi_iterator = AnsiCodeIterator::new(region);
560-
for chunk in ansi_iterator {
561-
match chunk {
562-
// ANSI escape passthrough.
563-
(ansi, true) => {
564-
self.ansi_style.update(ansi);
565-
write!(handle, "{}", ansi)?;
566-
}
567-
568-
// Regular text.
569-
(text, false) => {
570-
let text = self.preprocess(
571-
text.trim_end_matches(|c| c == '\r' || c == '\n'),
572-
&mut cursor_total,
573-
);
574-
575-
let mut max_width = cursor_max - cursor;
576-
577-
// line buffer (avoid calling write! for every character)
578-
let mut line_buf = String::with_capacity(max_width * 4);
579-
580-
// Displayed width of line_buf
581-
let mut current_width = 0;
582-
583-
for c in text.chars() {
584-
// calculate the displayed width for next character
585-
let cw = c.width().unwrap_or(0);
586-
current_width += cw;
587-
588-
// if next character cannot be printed on this line,
589-
// flush the buffer.
590-
if current_width > max_width {
591-
// Generate wrap padding if not already generated.
592-
if panel_wrap.is_none() {
593-
panel_wrap = if self.panel_width > 0 {
594-
Some(format!(
595-
"{} ",
596-
self.decorations
597-
.iter()
598-
.map(|d| d
599-
.generate(line_number, true, self)
600-
.text)
601-
.collect::<Vec<String>>()
602-
.join(" ")
603-
))
604-
} else {
605-
Some("".to_string())
606-
}
607-
}
608-
609-
// It wraps.
610-
write!(
611-
handle,
612-
"{}\n{}",
613-
as_terminal_escaped(
614-
style,
615-
&*format!("{}{}", self.ansi_style, line_buf),
616-
self.config.true_color,
617-
self.config.colored_output,
618-
self.config.use_italic_text,
619-
background_color
620-
),
621-
panel_wrap.clone().unwrap()
622-
)?;
623-
624-
cursor = 0;
625-
max_width = cursor_max;
626-
627-
line_buf.clear();
628-
current_width = cw;
629-
}
630-
631-
line_buf.push(c);
540+
let text = self.preprocess(
541+
region.trim_end_matches(|c| c == '\r' || c == '\n'),
542+
&mut cursor_total,
543+
);
544+
545+
let mut max_width = cursor_max - cursor;
546+
547+
// line buffer (avoid calling write! for every character)
548+
let mut line_buf = String::with_capacity(max_width * 4);
549+
550+
// Displayed width of line_buf
551+
let mut current_width = 0;
552+
553+
for c in text.chars() {
554+
// calculate the displayed width for next character
555+
let cw = c.width().unwrap_or(0);
556+
current_width += cw;
557+
558+
// if next character cannot be printed on this line,
559+
// flush the buffer.
560+
if current_width > max_width {
561+
// Generate wrap padding if not already generated.
562+
if panel_wrap.is_none() {
563+
panel_wrap = if self.panel_width > 0 {
564+
Some(format!(
565+
"{} ",
566+
self.decorations
567+
.iter()
568+
.map(|d| d.generate(line_number, true, self).text)
569+
.collect::<Vec<String>>()
570+
.join(" ")
571+
))
572+
} else {
573+
Some("".to_string())
632574
}
633-
634-
// flush the buffer
635-
cursor += current_width;
636-
write!(
637-
handle,
638-
"{}",
639-
as_terminal_escaped(
640-
style,
641-
&*format!("{}{}", self.ansi_style, line_buf),
642-
self.config.true_color,
643-
self.config.colored_output,
644-
self.config.use_italic_text,
645-
background_color
646-
)
647-
)?;
648575
}
576+
577+
// It wraps.
578+
write!(
579+
handle,
580+
"{}\n{}",
581+
as_terminal_escaped(
582+
style,
583+
&line_buf,
584+
self.config.true_color,
585+
self.config.colored_output,
586+
self.config.use_italic_text,
587+
background_color
588+
),
589+
panel_wrap.clone().unwrap()
590+
)?;
591+
592+
cursor = 0;
593+
max_width = cursor_max;
594+
595+
line_buf.clear();
596+
current_width = cw;
649597
}
598+
599+
line_buf.push(c);
650600
}
601+
602+
// flush the buffer
603+
cursor += current_width;
604+
write!(
605+
handle,
606+
"{}",
607+
as_terminal_escaped(
608+
style,
609+
&line_buf,
610+
self.config.true_color,
611+
self.config.colored_output,
612+
self.config.use_italic_text,
613+
background_color
614+
)
615+
)?;
651616
}
652617

653618
if let Some(background_color) = background_color {
@@ -666,7 +631,6 @@ impl<'a> Printer for InteractivePrinter<'a> {
666631
}
667632

668633
if highlight_this_line && self.config.theme == "ansi" {
669-
self.ansi_style.update("^[24m");
670634
write!(handle, "\x1B[24m")?;
671635
}
672636

0 commit comments

Comments
 (0)