From 28123841baf30124feb41c44c471ce74e6963d57 Mon Sep 17 00:00:00 2001 From: Maxim Zhiburt Date: Sun, 18 Dec 2022 17:43:15 +0300 Subject: [PATCH] Patch explore 4 (#7517) ref #7339 - This PR updates explore to take some of the colors from nushell, namely the line colors and the ls_colors. note: Not sure why this regression appeared maybe it's a feature or it's no longer supposed to be supported? Signed-off-by: Maxim Zhiburt Co-authored-by: Darren Schroeder <343840+fdncred@users.noreply.github.com> --- Cargo.lock | 3 + crates/nu-color-config/Cargo.toml | 3 +- crates/nu-color-config/src/color_config.rs | 21 +++- crates/nu-color-config/src/nu_style.rs | 1 + crates/nu-command/src/viewers/explore.rs | 45 ++++++- crates/nu-explore/Cargo.toml | 4 +- crates/nu-explore/src/lib.rs | 2 +- crates/nu-explore/src/nu_common/lscolor.rs | 115 ++++++++++++++++++ crates/nu-explore/src/nu_common/mod.rs | 2 + crates/nu-explore/src/nu_common/value.rs | 133 +++++++++++---------- crates/nu-explore/src/pager/mod.rs | 9 ++ crates/nu-explore/src/views/mod.rs | 4 + crates/nu-explore/src/views/record/mod.rs | 6 +- crates/nu-explore/src/views/util.rs | 8 +- 14 files changed, 276 insertions(+), 80 deletions(-) create mode 100644 crates/nu-explore/src/nu_common/lscolor.rs diff --git a/Cargo.lock b/Cargo.lock index 3539866838..96fc7d2bbc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2566,6 +2566,7 @@ version = "0.72.2" dependencies = [ "nu-ansi-term", "nu-engine", + "nu-json", "nu-path", "nu-protocol", "nu-test-support", @@ -2691,6 +2692,7 @@ version = "0.72.2" dependencies = [ "ansi-str 0.7.2", "crossterm 0.24.0", + "lscolors", "nu-ansi-term", "nu-color-config", "nu-engine", @@ -2698,6 +2700,7 @@ dependencies = [ "nu-parser", "nu-protocol", "nu-table", + "nu-utils", "strip-ansi-escapes", "terminal_size 0.2.1", "tui", diff --git a/crates/nu-color-config/Cargo.toml b/crates/nu-color-config/Cargo.toml index 04e9c2b62a..a0ce71aa1f 100644 --- a/crates/nu-color-config/Cargo.toml +++ b/crates/nu-color-config/Cargo.toml @@ -18,4 +18,5 @@ nu-utils = { path = "../nu-utils", version = "0.72.2" } nu-engine = { path = "../nu-engine", version = "0.72.2" } nu-test-support = { path="../nu-test-support", version = "0.72.2" } # nu-path is used only for test support -nu-path = { path="../nu-path", version = "0.72.2" } \ No newline at end of file +nu-path = { path="../nu-path", version = "0.72.2" } +nu-json = { path="../nu-json", version = "0.72.2" } diff --git a/crates/nu-color-config/src/color_config.rs b/crates/nu-color-config/src/color_config.rs index 56d182871b..6d605e5e66 100644 --- a/crates/nu-color-config/src/color_config.rs +++ b/crates/nu-color-config/src/color_config.rs @@ -1,4 +1,7 @@ -use crate::nu_style::{color_from_hex, lookup_style}; +use crate::{ + nu_style::{color_from_hex, lookup_style}, + parse_nustyle, NuStyle, +}; use nu_ansi_term::Style; use nu_protocol::Value; use std::collections::HashMap; @@ -9,6 +12,8 @@ pub fn lookup_ansi_color_style(s: &str) -> Style { .ok() .and_then(|c| c.map(|c| c.normal())) .unwrap_or_default() + } else if s.starts_with('{') { + color_string_to_nustyle(s.to_string()) } else { lookup_style(s) } @@ -36,3 +41,17 @@ pub fn get_color_map(colors: &HashMap) -> HashMap hm } + +fn color_string_to_nustyle(color_string: String) -> Style { + // eprintln!("color_string: {}", &color_string); + if color_string.is_empty() { + return Style::default(); + } + + let nu_style = match nu_json::from_str::(&color_string) { + Ok(s) => s, + Err(_) => return Style::default(), + }; + + parse_nustyle(nu_style) +} diff --git a/crates/nu-color-config/src/nu_style.rs b/crates/nu-color-config/src/nu_style.rs index 725bdab30d..b11a4184e4 100644 --- a/crates/nu-color-config/src/nu_style.rs +++ b/crates/nu-color-config/src/nu_style.rs @@ -106,6 +106,7 @@ pub fn color_record_to_nustyle(value: &Value) -> Style { } } } + parse_nustyle(NuStyle { fg, bg, attr }) } diff --git a/crates/nu-command/src/viewers/explore.rs b/crates/nu-command/src/viewers/explore.rs index e527d5a9dd..5fe14948ba 100644 --- a/crates/nu-command/src/viewers/explore.rs +++ b/crates/nu-command/src/viewers/explore.rs @@ -74,13 +74,16 @@ impl Command for Explore { let mut config = nu_config.explore.clone(); prepare_default_config(&mut config); update_config(&mut config, show_index, show_head); + include_nu_config(&mut config, &style_computer); let show_banner = is_need_banner(&config).unwrap_or(true); let exit_esc = is_need_esc_exit(&config).unwrap_or(true); let style = style_from_config(&config); - let mut config = PagerConfig::new(nu_config, &style_computer, config); + let lscolors = nu_explore::util::create_lscolors(engine_state, stack); + + let mut config = PagerConfig::new(nu_config, &style_computer, &lscolors, config); config.style = style; config.reverse = is_reverse; config.peek_value = peek_value; @@ -246,6 +249,7 @@ fn prepare_default_config(config: &mut HashMap) { config.insert(String::from("status"), map_into_value(hm)); } + { let mut hm = config .get("table") @@ -322,8 +326,7 @@ fn insert_style(map: &mut HashMap, key: &str, value: Style) { } let value = nu_color_config::NuStyle::from(value); - - if let Ok(val) = nu_json::to_string(&value) { + if let Ok(val) = nu_json::to_string_raw(&value) { map.insert(String::from(key), Value::string(val, Span::unknown())); } } @@ -368,3 +371,39 @@ fn convert_json_value_into_value(value: nu_json::Value) -> Value { } } } + +fn include_nu_config(config: &mut HashMap, style_computer: &StyleComputer) { + let line_color = lookup_color(style_computer, "separator"); + if line_color != nu_ansi_term::Style::default() { + { + let mut map = config + .get("table") + .and_then(parse_hash_map) + .unwrap_or_default(); + insert_style(&mut map, "split_line", line_color); + config.insert(String::from("table"), map_into_value(map)); + } + + { + let mut map = config + .get("try") + .and_then(parse_hash_map) + .unwrap_or_default(); + insert_style(&mut map, "border_color", line_color); + config.insert(String::from("try"), map_into_value(map)); + } + + { + let mut map = config + .get("config") + .and_then(parse_hash_map) + .unwrap_or_default(); + insert_style(&mut map, "border_color", line_color); + config.insert(String::from("config"), map_into_value(map)); + } + } +} + +fn lookup_color(style_computer: &StyleComputer, key: &str) -> nu_ansi_term::Style { + style_computer.compute(key, &Value::nothing(Span::unknown())) +} diff --git a/crates/nu-explore/Cargo.toml b/crates/nu-explore/Cargo.toml index 7d78b4aa98..2c3d7451c2 100644 --- a/crates/nu-explore/Cargo.toml +++ b/crates/nu-explore/Cargo.toml @@ -14,10 +14,12 @@ nu-parser = { path = "../nu-parser", version = "0.72.2" } nu-color-config = { path = "../nu-color-config", version = "0.72.2" } nu-engine = { path = "../nu-engine", version = "0.72.2" } nu-table = { path = "../nu-table", version = "0.72.2" } -nu-json = { path="../nu-json", version = "0.72.2" } +nu-json = { path = "../nu-json", version = "0.72.2" } +nu-utils = { path = "../nu-utils", version = "0.72.2" } terminal_size = "0.2.1" strip-ansi-escapes = "0.1.1" crossterm = "0.24.0" tui = "0.19.0" ansi-str = "0.7.2" +lscolors = { version = "0.12.0", features = ["crossterm"], default-features = false } diff --git a/crates/nu-explore/src/lib.rs b/crates/nu-explore/src/lib.rs index 5a3eb4d2aa..1d74e3b3b9 100644 --- a/crates/nu-explore/src/lib.rs +++ b/crates/nu-explore/src/lib.rs @@ -23,7 +23,7 @@ use views::{InformationView, Orientation, Preview, RecordView}; pub use pager::{PagerConfig, StyleConfig}; pub mod util { - pub use super::nu_common::{create_map, map_into_value}; + pub use super::nu_common::{create_lscolors, create_map, map_into_value}; } pub fn run_pager( diff --git a/crates/nu-explore/src/nu_common/lscolor.rs b/crates/nu-explore/src/nu_common/lscolor.rs new file mode 100644 index 0000000000..c2e46251c5 --- /dev/null +++ b/crates/nu-explore/src/nu_common/lscolor.rs @@ -0,0 +1,115 @@ +use std::fs::symlink_metadata; + +use lscolors::LsColors; +use nu_ansi_term::{Color, Style}; +use nu_engine::env_to_string; +use nu_protocol::engine::{EngineState, Stack}; +use nu_utils::get_ls_colors; + +use super::NuText; + +pub fn create_lscolors(engine_state: &EngineState, stack: &Stack) -> LsColors { + let colors = stack + .get_env_var(engine_state, "LS_COLORS") + .and_then(|v| env_to_string("LS_COLORS", &v, engine_state, stack).ok()); + + get_ls_colors(colors) +} + +pub fn lscolorize(header: &[String], data: &mut [Vec], lscolors: &LsColors) { + for (col, col_name) in header.iter().enumerate() { + if col_name != "name" { + continue; + } + + for row in data.iter_mut() { + let (path, text_style) = &mut row[col]; + + let style = get_path_style(path, lscolors); + if let Some(style) = style { + *text_style = text_style.style(style); + } + } + } +} + +fn get_path_style(path: &str, ls_colors: &LsColors) -> Option