nu-table: Fix expand table unnessary color in trail head config when wrap is used (#10367)

So it must address it,
But please check.

PS: I don't like the patch... but it is what it is

fix: #10359
cc: @amtoine
This commit is contained in:
Maxim Zhiburt 2023-09-15 16:44:53 +00:00 committed by GitHub
parent 5ee74b6ab5
commit 2b77544e58
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 101 additions and 100 deletions

View File

@ -2,7 +2,9 @@ use nu_color_config::{Alignment, StyleComputer, TextStyle};
use nu_protocol::TrimStrategy;
use nu_protocol::{Config, FooterMode, ShellError, Span, Value};
use crate::{clean_charset, string_wrap, NuTableConfig, TableOutput, TableTheme};
use crate::{
clean_charset, colorize_space_str, string_wrap, NuTableConfig, TableOutput, TableTheme,
};
pub type NuText = (String, TextStyle);
pub type TableResult = Result<Option<TableOutput>, ShellError>;
@ -34,9 +36,11 @@ pub fn nu_value_to_string(val: &Value, cfg: &Config, style: &StyleComputer) -> N
make_styled_string(style, text, Some(val), float_precision)
}
pub fn nu_value_to_string_clean(val: &Value, cfg: &Config, style: &StyleComputer) -> NuText {
let (text, style) = nu_value_to_string(val, cfg, style);
let text = clean_charset(&text);
pub fn nu_value_to_string_clean(val: &Value, cfg: &Config, style_comp: &StyleComputer) -> NuText {
let (text, style) = nu_value_to_string(val, cfg, style_comp);
let mut text = clean_charset(&text);
colorize_space_str(&mut text, style_comp);
(text, style)
}

View File

@ -1,4 +1,4 @@
use crate::table_theme::TableTheme;
use crate::{convert_style, table_theme::TableTheme};
use nu_ansi_term::Style;
use nu_color_config::TextStyle;
use nu_protocol::TrimStrategy;
@ -41,8 +41,6 @@ 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,
}
@ -140,17 +138,14 @@ 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);
}
pub fn get_records_mut(&mut self) -> &mut NuRecords {
&mut self.data
}
/// Converts a table to a String.
///
/// It returns None in case where table cannot be fit to a terminal width.
@ -235,7 +230,7 @@ fn build_table(
}
fn draw_table(
mut data: NuRecords,
data: NuRecords,
alignments: Alignments,
styles: Styles,
widths: Vec<usize>,
@ -249,12 +244,6 @@ 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();
@ -727,10 +716,6 @@ impl<R, D> TableOption<R, D, ColoredConfig> for SetAlignment {
}
}
fn convert_style(style: Style) -> Color {
Color::new(style.prefix().to_string(), style.suffix().to_string())
}
struct SetDimensions(Vec<usize>);
impl<R> TableOption<R, CompleteDimensionVecRecords<'_>, ColoredConfig> for SetDimensions {
@ -928,51 +913,6 @@ 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);
}
}
}
struct StripColorFromRow(usize);
impl TableOption<NuRecords, CompleteDimensionVecRecords<'_>, ColoredConfig> for StripColorFromRow {

View File

@ -9,8 +9,8 @@ use tabled::grid::config::Position;
use crate::{
common::{
create_nu_table_config, error_sign, get_header_style, get_index_style,
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,
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,10 +178,6 @@ 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)));
}
@ -341,10 +337,6 @@ 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)))
}
@ -395,10 +387,6 @@ 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)

View File

@ -3,10 +3,10 @@ use nu_engine::column::get_columns;
use nu_protocol::{ast::PathMember, Config, Record, ShellError, Span, TableIndexMode, Value};
use crate::{
clean_charset,
clean_charset, colorize_space,
common::{
create_nu_table_config, get_empty_style, get_header_style, get_index_style,
get_leading_trailing_space_style, get_value_style, NuText, INDEX_COLUMN_NAME,
get_value_style, NuText, INDEX_COLUMN_NAME,
},
NuTable, NuTableCell, StringResult, TableOpts, TableOutput, TableResult,
};
@ -30,6 +30,8 @@ fn create_table(input: &[Value], opts: TableOpts<'_>) -> Result<Option<String>,
let right = opts.config.table_indent.right;
out.table.set_indent(left, right);
colorize_space(out.table.get_records_mut(), opts.style_computer);
let table_config =
create_nu_table_config(opts.config, opts.style_computer, &out, false);
Ok(out.table.draw(table_config, opts.width))
@ -57,13 +59,11 @@ fn kv_table(record: &Record, opts: TableOpts<'_>) -> StringResult {
row.push(value);
}
colorize_space(&mut data, opts.style_computer);
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;
@ -125,10 +125,6 @@ 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());
}
@ -168,10 +164,6 @@ 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);

View File

@ -1,9 +1,14 @@
use nu_color_config::StyleComputer;
use tabled::{
builder::Builder,
grid::util::string::string_width_multiline,
settings::{width::Truncate, Modify, Padding, Style, Width},
grid::{
color::AnsiColor, records::vec_records::CellInfo, util::string::string_width_multiline,
},
settings::{width::Truncate, Color, Modify, Padding, Style, Width},
};
use crate::common::get_leading_trailing_space_style;
pub fn string_width(text: &str) -> usize {
string_width_multiline(text)
}
@ -47,3 +52,75 @@ pub fn clean_charset(text: &str) -> String {
// todo: optimize, I bet it can be done in 1 path
text.replace('\t', " ").replace('\r', "")
}
pub fn colorize_space(data: &mut [Vec<CellInfo<String>>], style_computer: &StyleComputer<'_>) {
if let Some(style) = get_leading_trailing_space_style(style_computer).color_style {
let style = convert_style(style).into();
colorize_lead_trail_space(data, Some(&style), Some(&style));
}
}
pub fn colorize_space_str(text: &mut String, style_computer: &StyleComputer<'_>) {
if let Some(style) = get_leading_trailing_space_style(style_computer).color_style {
let style = convert_style(style).into();
*text = colorize_space_one(text, Some(&style), Some(&style));
}
}
fn colorize_lead_trail_space(
data: &mut [Vec<CellInfo<String>>],
lead: Option<&AnsiColor<'_>>,
trail: Option<&AnsiColor<'_>>,
) {
if lead.is_none() && trail.is_none() {
return;
}
for row in data.iter_mut() {
for cell in row {
let buf = colorize_space_one(cell.as_ref(), lead, trail);
*cell = CellInfo::new(buf);
}
}
}
fn colorize_space_one(
text: &str,
lead: Option<&AnsiColor<'_>>,
trail: Option<&AnsiColor<'_>>,
) -> String {
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"));
let mut buf = text.to_owned();
if let Some(color) = &lead {
buf = RE_LEADING
.replace_all(&buf, |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, |cap: &Captures| {
let spaces = cap.get(1).expect("valid").as_str();
format!("{}{}{}", color.get_prefix(), spaces, color.get_suffix())
})
.into_owned();
}
buf
}
pub fn convert_style(style: nu_ansi_term::Style) -> Color {
Color::new(style.prefix().to_string(), style.suffix().to_string())
}