Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 17 additions & 9 deletions src/cargo/util/progress.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ struct Format {
max_width: usize,
max_print: usize,
term_integration: TerminalIntegration,
unicode: bool,
}

/// Controls terminal progress integration via OSC sequences.
Expand Down Expand Up @@ -229,6 +230,7 @@ impl<'gctx> Progress<'gctx> {
// even on narrow (e.g. 80 char) terminals.
max_print: 50,
term_integration: TerminalIntegration::from_config(gctx),
unicode: gctx.shell().err_unicode(),
},
name: name.to_string(),
done: false,
Expand Down Expand Up @@ -261,8 +263,7 @@ impl<'gctx> Progress<'gctx> {
/// * `cur` should be how far along the progress is.
/// * `max` is the maximum value for the progress bar.
/// * `msg` is a small piece of text to display at the end of the progress
/// bar. It will be truncated with `...` if it does not fit on the
/// terminal.
/// bar. It will be truncated with `…` if it does not fit on the terminal.
///
/// This may not actually update the display if `tick` is being called too
/// quickly.
Expand Down Expand Up @@ -521,20 +522,23 @@ impl Format {
fn render(&self, string: &mut String, msg: &str) {
let mut avail_msg_len = self.max_width - string.len() - 15;
let mut ellipsis_pos = 0;
if avail_msg_len <= 3 {

let (ellipsis, ellipsis_width) = if self.unicode { ("…", 1) } else { ("...", 3) };

if avail_msg_len <= ellipsis_width {
return;
}
for c in msg.chars() {
let display_width = c.width().unwrap_or(0);
if avail_msg_len >= display_width {
avail_msg_len -= display_width;
string.push(c);
if avail_msg_len >= 3 {
if avail_msg_len >= ellipsis_width {
ellipsis_pos = string.len();
}
} else {
string.truncate(ellipsis_pos);
string.push_str("...");
string.push_str(ellipsis);
break;
}
}
Expand Down Expand Up @@ -569,6 +573,7 @@ fn test_progress_status() {
max_print: 40,
max_width: 60,
term_integration: TerminalIntegration::new(false),
unicode: true,
};
assert_eq!(
format.progress_status(0, 4, ""),
Expand Down Expand Up @@ -610,7 +615,7 @@ fn test_progress_status() {
);
assert_eq!(
format.progress_status(3, 4, ": msg that's just fit"),
Some("[=============> ] 3/4: msg that's just...".to_string())
Some("[=============> ] 3/4: msg that's just f…".to_string())
);

// combining diacritics have width zero and thus can fit max_width.
Expand All @@ -623,16 +628,16 @@ fn test_progress_status() {
// some non-ASCII ellipsize test
assert_eq!(
format.progress_status(3, 4, "_123456789123456e\u{301}\u{301}8\u{301}90a"),
Some("[=============> ] 3/4_123456789123456e\u{301}\u{301}...".to_string())
Some("[=============> ] 3/4_123456789123456e\u{301}\u{301}8\u{301}9…".to_string())
);
assert_eq!(
format.progress_status(3, 4, ":每個漢字佔據了兩個字元"),
Some("[=============> ] 3/4:每個漢字佔據了...".to_string())
Some("[=============> ] 3/4:每個漢字佔據了兩…".to_string())
);
assert_eq!(
// handle breaking at middle of character
format.progress_status(3, 4, ":-每個漢字佔據了兩個字元"),
Some("[=============> ] 3/4:-每個漢字佔據了...".to_string())
Some("[=============> ] 3/4:-每個漢字佔據了兩…".to_string())
);
}

Expand All @@ -643,6 +648,7 @@ fn test_progress_status_percentage() {
max_print: 40,
max_width: 60,
term_integration: TerminalIntegration::new(false),
unicode: true,
};
assert_eq!(
format.progress_status(0, 77, ""),
Expand All @@ -669,6 +675,7 @@ fn test_progress_status_too_short() {
max_print: 25,
max_width: 25,
term_integration: TerminalIntegration::new(false),
unicode: true,
};
assert_eq!(
format.progress_status(1, 1, ""),
Expand All @@ -680,6 +687,7 @@ fn test_progress_status_too_short() {
max_print: 24,
max_width: 24,
term_integration: TerminalIntegration::new(false),
unicode: true,
};
assert_eq!(format.progress_status(1, 1, ""), None);
}
Expand Down
Loading