mirror of
https://github.com/nushell/nushell
synced 2024-12-28 22:13:10 +00:00
allow fg, bg, attributes to be set for all colors in color_config (#489)
* allow fg, bg, attributes to be set for all colors in color_config * no need for comma between each key value
This commit is contained in:
parent
04a9c8f3fd
commit
a5c1dd0da5
2 changed files with 136 additions and 18 deletions
|
@ -1,6 +1,7 @@
|
||||||
use nu_ansi_term::{Color, Style};
|
use nu_ansi_term::{Color, Style};
|
||||||
use nu_protocol::Config;
|
use nu_protocol::Config;
|
||||||
use nu_table::{Alignment, TextStyle};
|
use nu_table::{Alignment, TextStyle};
|
||||||
|
use serde::Deserialize;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
//TODO: should this be implemented again?
|
//TODO: should this be implemented again?
|
||||||
|
@ -14,6 +15,105 @@ use std::collections::HashMap;
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
#[derive(Deserialize, PartialEq, Debug)]
|
||||||
|
struct NuStyle {
|
||||||
|
fg: Option<String>,
|
||||||
|
bg: Option<String>,
|
||||||
|
attr: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_nustyle(nu_style: NuStyle) -> Style {
|
||||||
|
// get the nu_ansi_term::Color foreground color
|
||||||
|
let fg_color = match nu_style.fg {
|
||||||
|
Some(fg) => color_from_hex(&fg).expect("error with foreground color"),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
// get the nu_ansi_term::Color background color
|
||||||
|
let bg_color = match nu_style.bg {
|
||||||
|
Some(bg) => color_from_hex(&bg).expect("error with background color"),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
// get the attributes
|
||||||
|
let color_attr = match nu_style.attr {
|
||||||
|
Some(attr) => attr,
|
||||||
|
_ => "".to_string(),
|
||||||
|
};
|
||||||
|
|
||||||
|
// setup the attributes available in nu_ansi_term::Style
|
||||||
|
let mut bold = false;
|
||||||
|
let mut dimmed = false;
|
||||||
|
let mut italic = false;
|
||||||
|
let mut underline = false;
|
||||||
|
let mut blink = false;
|
||||||
|
let mut reverse = false;
|
||||||
|
let mut hidden = false;
|
||||||
|
let mut strikethrough = false;
|
||||||
|
|
||||||
|
// since we can combine styles like bold-italic, iterate through the chars
|
||||||
|
// and set the bools for later use in the nu_ansi_term::Style application
|
||||||
|
for ch in color_attr.to_lowercase().chars() {
|
||||||
|
match ch {
|
||||||
|
'l' => blink = true,
|
||||||
|
'b' => bold = true,
|
||||||
|
'd' => dimmed = true,
|
||||||
|
'h' => hidden = true,
|
||||||
|
'i' => italic = true,
|
||||||
|
'r' => reverse = true,
|
||||||
|
's' => strikethrough = true,
|
||||||
|
'u' => underline = true,
|
||||||
|
'n' => (),
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// here's where we build the nu_ansi_term::Style
|
||||||
|
Style {
|
||||||
|
foreground: fg_color,
|
||||||
|
background: bg_color,
|
||||||
|
is_blink: blink,
|
||||||
|
is_bold: bold,
|
||||||
|
is_dimmed: dimmed,
|
||||||
|
is_hidden: hidden,
|
||||||
|
is_italic: italic,
|
||||||
|
is_reverse: reverse,
|
||||||
|
is_strikethrough: strikethrough,
|
||||||
|
is_underline: underline,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn color_string_to_nustyle(color_string: String) -> Style {
|
||||||
|
// eprintln!("color_string: {}", &color_string);
|
||||||
|
if color_string.chars().count() < 1 {
|
||||||
|
Style::default()
|
||||||
|
} else {
|
||||||
|
let nu_style = match nu_json::from_str::<NuStyle>(&color_string) {
|
||||||
|
Ok(s) => s,
|
||||||
|
Err(_) => NuStyle {
|
||||||
|
fg: None,
|
||||||
|
bg: None,
|
||||||
|
attr: None,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
parse_nustyle(nu_style)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn color_from_hex(hex_color: &str) -> std::result::Result<Option<Color>, std::num::ParseIntError> {
|
||||||
|
// right now we only allow hex colors with hashtag and 6 characters
|
||||||
|
let trimmed = hex_color.trim_matches('#');
|
||||||
|
if trimmed.len() != 6 {
|
||||||
|
Ok(None)
|
||||||
|
} else {
|
||||||
|
// make a nu_ansi_term::Color::Rgb color by converting hex to decimal
|
||||||
|
Ok(Some(Color::Rgb(
|
||||||
|
u8::from_str_radix(&trimmed[..2], 16)?,
|
||||||
|
u8::from_str_radix(&trimmed[2..4], 16)?,
|
||||||
|
u8::from_str_radix(&trimmed[4..6], 16)?,
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn lookup_ansi_color_style(s: String) -> Style {
|
pub fn lookup_ansi_color_style(s: String) -> Style {
|
||||||
if s.starts_with('#') {
|
if s.starts_with('#') {
|
||||||
match color_from_hex(&s) {
|
match color_from_hex(&s) {
|
||||||
|
@ -23,6 +123,8 @@ pub fn lookup_ansi_color_style(s: String) -> Style {
|
||||||
},
|
},
|
||||||
Err(_) => Style::default(),
|
Err(_) => Style::default(),
|
||||||
}
|
}
|
||||||
|
} else if s.starts_with('{') {
|
||||||
|
color_string_to_nustyle(s)
|
||||||
} else {
|
} else {
|
||||||
match s.as_str() {
|
match s.as_str() {
|
||||||
"g" | "green" => Color::Green.normal(),
|
"g" | "green" => Color::Green.normal(),
|
||||||
|
@ -94,21 +196,6 @@ pub fn lookup_ansi_color_style(s: String) -> Style {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn color_from_hex(hex_color: &str) -> std::result::Result<Option<Color>, std::num::ParseIntError> {
|
|
||||||
// right now we only allow hex colors with hashtag and 6 characters
|
|
||||||
let trimmed = hex_color.trim_matches('#');
|
|
||||||
if trimmed.len() != 6 {
|
|
||||||
Ok(None)
|
|
||||||
} else {
|
|
||||||
// make a nu_ansi_term::Color::Rgb color by converting hex to decimal
|
|
||||||
Ok(Some(Color::Rgb(
|
|
||||||
u8::from_str_radix(&trimmed[..2], 16)?,
|
|
||||||
u8::from_str_radix(&trimmed[2..4], 16)?,
|
|
||||||
u8::from_str_radix(&trimmed[4..6], 16)?,
|
|
||||||
)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: i'm not sure how this ever worked but leaving it in case it's used elsewhere but not implemented yet
|
// TODO: i'm not sure how this ever worked but leaving it in case it's used elsewhere but not implemented yet
|
||||||
// pub fn string_to_lookup_value(str_prim: &str) -> String {
|
// pub fn string_to_lookup_value(str_prim: &str) -> String {
|
||||||
// match str_prim {
|
// match str_prim {
|
||||||
|
@ -136,6 +223,7 @@ fn color_from_hex(hex_color: &str) -> std::result::Result<Option<Color>, std::nu
|
||||||
// }
|
// }
|
||||||
|
|
||||||
fn update_hashmap(key: &str, val: &str, hm: &mut HashMap<String, Style>) {
|
fn update_hashmap(key: &str, val: &str, hm: &mut HashMap<String, Style>) {
|
||||||
|
// eprintln!("key: {}, val: {}", &key, &val);
|
||||||
let color = lookup_ansi_color_style(val.to_string());
|
let color = lookup_ansi_color_style(val.to_string());
|
||||||
if let Some(v) = hm.get_mut(key) {
|
if let Some(v) = hm.get_mut(key) {
|
||||||
*v = color;
|
*v = color;
|
||||||
|
|
|
@ -65,11 +65,41 @@ impl Value {
|
||||||
config.use_ls_colors = value.as_bool()?;
|
config.use_ls_colors = value.as_bool()?;
|
||||||
}
|
}
|
||||||
"color_config" => {
|
"color_config" => {
|
||||||
let (cols, vals) = value.as_record()?;
|
let (cols, inner_vals) = value.as_record()?;
|
||||||
let mut hm = HashMap::new();
|
let mut hm = HashMap::new();
|
||||||
for (k, v) in cols.iter().zip(vals) {
|
for (k, v) in cols.iter().zip(inner_vals) {
|
||||||
|
match &v {
|
||||||
|
Value::Record {
|
||||||
|
cols: inner_cols,
|
||||||
|
vals: inner_vals,
|
||||||
|
span: _,
|
||||||
|
} => {
|
||||||
|
// make a string from our config.color_config section that
|
||||||
|
// looks like this: { fg: "#rrggbb" bg: "#rrggbb" attr: "abc", }
|
||||||
|
// the real key here was to have quotes around the values but not
|
||||||
|
// require them around the keys.
|
||||||
|
|
||||||
|
// maybe there's a better way to generate this but i'm not sure
|
||||||
|
// what it is.
|
||||||
|
let key = k.to_string();
|
||||||
|
let mut val: String = inner_cols
|
||||||
|
.iter()
|
||||||
|
.zip(inner_vals)
|
||||||
|
.map(|(x, y)| {
|
||||||
|
let clony = y.clone();
|
||||||
|
format!("{}: \"{}\" ", x, clony.into_string(", ", &config))
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
// now insert the braces at the front and the back to fake the json string
|
||||||
|
val.insert(0, '{');
|
||||||
|
val.push('}');
|
||||||
|
hm.insert(key, val);
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
hm.insert(k.to_string(), v.as_string()?);
|
hm.insert(k.to_string(), v.as_string()?);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
config.color_config = hm;
|
config.color_config = hm;
|
||||||
}
|
}
|
||||||
"use_grid_icons" => {
|
"use_grid_icons" => {
|
||||||
|
|
Loading…
Reference in a new issue