From e9c298713eece456f3303c99ad84bc6a14c1e7fd Mon Sep 17 00:00:00 2001 From: Maxim Zhiburt Date: Thu, 16 Nov 2023 02:41:18 +0300 Subject: nu-table/ Add `-t/theme` argument && Replace `-n/start-number` with `-i/index` (#11058) ref #11054 cc: @fdncred I've not figured out how to be able to have a flag option as `table -i` :( ```nu ~/bin/nushell> [[a b, c]; [1 [2 3 3] 3] [4 5 [1 2 [1 2 3]]]] | table -e --width=80 --theme basic -i false +---+-------+-----------+ | a | b | c | +---+-------+-----------+ | 1 | +---+ | 3 | | | | 2 | | | | | +---+ | | | | | 3 | | | | | +---+ | | | | | 3 | | | | | +---+ | | +---+-------+-----------+ | 4 | 5 | +-------+ | | | | | 1 | | | | | +-------+ | | | | | 2 | | | | | +-------+ | | | | | +---+ | | | | | | | 1 | | | | | | | +---+ | | | | | | | 2 | | | | | | | +---+ | | | | | | | 3 | | | | | | | +---+ | | | | | +-------+ | +---+-------+-----------+ ``` ```nu ~/bin/nushell> [[a b, c]; [1 [2 3 3] 3] [4 5 [1 2 [1 2 3]]]] | table -e --width=80 --theme basic -i 100 +-----+---+-------------+-----------------------+ | # | a | b | c | +-----+---+-------------+-----------------------+ | 100 | 1 | +-----+---+ | 3 | | | | | 100 | 2 | | | | | | +-----+---+ | | | | | | 101 | 3 | | | | | | +-----+---+ | | | | | | 102 | 3 | | | | | | +-----+---+ | | +-----+---+-------------+-----------------------+ | 101 | 4 | 5 | +-----+-------------+ | | | | | | 100 | 1 | | | | | | +-----+-------------+ | | | | | | 101 | 2 | | | | | | +-----+-------------+ | | | | | | 102 | +-----+---+ | | | | | | | | | 100 | 1 | | | | | | | | | +-----+---+ | | | | | | | | | 101 | 2 | | | | | | | | | +-----+---+ | | | | | | | | | 102 | 3 | | | | | | | | | +-----+---+ | | | | | | +-----+-------------+ | +-----+---+-------------+-----------------------+ ``` --- crates/nu-command/src/viewers/table.rs | 144 ++++++++++++++++++++++++++---- crates/nu-command/tests/commands/table.rs | 49 ++++++++++ crates/nu-explore/src/nu_common/table.rs | 9 +- crates/nu-protocol/src/config/table.rs | 2 +- crates/nu-table/src/common.rs | 7 +- crates/nu-table/src/types/collapse.rs | 15 +++- crates/nu-table/src/types/expanded.rs | 35 ++++---- crates/nu-table/src/types/general.rs | 28 +++--- crates/nu-table/src/types/mod.rs | 27 ++++-- 9 files changed, 253 insertions(+), 63 deletions(-) diff --git a/crates/nu-command/src/viewers/table.rs b/crates/nu-command/src/viewers/table.rs index 74234de89..5410bc96a 100644 --- a/crates/nu-command/src/viewers/table.rs +++ b/crates/nu-command/src/viewers/table.rs @@ -1,14 +1,18 @@ +// todo: (refactoring) limit get_config() usage to 1 call +// overall reduce the redundant calls to StyleComputer etc. +// the goal is to configure it once... + use lscolors::{LsColors, Style}; use nu_color_config::color_from_hex; use nu_color_config::{StyleComputer, TextStyle}; use nu_engine::{env::get_config, env_to_string, CallExt}; -use nu_protocol::record; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, Category, Config, DataSource, Example, IntoPipelineData, ListStream, PipelineData, PipelineMetadata, RawStream, Record, ShellError, Signature, Span, SyntaxShape, Type, Value, }; +use nu_protocol::{record, TableMode}; use nu_table::common::create_nu_table_config; use nu_table::{ CollapsedTable, ExpandedTable, JustTable, NuTable, NuTableCell, StringResult, TableOpts, @@ -16,6 +20,7 @@ use nu_table::{ }; use nu_utils::get_ls_colors; use std::io::IsTerminal; +use std::str::FromStr; use std::sync::Arc; use std::time::Instant; use std::{path::PathBuf, sync::atomic::AtomicBool}; @@ -60,12 +65,17 @@ impl Command for Table { .input_output_types(vec![(Type::Any, Type::Any)]) // TODO: make this more precise: what turns into string and what into raw stream .named( - "start-number", - SyntaxShape::Int, - "row number to start viewing from", - Some('n'), + "theme", + SyntaxShape::String, + "set a table mode/theme", + Some('t'), + ) + .named( + "index", + SyntaxShape::Any, + "set or set off a index mode/theme", + Some('i'), ) - .switch("list", "list available table modes/themes", Some('l')) .named( "width", SyntaxShape::Int, @@ -101,6 +111,7 @@ impl Command for Table { "abbreviate the data in the table by truncating the middle part and only showing amount provided on top and bottom", Some('a'), ) + .switch("list", "list available table modes/themes", Some('l')) .category(Category::Viewers) } @@ -112,15 +123,15 @@ impl Command for Table { input: PipelineData, ) -> Result { let list_themes: bool = call.has_flag("list"); - let cfg = parse_table_config(call, engine_state, stack)?; - let input = CmdInput::new(engine_state, stack, call, input); - // if list argument is present we just need to return a list of supported table themes if list_themes { let val = Value::list(supported_table_modes(), Span::test_data()); return Ok(val.into_pipeline_data()); } + let cfg = parse_table_config(call, engine_state, stack)?; + let input = CmdInput::new(engine_state, stack, call, input); + // reset vt processing, aka ansi because illbehaved externals can break it #[cfg(windows)] { @@ -179,30 +190,53 @@ impl Command for Table { }), ])), }, + Example { + description: "Change a theme", + example: r#"[[a b]; [1 2] [2 [4 4]]] | table --theme basic"#, + result: None, + }, + Example { + description: "Force a show of an index", + example: r#"[[a b]; [1 2] [2 [4 4]]] | table -i"#, + result: None, + }, + Example { + description: "Set an index to start from a value", + example: r#"[[a b]; [1 2] [2 [4 4]]] | table -i 100"#, + result: None, + }, + Example { + description: "Remove an index", + example: r#"[[a b]; [1 2] [2 [4 4]]] | table -i false"#, + result: None, + }, ] } } #[derive(Debug, Clone)] struct TableConfig { - row_offset: usize, + index: Option, table_view: TableView, term_width: usize, + theme: TableMode, abbreviation: Option, } impl TableConfig { fn new( - row_offset: usize, table_view: TableView, term_width: usize, + theme: TableMode, abbreviation: Option, + index: Option, ) -> Self { Self { - row_offset, + index, table_view, term_width, abbreviation, + theme, } } } @@ -212,8 +246,6 @@ fn parse_table_config( state: &EngineState, stack: &mut Stack, ) -> Result { - let start_num: Option = call.get_flag(state, stack, "start-number")?; - let row_offset = start_num.unwrap_or_default() as usize; let width_param: Option = call.get_flag(state, stack, "width")?; let expand: bool = call.has_flag("expand"); let expand_limit: Option = call.get_flag(state, stack, "expand-deep")?; @@ -232,13 +264,73 @@ fn parse_table_config( flatten_separator, }, }; + let theme = + get_theme_flag(call, state, stack)?.unwrap_or_else(|| get_config(state, stack).table_mode); + let index = get_index_flag(call, state, stack)?; let term_width = get_width_param(width_param); - let cfg = TableConfig::new(row_offset, table_view, term_width, abbrivation); + let cfg = TableConfig::new(table_view, term_width, theme, abbrivation, index); Ok(cfg) } +fn get_index_flag( + call: &Call, + state: &EngineState, + stack: &mut Stack, +) -> Result, ShellError> { + let index: Option = call.get_flag(state, stack, "index")?; + let value = match index { + Some(value) => value, + None => return Ok(Some(0)), + }; + + match value { + Value::Bool { val, .. } => { + if val { + Ok(Some(0)) + } else { + Ok(None) + } + } + Value::Int { val, internal_span } => { + if val < 0 { + Err(ShellError::UnsupportedInput { + msg: String::from("got a negative integer"), + input: val.to_string(), + msg_span: call.span(), + input_span: internal_span, + }) + } else { + Ok(Some(val as usize)) + } + } + Value::Nothing { .. } => Ok(Some(0)), + _ => Err(ShellError::CantConvert { + to_type: String::from("index"), + from_type: String::new(), + span: call.span(), + help: Some(String::from("supported values: [bool, int, nothing]")), + }), + } +} + +fn get_theme_flag( + call: &Call, + state: &EngineState, + stack: &mut Stack, +) -> Result, ShellError> { + call.get_flag(state, stack, "theme")? + .map(|theme: String| TableMode::from_str(&theme)) + .transpose() + .map_err(|err| ShellError::CantConvert { + to_type: String::from("theme"), + from_type: String::from("string"), + span: call.span(), + help: Some(String::from(err)), + }) +} + struct CmdInput<'a> { engine_state: &'a EngineState, stack: &'a mut Stack, @@ -366,7 +458,17 @@ fn handle_record( } let indent = (config.table_indent.left, config.table_indent.right); - let opts = TableOpts::new(&config, styles, ctrlc, span, 0, cfg.term_width, indent); + let opts = TableOpts::new( + &config, + styles, + ctrlc, + span, + cfg.term_width, + indent, + cfg.theme, + cfg.index.unwrap_or(0), + cfg.index.is_none(), + ); let result = build_table_kv(record, cfg.table_view, opts, span)?; let result = match result { @@ -581,6 +683,7 @@ struct PagingTableCreator { elements_displayed: usize, reached_end: bool, cfg: TableConfig, + row_offset: usize, } impl PagingTableCreator { @@ -601,6 +704,7 @@ impl PagingTableCreator { cfg, elements_displayed: 0, reached_end: false, + row_offset: 0, } } @@ -657,9 +761,11 @@ impl PagingTableCreator { style_comp, self.ctrlc.clone(), self.head, - self.cfg.row_offset, self.cfg.term_width, (cfg.table_indent.left, cfg.table_indent.right), + self.cfg.theme, + self.cfg.index.unwrap_or(0) + self.row_offset, + self.cfg.index.is_none(), ) } @@ -770,7 +876,7 @@ impl Iterator for PagingTableCreator { let table = self.build_table(batch); - self.cfg.row_offset += idx; + self.row_offset += idx; let config = get_config(&self.engine_state, &self.stack); convert_table_to_output(table, &config, &self.ctrlc, self.cfg.term_width) @@ -858,7 +964,7 @@ fn create_empty_placeholder( let out = TableOutput::new(table, false, false); let style_computer = &StyleComputer::from_config(engine_state, stack); - let config = create_nu_table_config(&config, style_computer, &out, false); + let config = create_nu_table_config(&config, style_computer, &out, false, TableMode::default()); out.table .draw(config, termwidth) diff --git a/crates/nu-command/tests/commands/table.rs b/crates/nu-command/tests/commands/table.rs index c00f2fabc..6601592fb 100644 --- a/crates/nu-command/tests/commands/table.rs +++ b/crates/nu-command/tests/commands/table.rs @@ -2812,3 +2812,52 @@ fn table_abbreviation_by_config_override() { ); assert_eq!(actual.out, "╭───┬─────┬─────┬────────────────╮│ # │ a │ b │ c │├───┼─────┼─────┼────────────────┤│ 0 │ 1 │ 2 │ 3 ││ 1 │ 4 │ 5 │ [list 3 items] ││ 2 │ ... │ ... │ ... ││ 3 │ 1 │ 2 │ 3 ││ 4 │ 1 │ 2 │ 3 │╰───┴─────┴─────┴────────────────╯"); } + +#[test] +fn table_theme_arg() { + let actual = nu!("[[a b, c]; [1 2 3] [4 5 [1 2 3]] [1 2 3]] | table --width=80 --theme light"); + assert_eq!(actual.out, " # a b c ──────────────────────────── 0 1 2 3 1 4 5 [list 3 items] 2 1 2 3 "); + + let actual = nu!(theme_cmd( + "basic", + false, + "[[a b, c]; [1 2 3] [4 5 [1 2 3]] [1 2 3]] | table --width=80 --theme light" + )); + assert_eq!(actual.out, "─#───a───b─────────c──────── 0 1 2 3 1 4 5 [list 3 items] 2 1 2 3 "); +} + +#[test] +fn table_index_arg() { + let actual = nu!("[[a b]; [1 2] [2 [4 4]]] | table --width=80 --theme basic -i false"); + assert_eq!(actual.out, "+---+----------------+| a | b |+---+----------------+| 1 | 2 |+---+----------------+| 2 | [list 2 items] |+---+----------------+"); + + let actual = nu!("[[a b]; [1 2] [2 [4 4]]] | table --width=80 --theme basic -i true"); + assert_eq!(actual.out, "+---+---+----------------+| # | a | b |+---+---+----------------+| 0 | 1 | 2 |+---+---+----------------+| 1 | 2 | [list 2 items] |+---+---+----------------+"); + + let actual = nu!("[[a b]; [1 2] [2 [4 4]]] | table --width=80 --theme basic -i 10"); + assert_eq!(actual.out, "+----+---+----------------+| # | a | b |+----+---+----------------+| 10 | 1 | 2 |+----+---+----------------+| 11 | 2 | [list 2 items] |+----+---+----------------+"); +} + +#[test] +fn table_expand_index_arg() { + let actual = nu!("[[a b]; [1 2] [2 [4 4]]] | table --width=80 --theme basic --expand -i false"); + assert_eq!(actual.out, "+---+-------+| a | b |+---+-------+| 1 | 2 |+---+-------+| 2 | +---+ || | | 4 | || | +---+ || | | 4 | || | +---+ |+---+-------+"); + + let actual = nu!("[[a b]; [1 2] [2 [4 4]]] | table --width=80 --theme basic --expand -i true"); + assert_eq!(actual.out, "+---+---+-----------+| # | a | b |+---+---+-----------+| 0 | 1 | 2 |+---+---+-----------+| 1 | 2 | +---+---+ || | | | 0 | 4 | || | | +---+---+ || | | | 1 | 4 | || | | +---+---+ |+---+---+-----------+"); + + let actual = nu!("[[a b]; [1 2] [2 [4 4]]] | table --width=80 --theme basic --expand -i 10"); + assert_eq!(actual.out, "+----+---+------------+| # | a | b |+----+---+------------+| 10 | 1 | 2 |+----+---+------------+| 11 | 2 | +----+---+ || | | | 10 | 4 | || | | +----+---+ || | | | 11 | 4 | || | | +----+---+ |+----+---+------------+"); +} + +#[test] +fn table_list() { + let actual = nu!("table --list"); + assert_eq!(actual.out, "╭────┬────────────────╮│ 0 │ basic ││ 1 │ compact ││ 2 │ compact_double ││ 3 │ default ││ 4 │ heavy ││ 5 │ light ││ 6 │ none ││ 7 │ reinforced ││ 8 │ rounded ││ 9 │ thin ││ 10 │ with_love ││ 11 │ psql ││ 12 │ markdown ││ 13 │ dots ││ 14 │ restructured ││ 15 │ ascii_rounded ││ 16 │ basic_compact │╰────┴────────────────╯"); + + let actual = nu!("ls | table --list"); + assert_eq!(actual.out, "╭────┬────────────────╮│ 0 │ basic ││ 1 │ compact ││ 2 │ compact_double ││ 3 │ default ││ 4 │ heavy ││ 5 │ light ││ 6 │ none ││ 7 │ reinforced ││ 8 │ rounded ││ 9 │ thin ││ 10 │ with_love ││ 11 │ psql ││ 12 │ markdown ││ 13 │ dots ││ 14 │ restructured ││ 15 │ ascii_rounded ││ 16 │ basic_compact │╰────┴────────────────╯"); + + let actual = nu!("table --list --theme basic"); + assert_eq!(actual.out, "╭────┬────────────────╮│ 0 │ basic ││ 1 │ compact ││ 2 │ compact_double ││ 3 │ default ││ 4 │ heavy ││ 5 │ light ││ 6 │ none ││ 7 │ reinforced ││ 8 │ rounded ││ 9 │ thin ││ 10 │ with_love ││ 11 │ psql ││ 12 │ markdown ││ 13 │ dots ││ 14 │ restructured ││ 15 │ ascii_rounded ││ 16 │ basic_compact │╰────┴────────────────╯"); +} diff --git a/crates/nu-explore/src/nu_common/table.rs b/crates/nu-explore/src/nu_common/table.rs index a5bc49695..9e9695ea8 100644 --- a/crates/nu-explore/src/nu_common/table.rs +++ b/crates/nu-explore/src/nu_common/table.rs @@ -38,9 +38,11 @@ fn try_build_map( style_computer, ctrlc, Span::unknown(), - 0, usize::MAX, (config.table_indent.left, config.table_indent.right), + config.table_mode, + 0, + false, ); let result = ExpandedTable::new(None, false, String::new()).build_map(&record, opts); match result { @@ -63,10 +65,13 @@ fn try_build_list( style_computer, ctrlc, Span::unknown(), - 0, usize::MAX, (config.table_indent.left, config.table_indent.right), + config.table_mode, + 0, + false, ); + let result = ExpandedTable::new(None, false, String::new()).build_list(&vals, opts); match result { Ok(Some(out)) => out, diff --git a/crates/nu-protocol/src/config/table.rs b/crates/nu-protocol/src/config/table.rs index 81f30bad9..5c13a7b85 100644 --- a/crates/nu-protocol/src/config/table.rs +++ b/crates/nu-protocol/src/config/table.rs @@ -3,7 +3,7 @@ use crate::{record, Config, ShellError, Span, Value}; use serde::{Deserialize, Serialize}; use std::str::FromStr; -#[derive(Serialize, Deserialize, Clone, Debug, Default)] +#[derive(Serialize, Deserialize, Clone, Copy, Debug, Default)] pub enum TableMode { Basic, Thin, diff --git a/crates/nu-table/src/common.rs b/crates/nu-table/src/common.rs index f8e9a4d1b..89455e45e 100644 --- a/crates/nu-table/src/common.rs +++ b/crates/nu-table/src/common.rs @@ -17,9 +17,10 @@ pub fn create_nu_table_config( comp: &StyleComputer, out: &TableOutput, expand: bool, + mode: TableMode, ) -> NuTableConfig { NuTableConfig { - theme: load_theme_from_config(config), + theme: load_theme(mode), with_footer: with_footer(config, out.with_header, out.table.count_rows()), with_index: out.with_index, with_header: out.with_header, @@ -173,8 +174,8 @@ fn is_cfg_trim_keep_words(config: &Config) -> bool { ) } -pub fn load_theme_from_config(config: &Config) -> TableTheme { - match config.table_mode { +pub fn load_theme(mode: TableMode) -> TableTheme { + match mode { TableMode::Basic => TableTheme::basic(), TableMode::Thin => TableTheme::thin(), TableMode::Light => TableTheme::light(), diff --git a/crates/nu-table/src/types/collapse.rs b/crates/nu-table/src/types/collapse.rs index 6a7931bf2..287208523 100644 --- a/crates/nu-table/src/types/collapse.rs +++ b/crates/nu-table/src/types/collapse.rs @@ -1,11 +1,11 @@ use nu_color_config::StyleComputer; -use nu_protocol::{Config, Record, Value}; +use nu_protocol::{Config, Record, TableMode, Value}; use crate::UnstructuredTable; use crate::common::nu_value_to_string_clean; use crate::{ - common::{get_index_style, load_theme_from_config}, + common::{get_index_style, load_theme}, StringResult, TableOpts, }; @@ -13,7 +13,13 @@ pub struct CollapsedTable; impl CollapsedTable { pub fn build(value: Value, opts: TableOpts<'_>) -> StringResult { - collapsed_table(value, opts.config, opts.width, opts.style_computer) + collapsed_table( + value, + opts.config, + opts.width, + opts.style_computer, + opts.mode, + ) } } @@ -22,10 +28,11 @@ fn collapsed_table( config: &Config, term_width: usize, style_computer: &StyleComputer, + mode: TableMode, ) -> StringResult { colorize_value(&mut value, config, style_computer); - let theme = load_theme_from_config(config); + let theme = load_theme(mode); let mut table = UnstructuredTable::new(value, config); let is_empty = table.truncate(&theme, term_width); if is_empty { diff --git a/crates/nu-table/src/types/expanded.rs b/crates/nu-table/src/types/expanded.rs index 4880bac94..688370b70 100644 --- a/crates/nu-table/src/types/expanded.rs +++ b/crates/nu-table/src/types/expanded.rs @@ -3,17 +3,18 @@ use std::collections::HashMap; use nu_color_config::{Alignment, StyleComputer, TextStyle}; use nu_engine::column::get_columns; -use nu_protocol::{Config, Record, ShellError, Span, TableIndexMode, Value}; +use nu_protocol::{Config, Record, ShellError, Span, Value}; use tabled::grid::config::Position; use crate::{ common::{ - create_nu_table_config, error_sign, get_header_style, get_index_style, - load_theme_from_config, nu_value_to_string, nu_value_to_string_clean, - nu_value_to_string_colored, wrap_text, NuText, StringResult, TableResult, - INDEX_COLUMN_NAME, + create_nu_table_config, error_sign, get_header_style, get_index_style, load_theme, + nu_value_to_string, nu_value_to_string_clean, nu_value_to_string_colored, wrap_text, + NuText, StringResult, TableResult, INDEX_COLUMN_NAME, }, - string_width, NuTable, NuTableCell, TableOpts, TableOutput, + string_width, + types::has_index, + NuTable, NuTableCell, TableOpts, TableOutput, }; #[derive(Debug, Clone)] @@ -83,11 +84,8 @@ fn expanded_table_list(input: &[Value], cfg: Cfg<'_>) -> TableResult { let headers = get_columns(input); - let with_index = match cfg.opts.config.table_index_mode { - TableIndexMode::Always => true, - TableIndexMode::Never => false, - TableIndexMode::Auto => headers.iter().any(|header| header == INDEX_COLUMN_NAME), - }; + let with_index = has_index(&cfg.opts, &headers); + let row_offset = cfg.opts.index_offset; // The header with the INDEX is removed from the table headers since // it is added to the natural table index @@ -115,7 +113,7 @@ fn expanded_table_list(input: &[Value], cfg: Cfg<'_>) -> TableResult { return Err(*error.clone()); } - let index = row + cfg.opts.row_offset; + let index = row + row_offset; let text = item .as_record() .ok() @@ -343,7 +341,7 @@ fn expanded_table_list(input: &[Value], cfg: Cfg<'_>) -> TableResult { } fn expanded_table_kv(record: &Record, cfg: Cfg<'_>) -> StringResult { - let theme = load_theme_from_config(cfg.opts.config); + let theme = load_theme(cfg.opts.mode); let key_width = record .columns() .map(|col| string_width(col)) @@ -556,7 +554,8 @@ fn dive_options<'b>(cfg: &Cfg<'b>, span: Span) -> Cfg<'b> { } fn maybe_expand_table(out: TableOutput, term_width: usize, opts: &TableOpts<'_>) -> StringResult { - let mut table_config = create_nu_table_config(opts.config, opts.style_computer, &out, false); + let mut table_config = + create_nu_table_config(opts.config, opts.style_computer, &out, false, opts.mode); let total_width = out.table.total_width(&table_config); if total_width < term_width { const EXPAND_THRESHOLD: f32 = 0.80; @@ -577,7 +576,13 @@ fn set_data_styles(table: &mut NuTable, styles: HashMap) { } fn create_table_cfg(cfg: &Cfg<'_>, out: &TableOutput) -> crate::NuTableConfig { - create_nu_table_config(cfg.opts.config, cfg.opts.style_computer, out, false) + create_nu_table_config( + cfg.opts.config, + cfg.opts.style_computer, + out, + false, + cfg.opts.mode, + ) } fn value_to_string(value: &Value, cfg: &Cfg<'_>) -> String { diff --git a/crates/nu-table/src/types/general.rs b/crates/nu-table/src/types/general.rs index 368b7f0df..9171f6c1a 100644 --- a/crates/nu-table/src/types/general.rs +++ b/crates/nu-table/src/types/general.rs @@ -1,6 +1,6 @@ use nu_color_config::TextStyle; use nu_engine::column::get_columns; -use nu_protocol::{Config, Record, ShellError, TableIndexMode, Value}; +use nu_protocol::{Config, Record, ShellError, Value}; use crate::{ clean_charset, colorize_space, @@ -11,6 +11,8 @@ use crate::{ NuTable, NuTableCell, StringResult, TableOpts, TableOutput, TableResult, }; +use super::has_index; + pub struct JustTable; impl JustTable { @@ -24,7 +26,7 @@ impl JustTable { } fn create_table(input: &[Value], opts: TableOpts<'_>) -> Result, ShellError> { - match table(input, opts.row_offset, opts.clone())? { + match table(input, &opts)? { Some(mut out) => { let left = opts.config.table_indent.left; let right = opts.config.table_indent.right; @@ -33,7 +35,7 @@ fn create_table(input: &[Value], opts: TableOpts<'_>) -> Result, colorize_space(out.table.get_records_mut(), opts.style_computer); let table_config = - create_nu_table_config(opts.config, opts.style_computer, &out, false); + create_nu_table_config(opts.config, opts.style_computer, &out, false, opts.mode); Ok(out.table.draw(table_config, opts.width)) } None => Ok(None), @@ -65,23 +67,21 @@ fn kv_table(record: &Record, opts: TableOpts<'_>) -> StringResult { let right = opts.config.table_indent.right; out.table.set_indent(left, right); - let table_config = create_nu_table_config(opts.config, opts.style_computer, &out, false); + let table_config = + create_nu_table_config(opts.config, opts.style_computer, &out, false, opts.mode); let table = out.table.draw(table_config, opts.width); Ok(table) } -fn table(input: &[Value], row_offset: usize, opts: TableOpts<'_>) -> TableResult { +fn table(input: &[Value], opts: &TableOpts<'_>) -> TableResult { if input.is_empty() { return Ok(None); } let mut headers = get_columns(input); - let with_index = match opts.config.table_index_mode { - TableIndexMode::Always => true, - TableIndexMode::Never => false, - TableIndexMode::Auto => headers.iter().any(|header| header == INDEX_COLUMN_NAME), - }; + let with_index = has_index(opts, &headers); + let row_offset = opts.index_offset; let with_header = !headers.is_empty(); if !with_header { @@ -112,7 +112,7 @@ fn to_table_with_header( headers: Vec, with_index: bool, row_offset: usize, - opts: TableOpts<'_>, + opts: &TableOpts<'_>, ) -> Result, ShellError> { let count_rows = input.len() + 1; let count_columns = headers.len(); @@ -140,7 +140,7 @@ fn to_table_with_header( let skip_index = usize::from(with_index); for (col, header) in headers.iter().enumerate().skip(skip_index) { - let (text, style) = get_string_value_with_header(item, header, &opts); + let (text, style) = get_string_value_with_header(item, header, opts); table.insert((row + 1, col), text); table.insert_style((row + 1, col), style); @@ -154,7 +154,7 @@ fn to_table_with_no_header( input: &[Value], with_index: bool, row_offset: usize, - opts: TableOpts<'_>, + opts: &TableOpts<'_>, ) -> Result, ShellError> { let mut table = NuTable::new(input.len(), with_index as usize + 1); table.set_index_style(get_index_style(opts.style_computer)); @@ -173,7 +173,7 @@ fn to_table_with_no_header( table.insert((row, 0), text); } - let (text, style) = get_string_value(item, &opts); + let (text, style) = get_string_value(item, opts); let pos = (row, with_index as usize); table.insert(pos, text); diff --git a/crates/nu-table/src/types/mod.rs b/crates/nu-table/src/types/mod.rs index ad3625a81..eeebd70aa 100644 --- a/crates/nu-table/src/types/mod.rs +++ b/crates/nu-table/src/types/mod.rs @@ -8,9 +8,9 @@ pub use collapse::CollapsedTable; pub use expanded::ExpandedTable; pub use general::JustTable; use nu_color_config::StyleComputer; -use nu_protocol::{Config, Span}; +use nu_protocol::{Config, Span, TableIndexMode, TableMode}; -use crate::NuTable; +use crate::{common::INDEX_COLUMN_NAME, NuTable}; pub struct TableOutput { pub table: NuTable, @@ -34,29 +34,46 @@ pub struct TableOpts<'a> { config: &'a Config, style_computer: &'a StyleComputer<'a>, span: Span, - row_offset: usize, width: usize, indent: (usize, usize), + mode: TableMode, + index_offset: usize, + index_remove: bool, } impl<'a> TableOpts<'a> { + #[allow(clippy::too_many_arguments)] pub fn new( config: &'a Config, style_computer: &'a StyleComputer<'a>, ctrlc: Option>, span: Span, - row_offset: usize, width: usize, indent: (usize, usize), + mode: TableMode, + index_offset: usize, + index_remove: bool, ) -> Self { Self { ctrlc, config, style_computer, span, - row_offset, indent, width, + mode, + index_offset, + index_remove, } } } + +fn has_index(opts: &TableOpts<'_>, headers: &[String]) -> bool { + let with_index = match opts.config.table_index_mode { + TableIndexMode::Always => true, + TableIndexMode::Never => false, + TableIndexMode::Auto => headers.iter().any(|header| header == INDEX_COLUMN_NAME), + }; + + with_index && !opts.index_remove +} -- cgit v1.2.3-70-g09d2