diff --git a/crates/tty7-cli/src/output.rs b/crates/tty7-cli/src/output.rs index 9438a79b..53abae34 100644 --- a/crates/tty7-cli/src/output.rs +++ b/crates/tty7-cli/src/output.rs @@ -129,12 +129,27 @@ pub(crate) fn printable(s: &str) -> std::borrow::Cow<'_, str> { /// /// A full classic terminal width, so every realistic name and path still /// prints whole. `--json` is the output for anything that must not be cut. +/// +/// The last column is exempt. Nothing is padded against it — `render_row` +/// trims the end of every line — so its width cannot push anything out of +/// line, and cutting it is pure loss: `doctor` puts its findings there, and a +/// config path with its middle replaced by an ellipsis is the one thing the +/// reader of a diagnostic needed whole. const MAX_CELL: usize = 80; pub fn table(header: &[&str], rows: &[Vec]) -> String { + let last = header.len().saturating_sub(1); let rows: Vec> = rows .iter() - .map(|row| row.iter().map(|c| clamp(&printable(c), MAX_CELL)).collect()) + .map(|row| { + row.iter() + .enumerate() + .map(|(i, c)| match i == last { + true => printable(c).into_owned(), + false => clamp(&printable(c), MAX_CELL), + }) + .collect() + }) .collect(); let rows = &rows; let mut widths: Vec = header.iter().map(|h| width(h)).collect(); @@ -497,6 +512,26 @@ mod tests { assert!(widths.iter().all(|w| *w <= widest)); } + #[test] + fn the_last_column_is_never_cut() { + // `doctor` reports its findings in the last column, and a config path + // with an ellipsis through the middle is the one thing the reader of a + // diagnostic needed whole. Nothing is padded against the last column, + // so its width costs no alignment. + let long = format!("/private/var/folders/{}/config", "x".repeat(200)); + let out = table( + &["CHECK", "RESULT"], + &[ + vec!["config".into(), long.clone()], + vec!["server".into(), "ok".into()], + ], + ); + assert!(out.contains(&long), "the last column was cut"); + // The row that says `ok` is not dragged out to meet it. + let ok_row = out.lines().find(|l| l.contains("server")).unwrap(); + assert!(width(ok_row) < 40, "a short row was padded to the long one"); + } + #[test] fn wide_characters_are_padded_by_display_width_not_byte_length() { // "项目" is 6 bytes but occupies 4 columns. Padding by len() would add