From a9252c5075916f9a43fec88800425c1bc14a8bfb Mon Sep 17 00:00:00 2001 From: Maxim Zhiburt Date: Sat, 10 May 2025 02:21:33 +0300 Subject: [PATCH] nu-table: (table --expand) Remove unnessary use of truncate logic (#15727) A small optimization; Must be measurable on large tables. In case of `scope commands` for me seems like a bit faster in debug (~100ms). But I've had like a few runs. If someone is interested to check if it's any faster would be nice to see it :) cc: @fdncred --- crates/nu-table/src/table.rs | 34 +++++++++++++++++++-------- crates/nu-table/src/types/expanded.rs | 6 ++--- 2 files changed, 27 insertions(+), 13 deletions(-) diff --git a/crates/nu-table/src/table.rs b/crates/nu-table/src/table.rs index 0300705c5f..8ebe165221 100644 --- a/crates/nu-table/src/table.rs +++ b/crates/nu-table/src/table.rs @@ -241,6 +241,13 @@ impl NuTable { build_table(self, termwidth) } + /// Converts a table to a String. + /// + /// It returns None in case where table cannot be fit to a terminal width. + pub fn draw_unchecked(self, termwidth: usize) -> Option { + build_table_unchecked(self, termwidth) + } + /// Return a total table width. pub fn total_width(&self) -> usize { let config = create_config(&self.config.theme, false, None); @@ -327,6 +334,22 @@ impl HeadInfo { } } +fn build_table_unchecked(mut t: NuTable, termwidth: usize) -> Option { + if t.count_columns() == 0 || t.count_rows() == 0 { + return Some(String::new()); + } + + let widths = std::mem::take(&mut t.widths); + let config = create_config(&t.config.theme, false, None); + let totalwidth = get_total_width2(&t.widths, &config); + let widths = WidthEstimation::new(widths.clone(), widths, totalwidth, false, false); + + let head = remove_header_if(&mut t); + table_insert_footer_if(&mut t); + + draw_table(t, widths, head, termwidth) +} + fn build_table(mut t: NuTable, termwidth: usize) -> Option { if t.count_columns() == 0 || t.count_rows() == 0 { return Some(String::new()); @@ -583,7 +606,7 @@ impl TableOption> for } // NOTE: just an optimization; to not recalculate it internally - SetDimensions(self.width.needed).change(recs, cfg, dims); + dims.set_widths(self.width.needed); } } @@ -1021,15 +1044,6 @@ fn convert_alignment(alignment: nu_color_config::Alignment) -> AlignmentHorizont } } -// TODO: expose it get_dims_mut() -struct SetDimensions(Vec); - -impl TableOption> for SetDimensions { - fn change(self, _: &mut R, _: &mut ColoredConfig, dims: &mut CompleteDimensionVecRecords<'_>) { - dims.set_widths(self.0); - } -} - fn build_width(records: R, pad: usize) -> Vec where R: Records, diff --git a/crates/nu-table/src/types/expanded.rs b/crates/nu-table/src/types/expanded.rs index 52563efa3b..61e4b2069b 100644 --- a/crates/nu-table/src/types/expanded.rs +++ b/crates/nu-table/src/types/expanded.rs @@ -448,7 +448,7 @@ fn expand_value(value: &Value, width: usize, cfg: &Cfg<'_>) -> CellResult { match table { Some(mut out) => { table_apply_config(&mut out, cfg); - let value = out.table.draw(width); + let value = out.table.draw_unchecked(width); match value { Some(value) => Ok(Some(CellOutput::clean(value, out.count_rows, true))), None => Ok(None), @@ -556,7 +556,7 @@ fn expand_entry(item: &Value, cfg: Cfg<'_>) -> CellOutput { table_apply_config(&mut out, &cfg); - let table = out.table.draw(usize::MAX); + let table = out.table.draw_unchecked(cfg.opts.width); match table { Some(table) => CellOutput::clean(table, out.count_rows, false), None => { @@ -622,7 +622,7 @@ fn maybe_expand_table(mut out: TableOutput, term_width: usize) -> StringResult { } } - let table = out.table.draw(term_width); + let table = out.table.draw_unchecked(term_width); Ok(table) }