summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEthan P <eth-p+git@hidden.email>2023-04-17 19:19:49 -0700
committerEthan P. <eth-p+git@hidden.email>2024-02-09 22:09:39 -0800
commit1023399c5e20edac8710e9f19dc72b6a95fd257d (patch)
tree848e6bc9504746734d322450dd44a8c315645af0
parent6549e26f5d3923078b482d30bc4ed90b2f5710c9 (diff)
Remove hyperlink when wrapping lines
-rw-r--r--src/printer.rs11
-rw-r--r--src/vscreen.rs40
-rw-r--r--tests/integration_tests.rs2
3 files changed, 46 insertions, 7 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 {
diff --git a/tests/integration_tests.rs b/tests/integration_tests.rs
index bb4c4668..ecc37ed7 100644
--- a/tests/integration_tests.rs
+++ b/tests/integration_tests.rs
@@ -1966,7 +1966,7 @@ fn ansi_hyperlink_emitted_when_wrapped() {
.write_stdin("\x1B]8;;http://example.com/\x1B\\Hyperlinks..........Wrap across lines.\n")
.assert()
.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.
.stderr("");
}