Refactor ANSI color gathering

Now have a type for that (don't have to recompute them in
`get_flags_section`)
This commit is contained in:
sholderbach 2024-08-04 23:19:25 +02:00
parent b6f4ef1d86
commit d8d4a96eed
3 changed files with 68 additions and 73 deletions

View File

@ -1,4 +1,4 @@
use nu_engine::documentation::get_flags_section; use nu_engine::documentation::{get_flags_section, HelpStyle};
use nu_protocol::{engine::EngineState, levenshtein_distance, Config}; use nu_protocol::{engine::EngineState, levenshtein_distance, Config};
use nu_utils::IgnoreCaseExt; use nu_utils::IgnoreCaseExt;
use reedline::{Completer, Suggestion}; use reedline::{Completer, Suggestion};
@ -20,6 +20,9 @@ impl NuHelpCompleter {
fn completion_helper(&self, line: &str, pos: usize) -> Vec<Suggestion> { fn completion_helper(&self, line: &str, pos: usize) -> Vec<Suggestion> {
let folded_line = line.to_folded_case(); let folded_line = line.to_folded_case();
let mut help_style = HelpStyle::default();
help_style.update_from_config(&self.engine_state, &self.config);
let mut commands = self let mut commands = self
.engine_state .engine_state
.get_decls_sorted(false) .get_decls_sorted(false)
@ -60,12 +63,9 @@ impl NuHelpCompleter {
let _ = write!(long_desc, "Usage:\r\n > {}\r\n", sig.call_signature()); let _ = write!(long_desc, "Usage:\r\n > {}\r\n", sig.call_signature());
if !sig.named.is_empty() { if !sig.named.is_empty() {
long_desc.push_str(&get_flags_section( long_desc.push_str(&get_flags_section(&sig, &help_style, |v| {
Some(&self.engine_state), v.to_parsable_string(", ", &self.config)
Some(&self.config), }))
&sig,
|v| v.to_parsable_string(", ", &self.config),
))
} }
if !sig.required_positional.is_empty() if !sig.required_positional.is_empty()

View File

@ -68,25 +68,11 @@ fn get_documentation(
let nu_config = stack.get_config(engine_state); let nu_config = stack.get_config(engine_state);
// Create ansi colors // Create ansi colors
let help_section_name: String = get_ansi_color_for_component_or_default( let mut help_style = HelpStyle::default();
engine_state, help_style.update_from_config(engine_state, &nu_config);
&nu_config, let help_section_name = &help_style.section_name;
"shape_string", let help_subcolor_one = &help_style.subcolor_one;
"\x1b[32m", let help_subcolor_two = &help_style.subcolor_two;
); // default: green
let help_subcolor_one: String = get_ansi_color_for_component_or_default(
engine_state,
&nu_config,
"shape_external",
"\x1b[36m",
); // default: cyan
let help_subcolor_two: String = get_ansi_color_for_component_or_default(
engine_state,
&nu_config,
"shape_block",
"\x1b[94m",
); // default: light blue
let cmd_name = &sig.name; let cmd_name = &sig.name;
let mut long_desc = String::new(); let mut long_desc = String::new();
@ -146,12 +132,9 @@ fn get_documentation(
} }
if !sig.named.is_empty() { if !sig.named.is_empty() {
long_desc.push_str(&get_flags_section( long_desc.push_str(&get_flags_section(sig, &help_style, |v| {
Some(engine_state), nu_highlight_string(&v.to_parsable_string(", ", &nu_config), engine_state, stack)
Some(&nu_config), }))
sig,
|v| nu_highlight_string(&v.to_parsable_string(", ", &nu_config), engine_state, stack),
))
} }
if !sig.required_positional.is_empty() if !sig.required_positional.is_empty()
@ -370,12 +353,12 @@ fn get_documentation(
} }
} }
fn get_ansi_color_for_component_or_default( fn update_ansi_from_config(
ansi_code: &mut String,
engine_state: &EngineState, engine_state: &EngineState,
nu_config: &Config, nu_config: &Config,
theme_component: &str, theme_component: &str,
default: &str, ) {
) -> String {
if let Some(color) = &nu_config.color_config.get(theme_component) { if let Some(color) = &nu_config.color_config.get(theme_component) {
let caller_stack = &mut Stack::new().capture(); let caller_stack = &mut Stack::new().capture();
let span = Span::unknown(); let span = Span::unknown();
@ -398,14 +381,12 @@ fn get_ansi_color_for_component_or_default(
PipelineData::Empty, PipelineData::Empty,
) { ) {
if let Ok((str, ..)) = result.collect_string_strict(span) { if let Ok((str, ..)) = result.collect_string_strict(span) {
return str; *ansi_code = str;
} }
} }
} }
} }
} }
default.to_string()
} }
fn get_argument_for_color_value( fn get_argument_for_color_value(
@ -459,6 +440,48 @@ fn get_argument_for_color_value(
} }
} }
pub struct HelpStyle {
section_name: String,
subcolor_one: String,
subcolor_two: String,
}
impl Default for HelpStyle {
fn default() -> Self {
HelpStyle {
// default: green
section_name: "\x1b[32m".to_string(),
// default: cyan
subcolor_one: "\x1b[36m".to_string(),
// default: light blue
subcolor_two: "\x1b[94m".to_string(),
}
}
}
impl HelpStyle {
pub fn update_from_config(&mut self, engine_state: &EngineState, nu_config: &Config) {
update_ansi_from_config(
&mut self.section_name,
engine_state,
nu_config,
"shape_string",
);
update_ansi_from_config(
&mut self.subcolor_one,
engine_state,
nu_config,
"shape_external",
);
update_ansi_from_config(
&mut self.subcolor_two,
engine_state,
nu_config,
"shape_block",
);
}
}
/// Make syntax shape presentable by stripping custom completer info /// Make syntax shape presentable by stripping custom completer info
pub fn document_shape(shape: SyntaxShape) -> SyntaxShape { pub fn document_shape(shape: SyntaxShape) -> SyntaxShape {
match shape { match shape {
@ -468,45 +491,16 @@ pub fn document_shape(shape: SyntaxShape) -> SyntaxShape {
} }
pub fn get_flags_section<F>( pub fn get_flags_section<F>(
engine_state_opt: Option<&EngineState>,
nu_config_opt: Option<&Config>,
signature: &Signature, signature: &Signature,
help_style: &HelpStyle,
mut value_formatter: F, // format default Value (because some calls cant access config or nu-highlight) mut value_formatter: F, // format default Value (because some calls cant access config or nu-highlight)
) -> String ) -> String
where where
F: FnMut(&nu_protocol::Value) -> String, F: FnMut(&nu_protocol::Value) -> String,
{ {
let help_section_name: String; let help_section_name = &help_style.section_name;
let help_subcolor_one: String; let help_subcolor_one = &help_style.subcolor_one;
let help_subcolor_two: String; let help_subcolor_two = &help_style.subcolor_two;
// Sometimes we want to get the flags without engine_state
// For example, in nu-plugin. In that case, we fall back on default values
if let Some(engine_state) = engine_state_opt {
let nu_config = nu_config_opt.unwrap_or_else(|| engine_state.get_config());
help_section_name = get_ansi_color_for_component_or_default(
engine_state,
nu_config,
"shape_string",
"\x1b[32m",
); // default: green
help_subcolor_one = get_ansi_color_for_component_or_default(
engine_state,
nu_config,
"shape_external",
"\x1b[36m",
); // default: cyan
help_subcolor_two = get_ansi_color_for_component_or_default(
engine_state,
nu_config,
"shape_block",
"\x1b[94m",
); // default: light blue
} else {
help_section_name = "\x1b[32m".to_string();
help_subcolor_one = "\x1b[36m".to_string();
help_subcolor_two = "\x1b[94m".to_string();
}
let mut long_desc = String::new(); let mut long_desc = String::new();
let _ = write!(long_desc, "\n{help_section_name}Flags{RESET}:\n"); let _ = write!(long_desc, "\n{help_section_name}Flags{RESET}:\n");

View File

@ -9,7 +9,7 @@ use std::{
thread, thread,
}; };
use nu_engine::documentation::get_flags_section; use nu_engine::documentation::{get_flags_section, HelpStyle};
use nu_plugin_core::{ use nu_plugin_core::{
ClientCommunicationIo, CommunicationMode, InterfaceManager, PluginEncoder, PluginRead, ClientCommunicationIo, CommunicationMode, InterfaceManager, PluginEncoder, PluginRead,
PluginWrite, PluginWrite,
@ -657,6 +657,7 @@ fn print_help(plugin: &impl Plugin, encoder: impl PluginEncoder) {
println!("Encoder: {}", encoder.name()); println!("Encoder: {}", encoder.name());
let mut help = String::new(); let mut help = String::new();
let help_style = HelpStyle::default();
plugin.commands().into_iter().for_each(|command| { plugin.commands().into_iter().for_each(|command| {
let signature = command.signature(); let signature = command.signature();
@ -670,7 +671,7 @@ fn print_help(plugin: &impl Plugin, encoder: impl PluginEncoder) {
} }
}) })
.and_then(|_| { .and_then(|_| {
let flags = get_flags_section(None, None, &signature, |v| format!("{:#?}", v)); let flags = get_flags_section(&signature, &help_style, |v| format!("{:#?}", v));
write!(help, "{flags}") write!(help, "{flags}")
}) })
.and_then(|_| writeln!(help, "\nParameters:")) .and_then(|_| writeln!(help, "\nParameters:"))