diff --git a/Cargo.lock b/Cargo.lock index 48c884cde7..0e443af36f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1994,8 +1994,10 @@ dependencies = [ "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "term 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "toml-query 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", "which 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3165,6 +3167,16 @@ dependencies = [ "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "term_size" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "termcolor" version = "1.0.5" @@ -3186,6 +3198,7 @@ name = "textwrap" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ + "term_size 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4080,6 +4093,7 @@ dependencies = [ "checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" "checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" "checksum term 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "edd106a334b7657c10b7c540a0106114feadeb4dc314513e97df481d5d966f42" +"checksum term_size 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9e5b9a66db815dcfd2da92db471106457082577c3c278d4138ab3e3b4e189327" "checksum termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "96d6098003bde162e4277c70665bd87c326f5a0c3f3fbfb285787fa482d54e6e" "checksum termios 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "72b620c5ea021d75a735c943269bb07d30c9b77d6ac6b236bc8b5c496ef05625" "checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" diff --git a/Cargo.toml b/Cargo.toml index 4d4a2d0ebf..58d097b04e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -84,6 +84,8 @@ onig_sys = "=69.1.0" heim = {git = "https://github.com/heim-rs/heim.git"} which = "2.0.1" battery = "0.7.4" +textwrap = {version = "0.11.0", features = ["term_size"]} +unicode-width = "0.1.5" [dev-dependencies] pretty_assertions = "0.6.1" diff --git a/src/format/table.rs b/src/format/table.rs index c6af90fdc9..76ea37ee9a 100644 --- a/src/format/table.rs +++ b/src/format/table.rs @@ -4,6 +4,7 @@ use crate::prelude::*; use ansi_term::Color; use derive_new::new; use prettytable::format::{FormatBuilder, LinePosition, LineSeparator}; +use textwrap::fill; use prettytable::{color, Attr, Cell, Row, Table}; @@ -58,9 +59,70 @@ impl TableView { entries.push(row); } + let mut max_per_column = vec![]; + if values.len() > 1 { headers.insert(0, format!("#")); } + + for head in 0..headers.len() { + let mut current_row_max = 0; + for row in 0..values.len() { + if entries[row][head].len() > current_row_max { + current_row_max = entries[row][head].len(); + } + } + max_per_column.push(current_row_max); + } + + let termwidth = textwrap::termwidth() - 5; + + // Make sure we have enough space for the columns we have + let max_num_of_columns = termwidth / 7; + + // If we have too many columns, truncate the table + if max_num_of_columns < headers.len() { + headers.truncate(max_num_of_columns); + for row in 0..entries.len() { + entries[row].truncate(max_num_of_columns); + } + + headers.push("...".to_string()); + for row in 0..entries.len() { + entries[row].push("...".to_string()); + } + } + + // Measure how big our columns need to be + let max_naive_column_width = termwidth / headers.len(); + + let mut num_overages = 0; + let mut underage_sum = 0; + for idx in 0..headers.len() { + if max_per_column[idx] > max_naive_column_width { + num_overages += 1; + } else { + underage_sum += max_per_column[idx]; + } + } + + // Wrap cells as needed + for head in 0..headers.len() { + if max_per_column[head] > max_naive_column_width { + let max_column_width = (termwidth - underage_sum) / num_overages; + //Account for the separator + let max_column_width = if max_column_width > 1 { + max_column_width - 2 + } else { + max_column_width + }; + headers[head] = fill(&headers[head], max_column_width); + for row in 0..entries.len() { + entries[row][head] = fill(&entries[row][head], max_column_width); + } + } + } + Some(TableView { headers, entries }) } }