mirror of
https://github.com/nushell/nushell.git
synced 2025-06-30 22:50:14 +02:00
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 | | | | | | | | | +-----+---+ | | | | | | +-----+-------------+ | +-----+---+-------------+-----------------------+ ```
This commit is contained in:
@ -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(),
|
||||
|
@ -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 {
|
||||
|
@ -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<Position, TextStyle>) {
|
||||
}
|
||||
|
||||
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 {
|
||||
|
@ -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<Option<String>, 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<Option<String>,
|
||||
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<String>,
|
||||
with_index: bool,
|
||||
row_offset: usize,
|
||||
opts: TableOpts<'_>,
|
||||
opts: &TableOpts<'_>,
|
||||
) -> Result<Option<NuTable>, 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<Option<NuTable>, 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);
|
||||
|
@ -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<Arc<AtomicBool>>,
|
||||
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
|
||||
}
|
||||
|
Reference in New Issue
Block a user