mirror of
https://github.com/nushell/nushell.git
synced 2025-04-14 08:18:17 +02:00
Fix unused space when truncation is used and header on border is configured (#13353)
Somehow this logic was missed on my end. ( I mean I was not even thinking about it in original patch 😄 ) Please recheck Added a regression test too. close #13336 cc: @fdncred
This commit is contained in:
parent
ccd0160c32
commit
4bd87d0496
@ -2895,3 +2895,9 @@ fn table_kv_header_on_separator_trim_algorithm() {
|
|||||||
let actual = nu!("$env.config.table.header_on_separator = true; {key1: '111111111111111111111111111111111111111111111111111111111111'} | table --width=60 --theme basic");
|
let actual = nu!("$env.config.table.header_on_separator = true; {key1: '111111111111111111111111111111111111111111111111111111111111'} | table --width=60 --theme basic");
|
||||||
assert_eq!(actual.out, "+------+---------------------------------------------------+| key1 | 1111111111111111111111111111111111111111111111111 || | 11111111111 |+------+---------------------------------------------------+");
|
assert_eq!(actual.out, "+------+---------------------------------------------------+| key1 | 1111111111111111111111111111111111111111111111111 || | 11111111111 |+------+---------------------------------------------------+");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn table_general_header_on_separator_trim_algorithm() {
|
||||||
|
let actual = nu!("$env.config.table.header_on_separator = true; [[a b]; ['11111111111111111111111111111111111111' 2] ] | table --width=20 --theme basic");
|
||||||
|
assert_eq!(actual.out, "+-#-+----a-----+-b-+| 0 | 11111111 | 2 || | 11111111 | || | 11111111 | || | 11111111 | || | 111111 | |+---+----------+---+");
|
||||||
|
}
|
||||||
|
@ -255,7 +255,8 @@ fn draw_table(
|
|||||||
align_table(&mut table, alignments, with_index, with_header, with_footer);
|
align_table(&mut table, alignments, with_index, with_header, with_footer);
|
||||||
colorize_table(&mut table, styles, with_index, with_header, with_footer);
|
colorize_table(&mut table, styles, with_index, with_header, with_footer);
|
||||||
|
|
||||||
let width_ctrl = TableWidthCtrl::new(widths, cfg, termwidth);
|
let pad = indent.0 + indent.1;
|
||||||
|
let width_ctrl = TableWidthCtrl::new(widths, cfg, termwidth, pad);
|
||||||
|
|
||||||
if with_header && border_header {
|
if with_header && border_header {
|
||||||
set_border_head(&mut table, with_footer, width_ctrl);
|
set_border_head(&mut table, with_footer, width_ctrl);
|
||||||
@ -336,12 +337,18 @@ fn table_to_string(table: Table, termwidth: usize) -> Option<String> {
|
|||||||
struct TableWidthCtrl {
|
struct TableWidthCtrl {
|
||||||
width: Vec<usize>,
|
width: Vec<usize>,
|
||||||
cfg: NuTableConfig,
|
cfg: NuTableConfig,
|
||||||
max: usize,
|
width_max: usize,
|
||||||
|
pad: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TableWidthCtrl {
|
impl TableWidthCtrl {
|
||||||
fn new(width: Vec<usize>, cfg: NuTableConfig, max: usize) -> Self {
|
fn new(width: Vec<usize>, cfg: NuTableConfig, max: usize, pad: usize) -> Self {
|
||||||
Self { width, cfg, max }
|
Self {
|
||||||
|
width,
|
||||||
|
cfg,
|
||||||
|
width_max: max,
|
||||||
|
pad,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -354,19 +361,20 @@ impl TableOption<NuRecords, CompleteDimensionVecRecords<'_>, ColoredConfig> for
|
|||||||
) {
|
) {
|
||||||
let total_width = get_total_width2(&self.width, cfg);
|
let total_width = get_total_width2(&self.width, cfg);
|
||||||
|
|
||||||
if total_width > self.max {
|
if total_width > self.width_max {
|
||||||
let has_header = self.cfg.with_header && rec.count_rows() > 1;
|
let has_header = self.cfg.with_header && rec.count_rows() > 1;
|
||||||
let trim_as_head = has_header && self.cfg.header_on_border;
|
let trim_as_head = has_header && self.cfg.header_on_border;
|
||||||
|
|
||||||
TableTrim {
|
TableTrim::new(
|
||||||
max: self.max,
|
self.width,
|
||||||
strategy: self.cfg.trim,
|
self.width_max,
|
||||||
width: self.width,
|
self.cfg.trim,
|
||||||
trim_as_head,
|
trim_as_head,
|
||||||
}
|
self.pad,
|
||||||
|
)
|
||||||
.change(rec, cfg, dim);
|
.change(rec, cfg, dim);
|
||||||
} else if self.cfg.expand && self.max > total_width {
|
} else if self.cfg.expand && self.width_max > total_width {
|
||||||
Settings::new(SetDimensions(self.width), Width::increase(self.max))
|
Settings::new(SetDimensions(self.width), Width::increase(self.width_max))
|
||||||
.change(rec, cfg, dim)
|
.change(rec, cfg, dim)
|
||||||
} else {
|
} else {
|
||||||
SetDimensions(self.width).change(rec, cfg, dim);
|
SetDimensions(self.width).change(rec, cfg, dim);
|
||||||
@ -376,9 +384,28 @@ impl TableOption<NuRecords, CompleteDimensionVecRecords<'_>, ColoredConfig> for
|
|||||||
|
|
||||||
struct TableTrim {
|
struct TableTrim {
|
||||||
width: Vec<usize>,
|
width: Vec<usize>,
|
||||||
|
width_max: usize,
|
||||||
strategy: TrimStrategy,
|
strategy: TrimStrategy,
|
||||||
max: usize,
|
|
||||||
trim_as_head: bool,
|
trim_as_head: bool,
|
||||||
|
pad: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TableTrim {
|
||||||
|
fn new(
|
||||||
|
width: Vec<usize>,
|
||||||
|
width_max: usize,
|
||||||
|
strategy: TrimStrategy,
|
||||||
|
trim_as_head: bool,
|
||||||
|
pad: usize,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
width,
|
||||||
|
strategy,
|
||||||
|
pad,
|
||||||
|
width_max,
|
||||||
|
trim_as_head,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TableOption<NuRecords, CompleteDimensionVecRecords<'_>, ColoredConfig> for TableTrim {
|
impl TableOption<NuRecords, CompleteDimensionVecRecords<'_>, ColoredConfig> for TableTrim {
|
||||||
@ -395,13 +422,37 @@ impl TableOption<NuRecords, CompleteDimensionVecRecords<'_>, ColoredConfig> for
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// even though it's safe to trim columns by header there might be left unused space
|
||||||
|
// so we do use it if possible prioritizing left columns
|
||||||
|
|
||||||
let headers = recs[0].to_owned();
|
let headers = recs[0].to_owned();
|
||||||
for (i, head) in headers.into_iter().enumerate() {
|
let headers_widths = headers
|
||||||
let head_width = CellInfo::width(&head);
|
.iter()
|
||||||
|
.map(CellInfo::width)
|
||||||
|
.map(|v| v + self.pad)
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
let min_width_use = get_total_width2(&headers_widths, cfg);
|
||||||
|
|
||||||
|
let mut free_width = self.width_max.saturating_sub(min_width_use);
|
||||||
|
|
||||||
|
for (i, head_width) in headers_widths.into_iter().enumerate() {
|
||||||
|
let head_width = head_width - self.pad;
|
||||||
|
let column_width = self.width[i] - self.pad; // safe to assume width is bigger then paddding
|
||||||
|
|
||||||
|
let mut use_width = head_width;
|
||||||
|
if free_width > 0 {
|
||||||
|
// it's safe to assume that column_width is always bigger or equal to head_width
|
||||||
|
debug_assert!(column_width >= head_width);
|
||||||
|
|
||||||
|
let additional_width = min(free_width, column_width - head_width);
|
||||||
|
free_width -= additional_width;
|
||||||
|
use_width += additional_width;
|
||||||
|
}
|
||||||
|
|
||||||
match &self.strategy {
|
match &self.strategy {
|
||||||
TrimStrategy::Wrap { try_to_keep_words } => {
|
TrimStrategy::Wrap { try_to_keep_words } => {
|
||||||
let mut wrap = Width::wrap(head_width);
|
let mut wrap = Width::wrap(use_width);
|
||||||
if *try_to_keep_words {
|
if *try_to_keep_words {
|
||||||
wrap = wrap.keep_words();
|
wrap = wrap.keep_words();
|
||||||
}
|
}
|
||||||
@ -411,7 +462,7 @@ impl TableOption<NuRecords, CompleteDimensionVecRecords<'_>, ColoredConfig> for
|
|||||||
.change(recs, cfg, dims);
|
.change(recs, cfg, dims);
|
||||||
}
|
}
|
||||||
TrimStrategy::Truncate { suffix } => {
|
TrimStrategy::Truncate { suffix } => {
|
||||||
let mut truncate = Width::truncate(self.max);
|
let mut truncate = Width::truncate(use_width);
|
||||||
if let Some(suffix) = suffix {
|
if let Some(suffix) = suffix {
|
||||||
truncate = truncate.suffix(suffix).suffix_try_color(true);
|
truncate = truncate.suffix(suffix).suffix_try_color(true);
|
||||||
}
|
}
|
||||||
@ -428,7 +479,7 @@ impl TableOption<NuRecords, CompleteDimensionVecRecords<'_>, ColoredConfig> for
|
|||||||
|
|
||||||
match self.strategy {
|
match self.strategy {
|
||||||
TrimStrategy::Wrap { try_to_keep_words } => {
|
TrimStrategy::Wrap { try_to_keep_words } => {
|
||||||
let mut wrap = Width::wrap(self.max).priority::<PriorityMax>();
|
let mut wrap = Width::wrap(self.width_max).priority::<PriorityMax>();
|
||||||
if try_to_keep_words {
|
if try_to_keep_words {
|
||||||
wrap = wrap.keep_words();
|
wrap = wrap.keep_words();
|
||||||
}
|
}
|
||||||
@ -436,7 +487,7 @@ impl TableOption<NuRecords, CompleteDimensionVecRecords<'_>, ColoredConfig> for
|
|||||||
Settings::new(SetDimensions(self.width), wrap).change(recs, cfg, dims);
|
Settings::new(SetDimensions(self.width), wrap).change(recs, cfg, dims);
|
||||||
}
|
}
|
||||||
TrimStrategy::Truncate { suffix } => {
|
TrimStrategy::Truncate { suffix } => {
|
||||||
let mut truncate = Width::truncate(self.max).priority::<PriorityMax>();
|
let mut truncate = Width::truncate(self.width_max).priority::<PriorityMax>();
|
||||||
if let Some(suffix) = suffix {
|
if let Some(suffix) = suffix {
|
||||||
truncate = truncate.suffix(suffix).suffix_try_color(true);
|
truncate = truncate.suffix(suffix).suffix_try_color(true);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user