1
0
mirror of https://github.com/sharkdp/bat.git synced 2025-01-19 04:21:06 +00:00

Remove hyperlink when wrapping lines

This commit is contained in:
Ethan P 2023-04-17 19:19:49 -07:00 committed by Ethan P.
parent 6549e26f5d
commit 1023399c5e
No known key found for this signature in database
GPG Key ID: 1BA2A0CC7C22B854
3 changed files with 46 additions and 7 deletions

View File

@ -598,12 +598,12 @@ impl<'a> Printer for InteractivePrinter<'a> {
match chunk { match chunk {
// Regular text. // Regular text.
EscapeSequence::Text(text) => { EscapeSequence::Text(text) => {
let text = &*self.preprocess(text, &mut cursor_total); let text = self.preprocess(text, &mut cursor_total);
let text_trimmed = text.trim_end_matches(|c| c == '\r' || c == '\n'); let text_trimmed = text.trim_end_matches(|c| c == '\r' || c == '\n');
write!( write!(
handle, handle,
"{}", "{}{}",
as_terminal_escaped( as_terminal_escaped(
style, style,
&format!("{}{}", self.ansi_style, text_trimmed), &format!("{}{}", self.ansi_style, text_trimmed),
@ -611,9 +611,11 @@ impl<'a> Printer for InteractivePrinter<'a> {
colored_output, colored_output,
italics, italics,
background_color background_color
) ),
self.ansi_style.to_reset_sequence(),
)?; )?;
// Pad the rest of the line.
if text.len() != text_trimmed.len() { if text.len() != text_trimmed.len() {
if let Some(background_color) = background_color { if let Some(background_color) = background_color {
let ansi_style = Style { let ansi_style = Style {
@ -693,7 +695,7 @@ impl<'a> Printer for InteractivePrinter<'a> {
// It wraps. // It wraps.
write!( write!(
handle, handle,
"{}\n{}", "{}{}\n{}",
as_terminal_escaped( as_terminal_escaped(
style, style,
&format!("{}{}", self.ansi_style, line_buf), &format!("{}{}", self.ansi_style, line_buf),
@ -702,6 +704,7 @@ impl<'a> Printer for InteractivePrinter<'a> {
self.config.use_italic_text, self.config.use_italic_text,
background_color background_color
), ),
self.ansi_style.to_reset_sequence(),
panel_wrap.clone().unwrap() panel_wrap.clone().unwrap()
)?; )?;

View File

@ -23,6 +23,13 @@ impl AnsiStyle {
} }
} }
} }
pub fn to_reset_sequence(&mut self) -> String {
match &mut self.attributes {
Some(a) => a.to_reset_sequence(),
None => String::new(),
}
}
} }
impl Display for AnsiStyle { impl Display for AnsiStyle {
@ -35,6 +42,8 @@ impl Display for AnsiStyle {
} }
struct Attributes { struct Attributes {
has_sgr_sequences: bool,
foreground: String, foreground: String,
background: String, background: String,
underlined: String, underlined: String,
@ -67,16 +76,18 @@ struct Attributes {
strike: String, strike: String,
/// The hyperlink sequence. /// The hyperlink sequence.
/// FORMAT: \x1B]8;<ID>;<HREF>\e\\ /// FORMAT: \x1B]8;{ID};{URL}\e\\
/// ///
/// `\e\\` may be replaced with BEL `\x07`. /// `\e\\` may be replaced with BEL `\x07`.
/// Setting both <ID> and <HREF> to an empty string represents no hyperlink. /// Setting both {ID} and {URL} to an empty string represents no hyperlink.
hyperlink: String, hyperlink: String,
} }
impl Attributes { impl Attributes {
pub fn new() -> Self { pub fn new() -> Self {
Attributes { Attributes {
has_sgr_sequences: false,
foreground: "".to_owned(), foreground: "".to_owned(),
background: "".to_owned(), background: "".to_owned(),
underlined: "".to_owned(), underlined: "".to_owned(),
@ -135,6 +146,8 @@ impl Attributes {
} }
fn sgr_reset(&mut self) { fn sgr_reset(&mut self) {
self.has_sgr_sequences = false;
self.foreground.clear(); self.foreground.clear();
self.background.clear(); self.background.clear();
self.underlined.clear(); self.underlined.clear();
@ -152,6 +165,7 @@ impl Attributes {
.map(|p| p.parse::<u16>()) .map(|p| p.parse::<u16>())
.map(|p| p.unwrap_or(0)); // Treat errors as 0. .map(|p| p.unwrap_or(0)); // Treat errors as 0.
self.has_sgr_sequences = true;
while let Some(p) = iter.next() { while let Some(p) = iter.next() {
match p { match p {
0 => self.sgr_reset(), 0 => self.sgr_reset(),
@ -214,6 +228,28 @@ impl Attributes {
_ => format!("\x1B[{}m", color), _ => format!("\x1B[{}m", color),
} }
} }
/// Gets an ANSI escape sequence to reset all the known attributes.
pub fn to_reset_sequence(&self) -> String {
let mut buf = String::with_capacity(17);
// TODO: Enable me in a later pull request.
// if self.has_sgr_sequences {
// buf.push_str("\x1B[m");
// }
if !self.hyperlink.is_empty() {
buf.push_str("\x1B]8;;\x1B\\"); // Disable hyperlink.
}
// TODO: Enable me in a later pull request.
// if !self.charset.is_empty() {
// // https://espterm.github.io/docs/VT100%20escape%20codes.html
// buf.push_str("\x1B(B\x1B)B"); // setusg0 and setusg1
// }
buf
}
} }
impl Display for Attributes { impl Display for Attributes {

View File

@ -1966,7 +1966,7 @@ fn ansi_hyperlink_emitted_when_wrapped() {
.write_stdin("\x1B]8;;http://example.com/\x1B\\Hyperlinks..........Wrap across lines.\n") .write_stdin("\x1B]8;;http://example.com/\x1B\\Hyperlinks..........Wrap across lines.\n")
.assert() .assert()
.success() .success()
.stdout("\x1B]8;;http://example.com/\x1B\\\x1B]8;;http://example.com/\x1B\\Hyperlinks..........\n\x1B]8;;http://example.com/\x1B\\Wrap across lines.\n") .stdout("\x1B]8;;http://example.com/\x1B\\\x1B]8;;http://example.com/\x1B\\Hyperlinks..........\x1B]8;;\x1B\\\n\x1B]8;;http://example.com/\x1B\\Wrap across lines.\n")
// FIXME: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ should not be emitted twice. // FIXME: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ should not be emitted twice.
.stderr(""); .stderr("");
} }