diff --git a/Cargo.lock b/Cargo.lock index 2575d5901a..fc8ab22bbc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3363,6 +3363,7 @@ name = "nu-table" version = "0.24.2" dependencies = [ "ansi_term 0.12.1", + "regex 1.4.2", "unicode-width", ] diff --git a/crates/nu-data/src/primitive.rs b/crates/nu-data/src/primitive.rs index 44d2f996d1..c4fcb5017c 100644 --- a/crates/nu-data/src/primitive.rs +++ b/crates/nu-data/src/primitive.rs @@ -104,6 +104,7 @@ pub fn string_to_lookup_value(str_prim: &str) -> String { "header_bold" => "header_bold".to_string(), "header_style" => "header_style".to_string(), "index_color" => "index_color".to_string(), + "leading_trailing_space_bg" => "leading_trailing_space_bg".to_string(), _ => "Primitive::Nothing".to_string(), } } @@ -143,6 +144,10 @@ pub fn get_color_config() -> HashMap { hm.insert("header_bold".to_string(), Color::Green.bold()); hm.insert("header_style".to_string(), Style::default()); hm.insert("index_color".to_string(), Color::Green.bold()); + hm.insert( + "leading_trailing_space_bg".to_string(), + Style::default().on(Color::RGB(128, 128, 128)), + ); // populate hashmap from config values if let Ok(config) = crate::config::config(Tag::unknown()) { @@ -206,6 +211,9 @@ pub fn get_color_config() -> HashMap { "index_color" => { update_hashmap(&key, &value, &mut hm); } + "leading_trailing_space_bg" => { + update_hashmap(&key, &value, &mut hm); + } _ => (), } } diff --git a/crates/nu-table/Cargo.toml b/crates/nu-table/Cargo.toml index a30a329e07..807fb1a2cd 100644 --- a/crates/nu-table/Cargo.toml +++ b/crates/nu-table/Cargo.toml @@ -14,3 +14,4 @@ path = "src/main.rs" [dependencies] ansi_term = "0.12.1" unicode-width = "0.1.8" +regex = "1.4.2" diff --git a/crates/nu-table/src/table.rs b/crates/nu-table/src/table.rs index 1e39ad02b3..f391119873 100644 --- a/crates/nu-table/src/table.rs +++ b/crates/nu-table/src/table.rs @@ -778,7 +778,6 @@ impl WrappedTable { } println!("{}", output); - // println!("{:#?}", output); } fn print_cell_contents(&self, cells: &[WrappedCell], color_hm: &HashMap) { @@ -804,7 +803,6 @@ impl WrappedTable { let remainder = self.column_widths[column.0] - line.width; output.push(' '); - // println!("Column1: [{:?}]", column.1.style); match column.1.style.alignment { Alignment::Left => { if let Some(color) = column.1.style.color_style { @@ -869,7 +867,7 @@ impl WrappedTable { } } - fn new_print_table(&self, color_hm: &HashMap) { + fn print_table(&self, color_hm: &HashMap) { #[cfg(windows)] { let _ = ansi_term::enable_ansi_support(); @@ -1015,12 +1013,16 @@ pub fn draw_table(table: &Table, termwidth: usize, color_hm: &HashMap WrappedTable { +fn wrap_cells( + processed_table: ProcessedTable, + max_column_width: usize, + color_hm: &HashMap, +) -> WrappedTable { let mut column_widths = vec![ 0; std::cmp::max( @@ -1041,7 +1043,8 @@ fn wrap_cells(processed_table: ProcessedTable, max_column_width: usize) -> Wrapp }; for contents in header.1.contents.into_iter() { - let (mut lines, inner_max_width) = wrap(max_column_width, contents.into_iter()); + let (mut lines, inner_max_width) = + wrap(max_column_width, contents.into_iter(), &color_hm); wrapped.lines.append(&mut lines); if inner_max_width > wrapped.max_width { wrapped.max_width = inner_max_width; @@ -1063,7 +1066,8 @@ fn wrap_cells(processed_table: ProcessedTable, max_column_width: usize) -> Wrapp style: column.1.style, }; for contents in column.1.contents.into_iter() { - let (mut lines, inner_max_width) = wrap(max_column_width, contents.into_iter()); + let (mut lines, inner_max_width) = + wrap(max_column_width, contents.into_iter(), &color_hm); wrapped.lines.append(&mut lines); if inner_max_width > wrapped.max_width { wrapped.max_width = inner_max_width; diff --git a/crates/nu-table/src/wrap.rs b/crates/nu-table/src/wrap.rs index c4803af905..a54874d0fa 100644 --- a/crates/nu-table/src/wrap.rs +++ b/crates/nu-table/src/wrap.rs @@ -1,4 +1,6 @@ use crate::table::TextStyle; +use ansi_term::Style; +use std::collections::HashMap; use std::{fmt::Display, iter::Iterator}; use unicode_width::UnicodeWidthStr; @@ -136,12 +138,18 @@ fn split_word<'a>(cell_width: usize, word: &'a str) -> Vec> { pub fn wrap<'a>( cell_width: usize, mut input: impl Iterator>, + color_hm: &HashMap, ) -> (Vec, usize) { let mut lines = vec![]; let mut current_line: Vec = vec![]; let mut current_width = 0; let mut first = true; let mut max_width = 0; + let lead_trail_space_bg_color = color_hm + .get("leading_trailing_space_bg") + .unwrap_or(&Style::default()) + .to_owned(); + loop { match input.next() { Some(item) => { @@ -233,6 +241,28 @@ pub fn wrap<'a>( current_max = current_line_width; } + // highlight leading and trailing spaces so they stand out. + let mut bg_color_string = Style::default().prefix().to_string(); + // right now config settings can only set foreground colors so, in this + // instance we take the foreground color and make it a background color + if let Some(bg) = lead_trail_space_bg_color.foreground { + bg_color_string = Style::default().on(bg).prefix().to_string() + }; + + let re_leading = + regex::Regex::new(r"(?P^\s+)").expect("error with leading space regex"); + if let Some(leading_match) = re_leading.find(¤t_line.clone()) { + String::insert_str(&mut current_line, leading_match.end(), "\x1b[0m"); + String::insert_str(&mut current_line, leading_match.start(), &bg_color_string); + } + + let re_trailing = + regex::Regex::new(r"(?P\s+$)").expect("error with trailing space regex"); + if let Some(trailing_match) = re_trailing.find(¤t_line.clone()) { + String::insert_str(&mut current_line, trailing_match.start(), &bg_color_string); + current_line += "\x1b[0m"; + } + output.push(WrappedLine { line: current_line, width: current_line_width, diff --git a/docs/sample_config/config.toml b/docs/sample_config/config.toml index 7dc852e208..c9a508246c 100644 --- a/docs/sample_config/config.toml +++ b/docs/sample_config/config.toml @@ -53,6 +53,7 @@ header_align = "l" # left|l, right|r, center|c header_color = "c" # green|g, red|r, blue|u, black|b, yellow|y, purple|p, cyan|c, white|w header_bold = true index_color = "rd" +leading_trailing_space_bg = "white" [line_editor] max_history_size = 100000