Skip to content

Commit d7a1da4

Browse files
committed
fix truncation on ascii chars
1 parent ebb9956 commit d7a1da4

File tree

2 files changed

+23
-28
lines changed

2 files changed

+23
-28
lines changed

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ readme = "README.md"
1313
exclude = ["screenshots/*"]
1414

1515
[dependencies]
16-
console = { version = "0.15", default-features = false, features = ["ansi-parsing"] }
16+
# console = { version = "0.16", default-features = false, features = ["ansi-parsing"] }
17+
console = { git = "https://github.com/remi-dupre/console.git", branch = "ansi-slice", default-features = false, features = ["ansi-parsing"] }
1718
futures-core = { version = "0.3", default-features = false, optional = true }
1819
number_prefix = "0.4"
1920
portable-atomic = "1.0.0"

src/style.rs

Lines changed: 21 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use std::mem;
44
#[cfg(not(target_arch = "wasm32"))]
55
use std::time::Instant;
66

7-
use console::{measure_text_width, Style};
7+
use console::{measure_text_width, slice_str, Style};
88
#[cfg(target_arch = "wasm32")]
99
use instant::Instant;
1010
#[cfg(feature = "unicode-segmentation")]
@@ -684,27 +684,6 @@ impl<'a> fmt::Display for RepeatedStringDisplay<'a> {
684684
}
685685
}
686686

687-
fn truncate_to_fit(text: &str, align: Alignment, target_width: usize) -> Option<&str> {
688-
let mut start = 0;
689-
let mut end = text.len();
690-
let mut left_priority = true;
691-
692-
// Iter next truncation positions from left or right
693-
let mut char_pos_from_left = text.char_indices().map(|(idx, _)| idx).skip(1);
694-
let mut char_pos_from_right = text.char_indices().map(|(idx, _)| idx).rev();
695-
696-
while measure_text_width(text.get(start..end).unwrap_or("")) > target_width {
697-
match (align, left_priority) {
698-
(Alignment::Left, _) | (Alignment::Center, true) => end = char_pos_from_right.next()?,
699-
_ => start = char_pos_from_left.next()?,
700-
}
701-
702-
left_priority = !left_priority;
703-
}
704-
705-
text.get(start..end)
706-
}
707-
708687
struct PaddedStringDisplay<'a> {
709688
str: &'a str,
710689
width: usize,
@@ -715,11 +694,26 @@ struct PaddedStringDisplay<'a> {
715694
impl<'a> fmt::Display for PaddedStringDisplay<'a> {
716695
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
717696
let cols = measure_text_width(self.str);
697+
let text_width = measure_text_width(self.str);
698+
let excess = text_width.saturating_sub(self.width);
699+
700+
if excess > 0 {
701+
let truncated = {
702+
if self.truncate {
703+
match self.align {
704+
Alignment::Left => slice_str(self.str, "", 0..self.width, ""),
705+
Alignment::Right => slice_str(self.str, "", excess..text_width, ""),
706+
Alignment::Center => {
707+
slice_str(self.str, "", excess / 2..text_width - (excess + 1) / 2, "")
708+
}
709+
}
710+
} else {
711+
self.str.into()
712+
}
713+
};
718714

719-
if cols > self.width && self.truncate {
720-
return f
721-
.write_str(truncate_to_fit(self.str, self.align, self.width).unwrap_or(self.str));
722-
}
715+
return f.write_str(&truncated);
716+
};
723717

724718
let diff = self.width.saturating_sub(cols);
725719
let (left_pad, right_pad) = match self.align {
@@ -934,7 +928,7 @@ mod tests {
934928
let style = ProgressStyle::with_template("{wide_msg}").unwrap();
935929
state.message = TabExpandedString::NoTabs("\x1b[31mabcdefghijklmnopqrst\x1b[0m".into());
936930
style.format_state(&state, &mut buf, WIDTH);
937-
assert_eq!(&buf[0], "\x1b[31mabcdefghij");
931+
assert_eq!(&buf[0], "\x1b[31mabcdefghij\u{1b}[0m");
938932
}
939933

940934
#[test]

0 commit comments

Comments
 (0)