forked from extern/nushell
fix https://github.com/nushell/nushell/issues/7380
This commit is contained in:
@ -8,7 +8,7 @@ use nu_protocol::{
|
||||
PipelineData, PipelineMetadata, RawStream, ShellError, Signature, Span, SyntaxShape,
|
||||
TableIndexMode, Value,
|
||||
};
|
||||
use nu_table::{string_width, Alignment, Alignments, Table as NuTable, TableTheme, TextStyle};
|
||||
use nu_table::{string_width, Alignment, Table as NuTable, TableConfig, TableTheme, TextStyle};
|
||||
use nu_utils::get_ls_colors;
|
||||
use std::sync::Arc;
|
||||
use std::time::Instant;
|
||||
@ -302,6 +302,8 @@ fn handle_table_command(
|
||||
TableView::Collapsed => build_collapsed_table(cols, vals, config, term_width),
|
||||
}?;
|
||||
|
||||
let result = strip_output_color(result, config);
|
||||
|
||||
let ctrl_c_was_triggered = || match &ctrlc {
|
||||
Some(ctrlc) => ctrlc.load(Ordering::SeqCst),
|
||||
None => false,
|
||||
@ -411,19 +413,12 @@ fn build_general_table2(
|
||||
}
|
||||
|
||||
let data_len = data.len();
|
||||
let table = NuTable::new(data, (data_len, 2), term_width, false, false);
|
||||
|
||||
let theme = load_theme_from_config(config);
|
||||
let color_hm = get_color_config(config);
|
||||
let table_config = create_table_config(config, &color_hm, data_len, false, false, false);
|
||||
|
||||
let table = table.draw_table(
|
||||
config,
|
||||
&color_hm,
|
||||
Alignments::default(),
|
||||
&theme,
|
||||
term_width,
|
||||
false,
|
||||
);
|
||||
let table = NuTable::new(data, (data_len, 2));
|
||||
|
||||
let table = table.draw(table_config, term_width);
|
||||
|
||||
Ok(table)
|
||||
}
|
||||
@ -440,16 +435,18 @@ fn build_expanded_table(
|
||||
flatten: bool,
|
||||
flatten_sep: &str,
|
||||
) -> Result<Option<String>, ShellError> {
|
||||
let theme = load_theme_from_config(config);
|
||||
let color_hm = get_color_config(config);
|
||||
let alignments = Alignments::default();
|
||||
let theme = load_theme_from_config(config);
|
||||
|
||||
// calculate the width of a key part + the rest of table so we know the rest of the table width available for value.
|
||||
let key_width = cols.iter().map(|col| string_width(col)).max().unwrap_or(0);
|
||||
let key = NuTable::create_cell(" ".repeat(key_width), TextStyle::default());
|
||||
let key_table = NuTable::new(vec![vec![key]], (1, 2), term_width, false, false);
|
||||
let key_table = NuTable::new(vec![vec![key]], (1, 2));
|
||||
let key_width = key_table
|
||||
.draw_table(config, &color_hm, alignments, &theme, usize::MAX, false)
|
||||
.draw(
|
||||
create_table_config(config, &color_hm, 1, false, false, false),
|
||||
usize::MAX,
|
||||
)
|
||||
.map(|table| string_width(&table))
|
||||
.unwrap_or(0);
|
||||
|
||||
@ -486,7 +483,6 @@ fn build_expanded_table(
|
||||
config,
|
||||
span,
|
||||
&color_hm,
|
||||
&theme,
|
||||
deep,
|
||||
flatten,
|
||||
flatten_sep,
|
||||
@ -494,21 +490,23 @@ fn build_expanded_table(
|
||||
)?;
|
||||
|
||||
match table {
|
||||
Some(mut table) => {
|
||||
Some((mut table, with_header, with_index)) => {
|
||||
// controll width via removing table columns.
|
||||
let theme = load_theme_from_config(config);
|
||||
table.truncate(remaining_width, &theme);
|
||||
|
||||
is_expanded = true;
|
||||
|
||||
let val = table.draw_table(
|
||||
let table_config = create_table_config(
|
||||
config,
|
||||
&color_hm,
|
||||
alignments,
|
||||
&theme,
|
||||
remaining_width,
|
||||
table.count_rows(),
|
||||
with_header,
|
||||
with_index,
|
||||
false,
|
||||
);
|
||||
|
||||
let val = table.draw(table_config, remaining_width);
|
||||
match val {
|
||||
Some(result) => result,
|
||||
None => return Ok(None),
|
||||
@ -573,11 +571,10 @@ fn build_expanded_table(
|
||||
}
|
||||
|
||||
let data_len = data.len();
|
||||
let table = NuTable::new(data, (data_len, 2), term_width, false, false);
|
||||
let table_config = create_table_config(config, &color_hm, data_len, false, false, false);
|
||||
let table = NuTable::new(data, (data_len, 2));
|
||||
|
||||
let table_s = table
|
||||
.clone()
|
||||
.draw_table(config, &color_hm, alignments, &theme, term_width, false);
|
||||
let table_s = table.clone().draw(table_config.clone(), term_width);
|
||||
|
||||
let table = match table_s {
|
||||
Some(s) => {
|
||||
@ -590,7 +587,8 @@ fn build_expanded_table(
|
||||
let used_percent = width as f32 / term_width as f32;
|
||||
|
||||
if width < term_width && used_percent > EXPAND_TREASHHOLD {
|
||||
table.draw_table(config, &color_hm, alignments, &theme, term_width, true)
|
||||
let table_config = table_config.expand();
|
||||
table.draw(table_config, term_width)
|
||||
} else {
|
||||
Some(s)
|
||||
}
|
||||
@ -760,15 +758,15 @@ fn make_clickable_link(
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn convert_to_table(
|
||||
row_offset: usize,
|
||||
input: &[Value],
|
||||
ctrlc: Option<Arc<AtomicBool>>,
|
||||
config: &Config,
|
||||
head: Span,
|
||||
termwidth: usize,
|
||||
color_hm: &NuColorMap,
|
||||
) -> Result<Option<NuTable>, ShellError> {
|
||||
) -> Result<Option<(NuTable, bool, bool)>, ShellError> {
|
||||
let mut headers = get_columns(input);
|
||||
let mut input = input.iter().peekable();
|
||||
let float_precision = config.float_precision as usize;
|
||||
@ -861,15 +859,9 @@ fn convert_to_table(
|
||||
}
|
||||
|
||||
let count_rows = data.len();
|
||||
let table = NuTable::new(
|
||||
data,
|
||||
(count_rows, count_columns),
|
||||
termwidth,
|
||||
with_header,
|
||||
with_index,
|
||||
);
|
||||
let table = NuTable::new(data, (count_rows, count_columns));
|
||||
|
||||
Ok(Some(table))
|
||||
Ok(Some((table, with_header, with_index)))
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
@ -881,12 +873,11 @@ fn convert_to_table2<'a>(
|
||||
config: &Config,
|
||||
head: Span,
|
||||
color_hm: &NuColorMap,
|
||||
theme: &TableTheme,
|
||||
deep: Option<usize>,
|
||||
flatten: bool,
|
||||
flatten_sep: &str,
|
||||
available_width: usize,
|
||||
) -> Result<Option<NuTable>, ShellError> {
|
||||
) -> Result<Option<(NuTable, bool, bool)>, ShellError> {
|
||||
const PADDING_SPACE: usize = 2;
|
||||
const SPLIT_LINE_SPACE: usize = 1;
|
||||
const ADDITIONAL_CELL_SPACE: usize = PADDING_SPACE + SPLIT_LINE_SPACE;
|
||||
@ -984,7 +975,6 @@ fn convert_to_table2<'a>(
|
||||
config,
|
||||
&ctrlc,
|
||||
color_hm,
|
||||
theme,
|
||||
deep,
|
||||
flatten,
|
||||
flatten_sep,
|
||||
@ -997,9 +987,10 @@ fn convert_to_table2<'a>(
|
||||
|
||||
let count_columns = if with_index { 2 } else { 1 };
|
||||
let size = (data.len(), count_columns);
|
||||
let table = NuTable::new(data, size, usize::MAX, with_header, with_index);
|
||||
|
||||
return Ok(Some(table));
|
||||
let table = NuTable::new(data, size);
|
||||
|
||||
return Ok(Some((table, with_header, with_index)));
|
||||
}
|
||||
|
||||
let mut widths = Vec::new();
|
||||
@ -1045,7 +1036,6 @@ fn convert_to_table2<'a>(
|
||||
config,
|
||||
&ctrlc,
|
||||
color_hm,
|
||||
theme,
|
||||
deep,
|
||||
flatten,
|
||||
flatten_sep,
|
||||
@ -1162,9 +1152,9 @@ fn convert_to_table2<'a>(
|
||||
let count_rows = data.len();
|
||||
let size = (count_rows, count_columns);
|
||||
|
||||
let table = NuTable::new(data, size, usize::MAX, with_header, with_index);
|
||||
let table = NuTable::new(data, size);
|
||||
|
||||
Ok(Some(table))
|
||||
Ok(Some((table, with_header, with_index)))
|
||||
}
|
||||
|
||||
fn lookup_index_value(item: &Value, config: &Config) -> Option<String> {
|
||||
@ -1210,7 +1200,6 @@ fn create_table2_entry(
|
||||
config: &Config,
|
||||
ctrlc: &Option<Arc<AtomicBool>>,
|
||||
color_hm: &NuColorMap,
|
||||
theme: &TableTheme,
|
||||
deep: Option<usize>,
|
||||
flatten: bool,
|
||||
flatten_sep: &str,
|
||||
@ -1228,7 +1217,6 @@ fn create_table2_entry(
|
||||
config,
|
||||
ctrlc,
|
||||
color_hm,
|
||||
theme,
|
||||
deep,
|
||||
flatten,
|
||||
flatten_sep,
|
||||
@ -1242,7 +1230,6 @@ fn create_table2_entry(
|
||||
config,
|
||||
ctrlc,
|
||||
color_hm,
|
||||
theme,
|
||||
deep,
|
||||
flatten,
|
||||
flatten_sep,
|
||||
@ -1266,7 +1253,6 @@ fn convert_to_table2_entry(
|
||||
config: &Config,
|
||||
ctrlc: &Option<Arc<AtomicBool>>,
|
||||
color_hm: &NuColorMap,
|
||||
theme: &TableTheme,
|
||||
deep: Option<usize>,
|
||||
flatten: bool,
|
||||
flatten_sep: &str,
|
||||
@ -1289,7 +1275,6 @@ fn convert_to_table2_entry(
|
||||
config,
|
||||
*span,
|
||||
color_hm,
|
||||
theme,
|
||||
deep.map(|i| i - 1),
|
||||
flatten,
|
||||
flatten_sep,
|
||||
@ -1297,9 +1282,17 @@ fn convert_to_table2_entry(
|
||||
);
|
||||
|
||||
let inner_table = table.map(|table| {
|
||||
table.and_then(|table| {
|
||||
let alignments = Alignments::default();
|
||||
table.draw_table(config, color_hm, alignments, theme, usize::MAX, false)
|
||||
table.and_then(|(table, with_header, with_index)| {
|
||||
let table_config = create_table_config(
|
||||
config,
|
||||
color_hm,
|
||||
table.count_rows(),
|
||||
with_header,
|
||||
with_index,
|
||||
false,
|
||||
);
|
||||
|
||||
table.draw(table_config, usize::MAX)
|
||||
})
|
||||
});
|
||||
|
||||
@ -1329,7 +1322,6 @@ fn convert_to_table2_entry(
|
||||
config,
|
||||
*span,
|
||||
color_hm,
|
||||
theme,
|
||||
deep.map(|i| i - 1),
|
||||
flatten,
|
||||
flatten_sep,
|
||||
@ -1337,11 +1329,20 @@ fn convert_to_table2_entry(
|
||||
);
|
||||
|
||||
let inner_table = table.map(|table| {
|
||||
table.and_then(|table| {
|
||||
let alignments = Alignments::default();
|
||||
table.draw_table(config, color_hm, alignments, theme, usize::MAX, false)
|
||||
table.and_then(|(table, with_header, with_index)| {
|
||||
let table_config = create_table_config(
|
||||
config,
|
||||
color_hm,
|
||||
table.count_rows(),
|
||||
with_header,
|
||||
with_index,
|
||||
false,
|
||||
);
|
||||
|
||||
table.draw(table_config, usize::MAX)
|
||||
})
|
||||
});
|
||||
|
||||
if let Ok(Some(table)) = inner_table {
|
||||
(table, TextStyle::default())
|
||||
} else {
|
||||
@ -1445,9 +1446,10 @@ impl PagingTableCreator {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
let theme = load_theme_from_config(&self.config);
|
||||
let term_width = get_width_param(self.width_param);
|
||||
let color_hm = get_color_config(&self.config);
|
||||
let theme = load_theme_from_config(&self.config);
|
||||
|
||||
let table = convert_to_table2(
|
||||
self.row_offset,
|
||||
batch.iter(),
|
||||
@ -1455,29 +1457,30 @@ impl PagingTableCreator {
|
||||
&self.config,
|
||||
self.head,
|
||||
&color_hm,
|
||||
&theme,
|
||||
limit,
|
||||
flatten,
|
||||
flatten_separator.as_deref().unwrap_or(" "),
|
||||
term_width,
|
||||
)?;
|
||||
|
||||
let mut table = match table {
|
||||
let (mut table, with_header, with_index) = match table {
|
||||
Some(table) => table,
|
||||
None => return Ok(None),
|
||||
};
|
||||
|
||||
table.truncate(term_width, &theme);
|
||||
|
||||
let table_s = table.clone().draw_table(
|
||||
let table_config = create_table_config(
|
||||
&self.config,
|
||||
&color_hm,
|
||||
Alignments::default(),
|
||||
&theme,
|
||||
term_width,
|
||||
table.count_rows(),
|
||||
with_header,
|
||||
with_index,
|
||||
false,
|
||||
);
|
||||
|
||||
let table_s = table.clone().draw(table_config.clone(), term_width);
|
||||
|
||||
let table = match table_s {
|
||||
Some(s) => {
|
||||
// check whether we need to expand table or not,
|
||||
@ -1489,14 +1492,8 @@ impl PagingTableCreator {
|
||||
let used_percent = width as f32 / term_width as f32;
|
||||
|
||||
if width < term_width && used_percent > EXPAND_TREASHHOLD {
|
||||
table.draw_table(
|
||||
&self.config,
|
||||
&color_hm,
|
||||
Alignments::default(),
|
||||
&theme,
|
||||
term_width,
|
||||
true,
|
||||
)
|
||||
let table_config = table_config.expand();
|
||||
table.draw(table_config, term_width)
|
||||
} else {
|
||||
Some(s)
|
||||
}
|
||||
@ -1538,7 +1535,6 @@ impl PagingTableCreator {
|
||||
fn build_general(&self, batch: &[Value]) -> Result<Option<String>, ShellError> {
|
||||
let term_width = get_width_param(self.width_param);
|
||||
let color_hm = get_color_config(&self.config);
|
||||
let theme = load_theme_from_config(&self.config);
|
||||
|
||||
let table = convert_to_table(
|
||||
self.row_offset,
|
||||
@ -1546,24 +1542,25 @@ impl PagingTableCreator {
|
||||
self.ctrlc.clone(),
|
||||
&self.config,
|
||||
self.head,
|
||||
term_width,
|
||||
&color_hm,
|
||||
)?;
|
||||
|
||||
let table = match table {
|
||||
let (table, with_header, with_index) = match table {
|
||||
Some(table) => table,
|
||||
None => return Ok(None),
|
||||
};
|
||||
|
||||
let table = table.draw_table(
|
||||
let table_config = create_table_config(
|
||||
&self.config,
|
||||
&color_hm,
|
||||
Alignments::default(),
|
||||
&theme,
|
||||
term_width,
|
||||
table.count_rows(),
|
||||
with_index,
|
||||
with_header,
|
||||
false,
|
||||
);
|
||||
|
||||
let table = table.draw(table_config, term_width);
|
||||
|
||||
Ok(table)
|
||||
}
|
||||
}
|
||||
@ -1617,8 +1614,12 @@ impl Iterator for PagingTableCreator {
|
||||
|
||||
match table {
|
||||
Ok(Some(table)) => {
|
||||
let table =
|
||||
strip_output_color(Some(table), &self.config).expect("must never happen");
|
||||
|
||||
let mut bytes = table.as_bytes().to_vec();
|
||||
bytes.push(b'\n'); // tabled tables don't come with a newline on the end
|
||||
bytes.push(b'\n'); // nu-table tables don't come with a newline on the end
|
||||
|
||||
Some(Ok(bytes))
|
||||
}
|
||||
Err(err) => Some(Err(err)),
|
||||
@ -1696,3 +1697,59 @@ enum TableView {
|
||||
flatten_separator: Option<String>,
|
||||
},
|
||||
}
|
||||
|
||||
fn strip_output_color(output: Option<String>, config: &Config) -> Option<String> {
|
||||
match output {
|
||||
Some(output) => {
|
||||
// the atty is for when people do ls from vim, there should be no coloring there
|
||||
if !config.use_ansi_coloring || !atty::is(atty::Stream::Stdout) {
|
||||
// Draw the table without ansi colors
|
||||
Some(nu_utils::strip_ansi_string_likely(output))
|
||||
} else {
|
||||
// Draw the table with ansi colors
|
||||
Some(output)
|
||||
}
|
||||
}
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn create_table_config(
|
||||
config: &Config,
|
||||
color_hm: &HashMap<String, nu_ansi_term::Style>,
|
||||
count_records: usize,
|
||||
with_header: bool,
|
||||
with_index: bool,
|
||||
expand: bool,
|
||||
) -> TableConfig {
|
||||
let theme = load_theme_from_config(config);
|
||||
let append_footer = with_footer(config, with_header, count_records);
|
||||
|
||||
let mut table_cfg = TableConfig::new(theme, with_header, with_index, append_footer);
|
||||
|
||||
let sep_color = lookup_separator_color(color_hm);
|
||||
if let Some(color) = sep_color {
|
||||
table_cfg = table_cfg.splitline_style(color);
|
||||
}
|
||||
|
||||
if expand {
|
||||
table_cfg = table_cfg.expand();
|
||||
}
|
||||
|
||||
table_cfg.trim(config.trim_strategy.clone())
|
||||
}
|
||||
|
||||
fn lookup_separator_color(
|
||||
color_hm: &HashMap<String, nu_ansi_term::Style>,
|
||||
) -> Option<nu_ansi_term::Style> {
|
||||
color_hm.get("separator").cloned()
|
||||
}
|
||||
|
||||
fn with_footer(config: &Config, with_header: bool, count_records: usize) -> bool {
|
||||
with_header && need_footer(config, count_records as u64)
|
||||
}
|
||||
|
||||
fn need_footer(config: &Config, count_records: u64) -> bool {
|
||||
matches!(config.footer_mode, FooterMode::RowCount(limit) if count_records > limit)
|
||||
|| matches!(config.footer_mode, FooterMode::Always)
|
||||
}
|
||||
|
Reference in New Issue
Block a user