mirror of
https://github.com/nushell/nushell
synced 2024-12-26 04:53:09 +00:00
nu-table/ Add table.indent
configuration (#9983)
Hi there. Am I got it right? ref: https://github.com/zhiburt/tabled/issues/358 cc: @fdncred --------- Signed-off-by: Maxim Zhiburt <zhiburt@gmail.com>
This commit is contained in:
parent
a0cecf7658
commit
aa37572ddc
11 changed files with 226 additions and 13 deletions
|
@ -362,7 +362,8 @@ fn handle_record(
|
|||
let result = if cols.is_empty() {
|
||||
create_empty_placeholder("record", term_width, engine_state, stack)
|
||||
} else {
|
||||
let opts = TableOpts::new(config, style_computer, ctrlc, span, 0, term_width);
|
||||
let indent = (config.table_indent.left, config.table_indent.right);
|
||||
let opts = TableOpts::new(config, style_computer, ctrlc, span, 0, term_width, indent);
|
||||
let result = build_table_kv(cols, vals, table_view, opts, span)?;
|
||||
match result {
|
||||
Some(output) => maybe_strip_color(output, config),
|
||||
|
@ -691,6 +692,7 @@ impl PagingTableCreator {
|
|||
self.head,
|
||||
self.row_offset,
|
||||
get_width_param(self.width_param),
|
||||
(cfg.table_indent.left, cfg.table_indent.right),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2560,3 +2560,107 @@ fn theme_cmd(theme: &str, footer: bool, then: &str) -> String {
|
|||
|
||||
format!("$env.config.table.mode = {theme}; $env.config.table.header_on_separator = true; {with_foorter}; {then}")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn table_padding_not_default() {
|
||||
let actual = nu!("$env.config.table.padding = 5; [[a b, c]; [1 2 3] [4 5 [1 2 3]]] | table");
|
||||
assert_eq!(
|
||||
actual.out,
|
||||
"╭───────────┬───────────┬───────────┬────────────────────────╮\
|
||||
│ # │ a │ b │ c │\
|
||||
├───────────┼───────────┼───────────┼────────────────────────┤\
|
||||
│ 0 │ 1 │ 2 │ 3 │\
|
||||
│ 1 │ 4 │ 5 │ [list 3 items] │\
|
||||
╰───────────┴───────────┴───────────┴────────────────────────╯"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn table_padding_zero() {
|
||||
let actual = nu!(
|
||||
"$env.config.table.padding = {left: 0, right: 0}; [[a b, c]; [1 2 3] [4 5 [1 2 3]]] | table"
|
||||
);
|
||||
assert_eq!(
|
||||
actual.out,
|
||||
"╭─┬─┬─┬──────────────╮\
|
||||
│#│a│b│ c │\
|
||||
├─┼─┼─┼──────────────┤\
|
||||
│0│1│2│ 3│\
|
||||
│1│4│5│[list 3 items]│\
|
||||
╰─┴─┴─┴──────────────╯"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn table_expand_padding_not_default() {
|
||||
let actual = nu!("$env.config.table.padding = 5; [[a b, c]; [1 2 3] [4 5 [1 2 3]]] | table -e");
|
||||
assert_eq!(
|
||||
actual.out,
|
||||
"╭───────────┬───────────┬───────────┬───────────────────────────────────╮\
|
||||
│ # │ a │ b │ c │\
|
||||
├───────────┼───────────┼───────────┼───────────────────────────────────┤\
|
||||
│ 0 │ 1 │ 2 │ 3 │\
|
||||
│ 1 │ 4 │ 5 │ ╭───────────┬───────────╮ │\
|
||||
│ │ │ │ │ 0 │ 1 │ │\
|
||||
│ │ │ │ │ 1 │ 2 │ │\
|
||||
│ │ │ │ │ 2 │ 3 │ │\
|
||||
│ │ │ │ ╰───────────┴───────────╯ │\
|
||||
╰───────────┴───────────┴───────────┴───────────────────────────────────╯"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn table_expand_padding_zero() {
|
||||
let actual = nu!("$env.config.table.padding = {left: 0, right: 0}; [[a b, c]; [1 2 3] [4 5 [1 2 3]]] | table -e");
|
||||
assert_eq!(
|
||||
actual.out,
|
||||
"╭─┬─┬─┬─────╮\
|
||||
│#│a│b│ c │\
|
||||
├─┼─┼─┼─────┤\
|
||||
│0│1│2│ 3│\
|
||||
│1│4│5│╭─┬─╮│\
|
||||
│ │ │ ││0│1││\
|
||||
│ │ │ ││1│2││\
|
||||
│ │ │ ││2│3││\
|
||||
│ │ │ │╰─┴─╯│\
|
||||
╰─┴─┴─┴─────╯"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn table_collapse_padding_not_default() {
|
||||
let actual = nu!("$env.config.table.padding = 5; [[a b, c]; [1 2 3] [4 5 [1 2 3]]] | table -c");
|
||||
assert_eq!(
|
||||
actual.out,
|
||||
"╭───────────┬───────────┬───────────╮\
|
||||
│ a │ b │ c │\
|
||||
├───────────┼───────────┼───────────┤\
|
||||
│ 1 │ 2 │ 3 │\
|
||||
├───────────┼───────────┼───────────┤\
|
||||
│ 4 │ 5 │ 1 │\
|
||||
│ │ ├───────────┤\
|
||||
│ │ │ 2 │\
|
||||
│ │ ├───────────┤\
|
||||
│ │ │ 3 │\
|
||||
╰───────────┴───────────┴───────────╯"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn table_collapse_padding_zero() {
|
||||
let actual = nu!("$env.config.table.padding = {left: 0, right: 0}; [[a b, c]; [1 2 3] [4 5 [1 2 3]]] | table -c");
|
||||
assert_eq!(
|
||||
actual.out,
|
||||
"╭─┬─┬─╮\
|
||||
│a│b│c│\
|
||||
├─┼─┼─┤\
|
||||
│1│2│3│\
|
||||
├─┼─┼─┤\
|
||||
│4│5│1│\
|
||||
│ │ ├─┤\
|
||||
│ │ │2│\
|
||||
│ │ ├─┤\
|
||||
│ │ │3│\
|
||||
╰─┴─┴─╯"
|
||||
);
|
||||
}
|
||||
|
|
|
@ -42,6 +42,7 @@ fn try_build_map(
|
|||
Span::unknown(),
|
||||
0,
|
||||
usize::MAX,
|
||||
(config.table_indent.left, config.table_indent.right),
|
||||
);
|
||||
let result = ExpandedTable::new(None, false, String::new()).build_map(&cols, &vals, opts);
|
||||
match result {
|
||||
|
@ -66,6 +67,7 @@ fn try_build_list(
|
|||
Span::unknown(),
|
||||
0,
|
||||
usize::MAX,
|
||||
(config.table_indent.left, config.table_indent.right),
|
||||
);
|
||||
let result = ExpandedTable::new(None, false, String::new()).build_list(&vals, opts);
|
||||
match result {
|
||||
|
|
|
@ -75,6 +75,7 @@ pub struct Config {
|
|||
pub table_mode: String,
|
||||
pub table_move_header: bool,
|
||||
pub table_show_empty: bool,
|
||||
pub table_indent: TableIndent,
|
||||
pub use_ls_colors: bool,
|
||||
pub color_config: HashMap<String, Value>,
|
||||
pub use_grid_icons: bool,
|
||||
|
@ -131,6 +132,7 @@ impl Default for Config {
|
|||
table_show_empty: true,
|
||||
trim_strategy: TRIM_STRATEGY_DEFAULT,
|
||||
table_move_header: false,
|
||||
table_indent: TableIndent { left: 1, right: 1 },
|
||||
|
||||
datetime_normal_format: None,
|
||||
datetime_table_format: None,
|
||||
|
@ -243,6 +245,12 @@ impl TrimStrategy {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct TableIndent {
|
||||
pub left: usize,
|
||||
pub right: usize,
|
||||
}
|
||||
|
||||
impl Value {
|
||||
pub fn into_config(&mut self, config: &Config) -> (Config, Option<ShellError>) {
|
||||
// Clone the passed-in config rather than mutating it.
|
||||
|
@ -934,6 +942,55 @@ impl Value {
|
|||
"header_on_separator" => {
|
||||
try_bool!(cols, vals, index, span, table_move_header)
|
||||
}
|
||||
"padding" => match value {
|
||||
Value::Int { val, .. } => {
|
||||
if *val < 0 {
|
||||
invalid!(Some(span), "unexpected $env.config.{key}.{key2} '{val}'; expected a unsigned integer");
|
||||
}
|
||||
|
||||
config.table_indent.left = *val as usize;
|
||||
config.table_indent.right = *val as usize;
|
||||
}
|
||||
Value::Record { vals, cols, .. } => {
|
||||
let left = cols.iter().position(|e| e == "left");
|
||||
let right = cols.iter().position(|e| e == "right");
|
||||
|
||||
if let Some(i) = left {
|
||||
let value = vals[i].as_int();
|
||||
match value {
|
||||
Ok(val) => {
|
||||
if val < 0 {
|
||||
invalid!(Some(span), "unexpected $env.config.{key}.{key2} '{val}'; expected a unsigned integer");
|
||||
}
|
||||
|
||||
config.table_indent.left = val as usize;
|
||||
}
|
||||
Err(_) => {
|
||||
invalid!(Some(span), "unexpected $env.config.{key}.{key2} value; expected a unsigned integer or a record");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(i) = right {
|
||||
let value = vals[i].as_int();
|
||||
match value {
|
||||
Ok(val) => {
|
||||
if val < 0 {
|
||||
invalid!(Some(span), "unexpected $env.config.{key}.{key2} '{val}'; expected a unsigned integer");
|
||||
}
|
||||
|
||||
config.table_indent.right = val as usize;
|
||||
}
|
||||
Err(_) => {
|
||||
invalid!(Some(span), "unexpected $env.config.{key}.{key2} value; expected a unsigned integer or a record");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
invalid!(Some(span), "unexpected $env.config.{key}.{key2} value; expected a unsigned integer or a record");
|
||||
}
|
||||
},
|
||||
"index_mode" => {
|
||||
if let Ok(b) = value.as_string() {
|
||||
let val_str = b.to_lowercase();
|
||||
|
|
|
@ -18,7 +18,7 @@ use tabled::{
|
|||
},
|
||||
settings::{
|
||||
formatting::AlignmentStrategy, object::Segment, peaker::Peaker, themes::ColumnNames, Color,
|
||||
Modify, Settings, TableOption, Width,
|
||||
Modify, Padding, Settings, TableOption, Width,
|
||||
},
|
||||
Table,
|
||||
};
|
||||
|
@ -29,6 +29,7 @@ pub struct NuTable {
|
|||
data: NuTableData,
|
||||
styles: Styles,
|
||||
alignments: Alignments,
|
||||
indent: (usize, usize),
|
||||
}
|
||||
|
||||
type NuTableData = VecRecords<NuTableCell>;
|
||||
|
@ -57,6 +58,7 @@ impl NuTable {
|
|||
Self {
|
||||
data: VecRecords::new(vec![vec![CellInfo::default(); count_columns]; count_rows]),
|
||||
styles: Styles::default(),
|
||||
indent: (1, 1),
|
||||
alignments: Alignments {
|
||||
data: AlignmentHorizontal::Left,
|
||||
index: AlignmentHorizontal::Right,
|
||||
|
@ -135,11 +137,22 @@ impl NuTable {
|
|||
self.alignments.data = convert_alignment(style.alignment);
|
||||
}
|
||||
|
||||
pub fn set_indent(&mut self, left: usize, right: usize) {
|
||||
self.indent = (left, right);
|
||||
}
|
||||
|
||||
/// Converts a table to a String.
|
||||
///
|
||||
/// It returns None in case where table cannot be fit to a terminal width.
|
||||
pub fn draw(self, config: NuTableConfig, termwidth: usize) -> Option<String> {
|
||||
build_table(self.data, config, self.alignments, self.styles, termwidth)
|
||||
build_table(
|
||||
self.data,
|
||||
config,
|
||||
self.alignments,
|
||||
self.styles,
|
||||
termwidth,
|
||||
self.indent,
|
||||
)
|
||||
}
|
||||
|
||||
/// Return a total table width.
|
||||
|
@ -192,6 +205,7 @@ fn build_table(
|
|||
alignments: Alignments,
|
||||
styles: Styles,
|
||||
termwidth: usize,
|
||||
indent: (usize, usize),
|
||||
) -> Option<String> {
|
||||
if data.count_columns() == 0 || data.count_rows() == 0 {
|
||||
return Some(String::new());
|
||||
|
@ -206,7 +220,7 @@ fn build_table(
|
|||
duplicate_row(&mut data, 0);
|
||||
}
|
||||
|
||||
draw_table(data, alignments, styles, widths, cfg, termwidth)
|
||||
draw_table(data, alignments, styles, widths, cfg, termwidth, indent)
|
||||
}
|
||||
|
||||
fn draw_table(
|
||||
|
@ -216,6 +230,7 @@ fn draw_table(
|
|||
widths: Vec<usize>,
|
||||
cfg: NuTableConfig,
|
||||
termwidth: usize,
|
||||
indent: (usize, usize),
|
||||
) -> Option<String> {
|
||||
let with_index = cfg.with_index;
|
||||
let with_header = cfg.with_header && data.count_rows() > 1;
|
||||
|
@ -226,6 +241,7 @@ fn draw_table(
|
|||
let data: Vec<Vec<_>> = data.into();
|
||||
let mut table = Builder::from(data).build();
|
||||
|
||||
set_indent(&mut table, indent.0, indent.1);
|
||||
load_theme(&mut table, &cfg.theme, with_footer, with_header, sep_color);
|
||||
align_table(&mut table, alignments, with_index, with_header, with_footer);
|
||||
colorize_table(&mut table, styles, with_index, with_header, with_footer);
|
||||
|
@ -240,6 +256,10 @@ fn draw_table(
|
|||
build_table_with_width_check(table, total_width, termwidth)
|
||||
}
|
||||
|
||||
fn set_indent(table: &mut Table, left: usize, right: usize) {
|
||||
table.with(Padding::new(left, right, 0, 0));
|
||||
}
|
||||
|
||||
fn set_border_head(table: &mut Table, with_footer: bool) {
|
||||
let count_rows = table.count_rows();
|
||||
|
||||
|
|
|
@ -32,7 +32,8 @@ fn collapsed_table(
|
|||
return Ok(None);
|
||||
}
|
||||
|
||||
let table = table.draw(style_computer, &theme);
|
||||
let indent = (config.table_indent.left, config.table_indent.right);
|
||||
let table = table.draw(style_computer, &theme, indent);
|
||||
|
||||
Ok(Some(table))
|
||||
}
|
||||
|
|
|
@ -174,6 +174,7 @@ fn expanded_table_list(input: &[Value], cfg: Cfg<'_>) -> TableResult {
|
|||
}
|
||||
|
||||
let mut table = NuTable::from(data);
|
||||
table.set_indent(cfg.opts.indent.0, cfg.opts.indent.1);
|
||||
table.set_index_style(get_index_style(cfg.opts.style_computer));
|
||||
set_data_styles(&mut table, data_styles);
|
||||
|
||||
|
@ -333,6 +334,7 @@ fn expanded_table_list(input: &[Value], cfg: Cfg<'_>) -> TableResult {
|
|||
let mut table = NuTable::from(data);
|
||||
table.set_index_style(get_index_style(cfg.opts.style_computer));
|
||||
table.set_header_style(get_header_style(cfg.opts.style_computer));
|
||||
table.set_indent(cfg.opts.indent.0, cfg.opts.indent.1);
|
||||
set_data_styles(&mut table, data_styles);
|
||||
|
||||
Ok(Some(TableOutput::new(table, true, with_index)))
|
||||
|
@ -378,6 +380,7 @@ fn expanded_table_kv(cols: &[String], vals: &[Value], cfg: Cfg<'_>) -> StringRes
|
|||
|
||||
let mut table = NuTable::from(data);
|
||||
table.set_index_style(get_key_style(&cfg));
|
||||
table.set_indent(cfg.opts.indent.0, cfg.opts.indent.1);
|
||||
|
||||
let out = TableOutput::new(table, false, true);
|
||||
|
||||
|
|
|
@ -25,7 +25,11 @@ impl JustTable {
|
|||
|
||||
fn create_table(input: &[Value], opts: TableOpts<'_>) -> Result<Option<String>, ShellError> {
|
||||
match table(input, opts.row_offset, opts.clone())? {
|
||||
Some(out) => {
|
||||
Some(mut out) => {
|
||||
let left = opts.config.table_indent.left;
|
||||
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);
|
||||
Ok(out.table.draw(table_config, opts.width))
|
||||
|
@ -56,7 +60,12 @@ fn kv_table(cols: &[String], vals: &[Value], opts: TableOpts<'_>) -> StringResul
|
|||
let mut table = NuTable::from(data);
|
||||
table.set_index_style(TextStyle::default_field());
|
||||
|
||||
let out = TableOutput::new(table, false, true);
|
||||
let mut out = TableOutput::new(table, false, true);
|
||||
|
||||
let left = opts.config.table_indent.left;
|
||||
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 = out.table.draw(table_config, opts.width);
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@ pub struct TableOpts<'a> {
|
|||
span: Span,
|
||||
row_offset: usize,
|
||||
width: usize,
|
||||
indent: (usize, usize),
|
||||
}
|
||||
|
||||
impl<'a> TableOpts<'a> {
|
||||
|
@ -45,7 +46,8 @@ impl<'a> TableOpts<'a> {
|
|||
ctrlc: Option<Arc<AtomicBool>>,
|
||||
span: Span,
|
||||
row_offset: usize,
|
||||
available_width: usize,
|
||||
width: usize,
|
||||
indent: (usize, usize),
|
||||
) -> Self {
|
||||
Self {
|
||||
ctrlc,
|
||||
|
@ -53,7 +55,8 @@ impl<'a> TableOpts<'a> {
|
|||
style_computer,
|
||||
span,
|
||||
row_offset,
|
||||
width: available_width,
|
||||
indent,
|
||||
width,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ use tabled::{
|
|||
config::{AlignmentHorizontal, Borders, CompactMultilineConfig},
|
||||
dimension::{DimensionPriority, PoolTableDimension},
|
||||
},
|
||||
settings::{style::RawStyle, Color, TableOption},
|
||||
settings::{style::RawStyle, Color, Padding, TableOption},
|
||||
tables::{PoolTable, TableValue},
|
||||
};
|
||||
|
||||
|
@ -35,17 +35,28 @@ impl UnstructuredTable {
|
|||
truncate_table_value(&mut self.value, has_vertical, available).is_none()
|
||||
}
|
||||
|
||||
pub fn draw(self, style_computer: &StyleComputer, theme: &TableTheme) -> String {
|
||||
build_table(self.value, style_computer, theme)
|
||||
pub fn draw(
|
||||
self,
|
||||
style_computer: &StyleComputer,
|
||||
theme: &TableTheme,
|
||||
indent: (usize, usize),
|
||||
) -> String {
|
||||
build_table(self.value, style_computer, theme, indent)
|
||||
}
|
||||
}
|
||||
|
||||
fn build_table(val: TableValue, style_computer: &StyleComputer, theme: &TableTheme) -> String {
|
||||
fn build_table(
|
||||
val: TableValue,
|
||||
style_computer: &StyleComputer,
|
||||
theme: &TableTheme,
|
||||
indent: (usize, usize),
|
||||
) -> String {
|
||||
let mut table = PoolTable::from(val);
|
||||
|
||||
let mut theme = theme.get_theme_full();
|
||||
theme.set_horizontals(std::collections::HashMap::default());
|
||||
|
||||
table.with(Padding::new(indent.0, indent.1, 0, 0));
|
||||
table.with(SetRawStyle(theme));
|
||||
table.with(SetAlignment(AlignmentHorizontal::Left));
|
||||
table.with(PoolTableDimension::new(
|
||||
|
|
|
@ -158,6 +158,7 @@ $env.config = {
|
|||
mode: rounded # basic, compact, compact_double, light, thin, with_love, rounded, reinforced, heavy, none, other
|
||||
index_mode: always # "always" show indexes, "never" show indexes, "auto" = show indexes when a table has "index" column
|
||||
show_empty: true # show 'empty list' and 'empty record' placeholders for command output
|
||||
padding: { left: 1, right: 1 } # a left right padding of each column in a table
|
||||
trim: {
|
||||
methodology: wrapping # wrapping or truncating
|
||||
wrapping_try_keep_words: true # A strategy used by the 'wrapping' methodology
|
||||
|
|
Loading…
Reference in a new issue