diff options
author | Ethan P <eth-p+git@hidden.email> | 2023-04-17 19:19:49 -0700 |
---|---|---|
committer | Ethan P. <eth-p+git@hidden.email> | 2024-02-09 22:09:39 -0800 |
commit | 1023399c5e20edac8710e9f19dc72b6a95fd257d (patch) | |
tree | 848e6bc9504746734d322450dd44a8c315645af0 /src | |
parent | 6549e26f5d3923078b482d30bc4ed90b2f5710c9 (diff) |
Remove hyperlink when wrapping lines
Diffstat (limited to 'src')
-rw-r--r-- | src/printer.rs | 11 | ||||
-rw-r--r-- | src/vscreen.rs | 40 |
2 files changed, 45 insertions, 6 deletions
diff --git a/src/printer.rs b/src/printer.rs index 6d495777..f413fdc3 100644 --- a/src/printer.rs +++ b/src/printer.rs @@ -598,12 +598,12 @@ impl<'a> Printer for InteractivePrinter<'a> { match chunk { // Regular 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'); write!( handle, - "{}", + "{}{}", as_terminal_escaped( style, &format!("{}{}", self.ansi_style, text_trimmed), @@ -611,9 +611,11 @@ impl<'a> Printer for InteractivePrinter<'a> { colored_output, italics, background_color - ) + ), + self.ansi_style.to_reset_sequence(), )?; + // Pad the rest of the line. if text.len() != text_trimmed.len() { if let Some(background_color) = background_color { let ansi_style = Style { @@ -693,7 +695,7 @@ impl<'a> Printer for InteractivePrinter<'a> { // It wraps. write!( handle, - "{}\n{}", + "{}{}\n{}", as_terminal_escaped( style, &format!("{}{}", self.ansi_style, line_buf), @@ -702,6 +704,7 @@ impl<'a> Printer for InteractivePrinter<'a> { self.config.use_italic_text, background_color ), + self.ansi_style.to_reset_sequence(), panel_wrap.clone().unwrap() )?; diff --git a/src/vscreen.rs b/src/vscreen.rs index 7e2b8cd1..c902d42b 100644 --- a/src/vscreen.rs +++ b/src/vscreen.rs @@ -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 { @@ -35,6 +42,8 @@ impl Display for AnsiStyle { } struct Attributes { + has_sgr_sequences: bool, + foreground: String, background: String, underlined: String, @@ -67,16 +76,18 @@ struct Attributes { strike: String, /// The hyperlink sequence. - /// FORMAT: \x1B]8;<ID>;<HREF>\e\\ + /// FORMAT: \x1B]8;{ID};{URL}\e\\ /// /// `\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, } impl Attributes { pub fn new() -> Self { Attributes { + has_sgr_sequences: false, + foreground: "".to_owned(), background: "".to_owned(), underlined: "".to_owned(), @@ -135,6 +146,8 @@ impl Attributes { } fn sgr_reset(&mut self) { + self.has_sgr_sequences = false; + self.foreground.clear(); self.background.clear(); self.underlined.clear(); @@ -152,6 +165,7 @@ impl Attributes { .map(|p| p.parse::<u16>()) .map(|p| p.unwrap_or(0)); // Treat errors as 0. + self.has_sgr_sequences = true; while let Some(p) = iter.next() { match p { 0 => self.sgr_reset(), @@ -214,6 +228,28 @@ impl Attributes { _ => 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 { |