use std::fmt::Write;
use crate::{glyphs::{ELLIPSIS_GLYPH, SPACER_GLYPH},
ColWidth,
GCStringExt as _,
InlineString};
pub fn contains_ansi_escape_sequence(text: &str) -> bool {
text.chars().any(|it| it == '\x1b')
}
pub fn remove_escaped_quotes(s: &str) -> String {
s.replace("\\\"", "\"").replace("\"", "")
}
pub fn truncate_from_right(
string: &str,
arg_width: impl Into<ColWidth>,
pad: bool,
) -> InlineString {
let display_width = arg_width.into();
let string_gcs = string.grapheme_string();
let string_display_width = string_gcs.display_width;
if string_display_width > display_width {
let postfix = ELLIPSIS_GLYPH;
let postfix_gcs = postfix.grapheme_string();
let postfix_display_width = postfix_gcs.display_width;
let truncate_cols_from_right = string_display_width - display_width;
let truncated_text =
string_gcs.trunc_end_by(truncate_cols_from_right + postfix_display_width);
let mut acc = InlineString::new();
_ = write!(acc, "{}{}", truncated_text, postfix_gcs.string);
acc
}
else if pad {
use crate::glyphs::SPACER_GLYPH as SPACER;
string_gcs.pad_end_to_fit(SPACER, display_width)
}
else {
string.into()
}
}
pub fn truncate_from_left(
string: &str,
arg_width: impl Into<ColWidth>,
pad: bool,
) -> InlineString {
let display_width = arg_width.into();
let string_gcs = string.grapheme_string();
let string_display_width = string_gcs.display_width;
if string_display_width > display_width {
let prefix = ELLIPSIS_GLYPH;
let prefix_gcs = prefix.grapheme_string();
let prefix_display_width = prefix_gcs.display_width;
let truncate_cols_from_left = string_display_width - display_width;
let truncated_text =
string_gcs.trunc_start_by(truncate_cols_from_left + prefix_display_width);
let mut acc = InlineString::new();
_ = write!(acc, "{}{}", prefix_gcs.string, truncated_text);
acc
}
else if pad {
string_gcs.pad_start_to_fit(SPACER_GLYPH, display_width)
} else {
string.into()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{ast, new_style, tui_color, width};
#[test]
fn test_contains_ansi_escape_sequence() {
use crate::assert_eq2;
assert_eq2!(
contains_ansi_escape_sequence(
"\x1b[31mThis is red text.\x1b[0m And this is normal text."
),
true
);
assert_eq2!(contains_ansi_escape_sequence("This is normal text."), false);
assert_eq2!(
contains_ansi_escape_sequence(
&ast(
"Print a formatted (bold, italic, underline) string w/ ANSI color codes.",
new_style!(
bold italic underline
color_fg: {tui_color!(50, 50, 50)}
color_bg: {tui_color!(100, 200, 1)}
),
)
.to_string()
),
true
);
}
#[test]
fn test_truncate_or_pad_from_right() {
let long_string = "Hello, world!";
let short_string = "Hi!";
let width = width(10);
assert_eq!(truncate_from_right(long_string, width, true), "Hello, wo…");
assert_eq!(truncate_from_right(short_string, width, true), "Hi! ");
assert_eq!(truncate_from_right(long_string, width, false), "Hello, wo…");
assert_eq!(truncate_from_right(short_string, width, false), "Hi!");
}
#[test]
fn test_truncate_or_pad_from_left() {
let long_string = "Hello, world!";
let short_string = "Hi!";
let width = width(10);
assert_eq!(truncate_from_left(long_string, width, true), "…o, world!");
assert_eq!(truncate_from_left(short_string, width, true), " Hi!");
assert_eq!(truncate_from_left(long_string, width, false), "…o, world!");
assert_eq!(truncate_from_left(short_string, width, false), "Hi!");
}
}