feat: strip ANSI escape codes for text element#169
feat: strip ANSI escape codes for text element#169bytesnake wants to merge 1 commit intoccbrown:mainfrom
Conversation
|
I'm fine with the added dependency. For inspiration, I took a look at what Ink does. Similar issue: vadimdemedes/ink#362 They strip all ANSI codes out for measurement purposes, but leave certain ANSI codes in during rendering if they wouldn't break the layout. That might be something to consider later, but I'm okay stripping all of them out for now. Their sanitization: https://github.com/vadimdemedes/ink/blob/70477953d4c97bb2e1754aef9770317d4d05f043/src/sanitize-ansi.ts#L9 Their string measurement: https://github.com/sindresorhus/string-width/blob/main/index.js I did some benchmarks to see if this would have a notable impact on performance. For strings that don't contain ANSI sequences, the impact is pretty negligible. However, I think it is worth returning the diff --git a/packages/iocraft/src/components/text.rs b/packages/iocraft/src/components/text.rs
index 247c4f8..024168c 100644
--- a/packages/iocraft/src/components/text.rs
+++ b/packages/iocraft/src/components/text.rs
@@ -228,7 +228,7 @@ impl Component for Text {
underline: props.decoration == TextDecoration::Underline,
italic: props.italic,
};
- self.content = strip_ansi(&props.content);
+ self.content = strip_ansi(&props.content).into_owned();
self.wrap = props.wrap;
self.align = props.align;
updater.set_measure_func(Self::measure_func(self.content.clone(), props.wrap));
diff --git a/packages/iocraft/src/strip_ansi.rs b/packages/iocraft/src/strip_ansi.rs
index 56f711e..2fcbd28 100644
--- a/packages/iocraft/src/strip_ansi.rs
+++ b/packages/iocraft/src/strip_ansi.rs
@@ -1,5 +1,5 @@
-use std::sync::LazyLock;
use regex::Regex;
+use std::{borrow::Cow, sync::LazyLock};
pub const ANSI_REGEX_PATTERN: &str = concat!(
// OSC branch
@@ -28,6 +28,6 @@ pub const ANSI_REGEX_PATTERN: &str = concat!(
static ANSI_REGEX: LazyLock<Regex> =
LazyLock::new(|| Regex::new(ANSI_REGEX_PATTERN).expect("valid ANSI regex"));
-pub(crate) fn strip_ansi(string: &str) -> String {
- ANSI_REGEX.replace_all(string, "").to_string()
+pub(crate) fn strip_ansi(string: &str) -> Cow<str> {
+ ANSI_REGEX.replace_all(string, "")
}That makes It seems like it's probably worth stripping ANSI in |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #169 +/- ##
=======================================
Coverage 90.06% 90.06%
=======================================
Files 32 33 +1
Lines 5333 5337 +4
Branches 5333 5337 +4
=======================================
+ Hits 4803 4807 +4
Misses 427 427
Partials 103 103
🚀 New features to boost your workflow:
|
What It Does
Remove ANSI escape codes for Text element. A major drawback is that this pulls in regex dependency
Related Issues
#168