forked from extern/nushell
Patch restore lead trail space bg color (#10351)
```nu $env.config.color_config.leading_trailing_space_bg = { bg: 'white' }; [[a b, 'c ']; [' 1 ' ' 2' '3 '] [' 4 ' "hello \n world " [' 1 ' 2 [1 ' 2 ' 3]]]] | table --expand ``` ![image](https://github.com/nushell/nushell/assets/20165848/01a35042-0e36-4c51-99a9-3011fabb551b) ref: #2794 close: #10317 note: test are not actually make scenes cause `nu!` strips colors. (Ideally it would need a flag to not do so) note: It does does does ... slower down quite a bit rendering... ( PS: Maybe it's better being a flag to `table` rather then a configuration option? PS: I am not sure why the logic was removed in a first place
This commit is contained in:
parent
bbea7da669
commit
73d3708006
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -3078,11 +3078,13 @@ dependencies = [
|
||||
name = "nu-table"
|
||||
version = "0.84.1"
|
||||
dependencies = [
|
||||
"fancy-regex",
|
||||
"nu-ansi-term",
|
||||
"nu-color-config",
|
||||
"nu-engine",
|
||||
"nu-protocol",
|
||||
"nu-utils",
|
||||
"once_cell",
|
||||
"tabled",
|
||||
]
|
||||
|
||||
|
@ -2664,3 +2664,25 @@ fn table_collapse_padding_zero() {
|
||||
╰─┴─┴─╯"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn table_leading_trailing_space_bg() {
|
||||
let actual = nu!(
|
||||
r#"$env.config.color_config.leading_trailing_space_bg = { bg: 'white' }; [[a b, 'c ']; [' 1 ' ' 2' '3 '] [' 4 ' "hello\nworld" [' 1 ' 2 [1 ' 2 ' 3]]]] | table"#
|
||||
);
|
||||
assert_eq!(
|
||||
actual.out,
|
||||
"╭───┬───────┬───────┬────────────────╮│ # │ a │ b │ c │├───┼───────┼───────┼────────────────┤│ 0 │ 1 │ 2 │ 3 ││ 1 │ 4 │ hello │ [list 3 items] ││ │ │ world │ │╰───┴───────┴───────┴────────────────╯"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn table_leading_trailing_space_bg_expand() {
|
||||
let actual = nu!(
|
||||
r#"$env.config.color_config.leading_trailing_space_bg = { bg: 'white' }; [[a b, 'c ']; [' 1 ' ' 2' '3 '] [' 4 ' "hello\nworld" [' 1 ' 2 [1 ' 2 ' 3]]]] | table --expand"#
|
||||
);
|
||||
assert_eq!(
|
||||
actual.out,
|
||||
"╭───┬───────┬───────┬───────────────────────╮│ # │ a │ b │ c │├───┼───────┼───────┼───────────────────────┤│ 0 │ 1 │ 2 │ 3 ││ 1 │ 4 │ hello │ ╭───┬───────────────╮ ││ │ │ world │ │ 0 │ 1 │ ││ │ │ │ │ 1 │ 2 │ ││ │ │ │ │ 2 │ ╭───┬───────╮ │ ││ │ │ │ │ │ │ 0 │ 1 │ │ ││ │ │ │ │ │ │ 1 │ 2 │ │ ││ │ │ │ │ │ │ 2 │ 3 │ │ ││ │ │ │ │ │ ╰───┴───────╯ │ ││ │ │ │ ╰───┴───────────────╯ │╰───┴───────┴───────┴───────────────────────╯"
|
||||
);
|
||||
}
|
||||
|
@ -16,6 +16,8 @@ nu-utils = { path = "../nu-utils", version = "0.84.1" }
|
||||
nu-engine = { path = "../nu-engine", version = "0.84.1" }
|
||||
nu-color-config = { path = "../nu-color-config", version = "0.84.1" }
|
||||
nu-ansi-term = "0.49.0"
|
||||
once_cell = "1.18"
|
||||
fancy-regex = "0.11"
|
||||
tabled = { version = "0.14.0", features = ["color"], default-features = false }
|
||||
|
||||
[dev-dependencies]
|
||||
|
@ -62,6 +62,16 @@ pub fn get_index_style(style_computer: &StyleComputer) -> TextStyle {
|
||||
)
|
||||
}
|
||||
|
||||
pub fn get_leading_trailing_space_style(style_computer: &StyleComputer) -> TextStyle {
|
||||
TextStyle::with_style(
|
||||
Alignment::Right,
|
||||
style_computer.compute(
|
||||
"leading_trailing_space_bg",
|
||||
&Value::string("", Span::unknown()),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn get_value_style(value: &Value, config: &Config, style_computer: &StyleComputer) -> NuText {
|
||||
match value {
|
||||
// Float precision is required here.
|
||||
|
@ -40,6 +40,8 @@ struct Styles {
|
||||
index: AnsiColor<'static>,
|
||||
header: AnsiColor<'static>,
|
||||
data: EntityMap<AnsiColor<'static>>,
|
||||
space_lead: Option<AnsiColor<'static>>,
|
||||
space_trail: Option<AnsiColor<'static>>,
|
||||
data_is_set: bool,
|
||||
}
|
||||
|
||||
@ -137,6 +139,13 @@ impl NuTable {
|
||||
self.alignments.data = convert_alignment(style.alignment);
|
||||
}
|
||||
|
||||
pub fn set_trail_lead_style(&mut self, head: Style, tail: Style) {
|
||||
let style_head = AnsiColor::from(convert_style(head));
|
||||
let style_tail = AnsiColor::from(convert_style(tail));
|
||||
self.styles.space_trail = Some(style_tail);
|
||||
self.styles.space_lead = Some(style_head);
|
||||
}
|
||||
|
||||
pub fn set_indent(&mut self, left: usize, right: usize) {
|
||||
self.indent = (left, right);
|
||||
}
|
||||
@ -225,7 +234,7 @@ fn build_table(
|
||||
}
|
||||
|
||||
fn draw_table(
|
||||
data: NuRecords,
|
||||
mut data: NuRecords,
|
||||
alignments: Alignments,
|
||||
styles: Styles,
|
||||
widths: Vec<usize>,
|
||||
@ -239,6 +248,12 @@ fn draw_table(
|
||||
let sep_color = cfg.split_color;
|
||||
let border_header = cfg.header_on_border;
|
||||
|
||||
colorize_lead_trail_space(
|
||||
&mut data,
|
||||
styles.space_lead.clone(),
|
||||
styles.space_trail.clone(),
|
||||
);
|
||||
|
||||
let data: Vec<Vec<_>> = data.into();
|
||||
let mut table = Builder::from(data).build();
|
||||
|
||||
@ -908,3 +923,48 @@ fn remove_row(recs: &mut NuRecords, row: usize) -> Vec<String> {
|
||||
|
||||
columns
|
||||
}
|
||||
|
||||
fn colorize_lead_trail_space(
|
||||
data: &mut NuRecords,
|
||||
lead: Option<AnsiColor<'_>>,
|
||||
trail: Option<AnsiColor<'_>>,
|
||||
) {
|
||||
use fancy_regex::Captures;
|
||||
use fancy_regex::Regex;
|
||||
use once_cell::sync::Lazy;
|
||||
|
||||
static RE_LEADING: Lazy<Regex> =
|
||||
Lazy::new(|| Regex::new(r"(?m)(?P<beginsp>^\s+)").expect("error with leading space regex"));
|
||||
static RE_TRAILING: Lazy<Regex> =
|
||||
Lazy::new(|| Regex::new(r"(?m)(?P<endsp>\s+$)").expect("error with trailing space regex"));
|
||||
|
||||
if lead.is_none() && trail.is_none() {
|
||||
return;
|
||||
}
|
||||
|
||||
for row in data.iter_mut() {
|
||||
for cell in row {
|
||||
let mut buf = cell.as_ref().to_owned();
|
||||
|
||||
if let Some(color) = &lead {
|
||||
buf = RE_LEADING
|
||||
.replace_all(cell.as_ref(), |cap: &Captures| {
|
||||
let spaces = cap.get(1).expect("valid").as_str();
|
||||
format!("{}{}{}", color.get_prefix(), spaces, color.get_suffix())
|
||||
})
|
||||
.into_owned();
|
||||
}
|
||||
|
||||
if let Some(color) = &trail {
|
||||
buf = RE_TRAILING
|
||||
.replace_all(buf.as_ref(), |cap: &Captures| {
|
||||
let spaces = cap.get(1).expect("valid").as_str();
|
||||
format!("{}{}{}", color.get_prefix(), spaces, color.get_suffix())
|
||||
})
|
||||
.into_owned();
|
||||
}
|
||||
|
||||
*cell = CellInfo::new(buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,8 +9,8 @@ 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, wrap_text, NuText,
|
||||
StringResult, TableResult, INDEX_COLUMN_NAME,
|
||||
get_leading_trailing_space_style, load_theme_from_config, nu_value_to_string,
|
||||
nu_value_to_string_clean, wrap_text, NuText, StringResult, TableResult, INDEX_COLUMN_NAME,
|
||||
},
|
||||
string_width, NuTable, NuTableCell, TableOpts, TableOutput,
|
||||
};
|
||||
@ -178,6 +178,10 @@ fn expanded_table_list(input: &[Value], cfg: Cfg<'_>) -> TableResult {
|
||||
table.set_index_style(get_index_style(cfg.opts.style_computer));
|
||||
set_data_styles(&mut table, data_styles);
|
||||
|
||||
if let Some(style) = get_leading_trailing_space_style(cfg.opts.style_computer).color_style {
|
||||
table.set_trail_lead_style(style, style);
|
||||
}
|
||||
|
||||
return Ok(Some(TableOutput::new(table, false, with_index)));
|
||||
}
|
||||
|
||||
@ -337,6 +341,10 @@ fn expanded_table_list(input: &[Value], cfg: Cfg<'_>) -> TableResult {
|
||||
table.set_indent(cfg.opts.indent.0, cfg.opts.indent.1);
|
||||
set_data_styles(&mut table, data_styles);
|
||||
|
||||
if let Some(style) = get_leading_trailing_space_style(cfg.opts.style_computer).color_style {
|
||||
table.set_trail_lead_style(style, style);
|
||||
}
|
||||
|
||||
Ok(Some(TableOutput::new(table, true, with_index)))
|
||||
}
|
||||
|
||||
@ -387,6 +395,10 @@ fn expanded_table_kv(record: &Record, cfg: Cfg<'_>) -> StringResult {
|
||||
table.set_index_style(get_key_style(&cfg));
|
||||
table.set_indent(cfg.opts.indent.0, cfg.opts.indent.1);
|
||||
|
||||
if let Some(style) = get_leading_trailing_space_style(cfg.opts.style_computer).color_style {
|
||||
table.set_trail_lead_style(style, style);
|
||||
}
|
||||
|
||||
let out = TableOutput::new(table, false, true);
|
||||
|
||||
maybe_expand_table(out, cfg.opts.width, &cfg.opts)
|
||||
|
@ -6,7 +6,7 @@ use crate::{
|
||||
clean_charset,
|
||||
common::{
|
||||
create_nu_table_config, get_empty_style, get_header_style, get_index_style,
|
||||
get_value_style, NuText, INDEX_COLUMN_NAME,
|
||||
get_leading_trailing_space_style, get_value_style, NuText, INDEX_COLUMN_NAME,
|
||||
},
|
||||
NuTable, NuTableCell, StringResult, TableOpts, TableOutput, TableResult,
|
||||
};
|
||||
@ -60,6 +60,10 @@ fn kv_table(record: &Record, opts: TableOpts<'_>) -> StringResult {
|
||||
let mut table = NuTable::from(data);
|
||||
table.set_index_style(TextStyle::default_field());
|
||||
|
||||
if let Some(style) = get_leading_trailing_space_style(opts.style_computer).color_style {
|
||||
table.set_trail_lead_style(style, style);
|
||||
}
|
||||
|
||||
let mut out = TableOutput::new(table, false, true);
|
||||
|
||||
let left = opts.config.table_indent.left;
|
||||
@ -121,6 +125,10 @@ fn to_table_with_header(
|
||||
table.set_header_style(get_header_style(opts.style_computer));
|
||||
table.set_index_style(get_index_style(opts.style_computer));
|
||||
|
||||
if let Some(style) = get_leading_trailing_space_style(opts.style_computer).color_style {
|
||||
table.set_trail_lead_style(style, style);
|
||||
}
|
||||
|
||||
for (i, text) in headers.iter().enumerate() {
|
||||
table.insert((0, i), text.to_owned());
|
||||
}
|
||||
@ -160,6 +168,10 @@ fn to_table_with_no_header(
|
||||
let mut table = NuTable::new(input.len(), with_index as usize + 1);
|
||||
table.set_index_style(get_index_style(opts.style_computer));
|
||||
|
||||
if let Some(style) = get_leading_trailing_space_style(opts.style_computer).color_style {
|
||||
table.set_trail_lead_style(style, style);
|
||||
}
|
||||
|
||||
for (row, item) in input.iter().enumerate() {
|
||||
if nu_utils::ctrl_c::was_pressed(&opts.ctrlc) {
|
||||
return Ok(None);
|
||||
|
Loading…
Reference in New Issue
Block a user