mirror of
https://github.com/nushell/nushell.git
synced 2025-08-09 15:06:03 +02:00
Update config directly at assignment (#13332)
# Description Allows `Stack` to have a modified local `Config`, which is updated immediately when `$env.config` is assigned to. This means that even within a script, commands that come after `$env.config` changes will always see those changes in `Stack::get_config()`. Also fixed a lot of cases where `engine_state.get_config()` was used even when `Stack` was available. Closes #13324. # User-Facing Changes - Config changes apply immediately after the assignment is executed, rather than whenever config is read by a command that needs it. - Potentially slower performance when executing a lot of lines that change `$env.config` one after another. Recommended to get `$env.config` into a `mut` variable first and do modifications, then assign it back. - Much faster performance when executing a script that made modifications to `$env.config`, as the changes are only parsed once. # Tests + Formatting All passing. # After Submitting - [ ] release notes
This commit is contained in:
@ -3,8 +3,8 @@ use nu_protocol::{
|
||||
ast::{Argument, Call, Expr, Expression, RecordItem},
|
||||
debugger::WithoutDebug,
|
||||
engine::{Command, EngineState, Stack, UNKNOWN_SPAN_ID},
|
||||
record, Category, Example, IntoPipelineData, PipelineData, Signature, Span, SpanId, Spanned,
|
||||
SyntaxShape, Type, Value,
|
||||
record, Category, Config, Example, IntoPipelineData, PipelineData, Signature, Span, SpanId,
|
||||
Spanned, SyntaxShape, Type, Value,
|
||||
};
|
||||
use std::{collections::HashMap, fmt::Write};
|
||||
|
||||
@ -13,7 +13,7 @@ pub fn get_full_help(
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
) -> String {
|
||||
let config = engine_state.get_config();
|
||||
let config = stack.get_config(engine_state);
|
||||
let doc_config = DocumentationConfig {
|
||||
no_subcommands: false,
|
||||
no_color: !config.use_ansi_coloring,
|
||||
@ -70,16 +70,30 @@ fn get_documentation(
|
||||
config: &DocumentationConfig,
|
||||
is_parser_keyword: bool,
|
||||
) -> String {
|
||||
let nu_config = stack.get_config(engine_state);
|
||||
|
||||
// Create ansi colors
|
||||
//todo make these configurable -- pull from enginestate.config
|
||||
let help_section_name: String =
|
||||
get_ansi_color_for_component_or_default(engine_state, "shape_string", "\x1b[32m"); // default: green
|
||||
let help_section_name: String = get_ansi_color_for_component_or_default(
|
||||
engine_state,
|
||||
&nu_config,
|
||||
"shape_string",
|
||||
"\x1b[32m",
|
||||
); // default: green
|
||||
|
||||
let help_subcolor_one: String =
|
||||
get_ansi_color_for_component_or_default(engine_state, "shape_external", "\x1b[36m"); // default: cyan
|
||||
// was const bb: &str = "\x1b[1;34m"; // bold blue
|
||||
let help_subcolor_two: String =
|
||||
get_ansi_color_for_component_or_default(engine_state, "shape_block", "\x1b[94m"); // default: light blue (nobold, should be bolding the *names*)
|
||||
let help_subcolor_one: String = get_ansi_color_for_component_or_default(
|
||||
engine_state,
|
||||
&nu_config,
|
||||
"shape_external",
|
||||
"\x1b[36m",
|
||||
); // default: cyan
|
||||
// was const bb: &str = "\x1b[1;34m"; // bold blue
|
||||
let help_subcolor_two: String = get_ansi_color_for_component_or_default(
|
||||
engine_state,
|
||||
&nu_config,
|
||||
"shape_block",
|
||||
"\x1b[94m",
|
||||
); // default: light blue (nobold, should be bolding the *names*)
|
||||
|
||||
const RESET: &str = "\x1b[0m"; // reset
|
||||
|
||||
@ -139,13 +153,12 @@ fn get_documentation(
|
||||
}
|
||||
|
||||
if !sig.named.is_empty() {
|
||||
long_desc.push_str(&get_flags_section(Some(engine_state), sig, |v| {
|
||||
nu_highlight_string(
|
||||
&v.to_parsable_string(", ", &engine_state.config),
|
||||
engine_state,
|
||||
stack,
|
||||
)
|
||||
}))
|
||||
long_desc.push_str(&get_flags_section(
|
||||
Some(engine_state),
|
||||
Some(&nu_config),
|
||||
sig,
|
||||
|v| nu_highlight_string(&v.to_parsable_string(", ", &nu_config), engine_state, stack),
|
||||
))
|
||||
}
|
||||
|
||||
if !sig.required_positional.is_empty()
|
||||
@ -189,7 +202,7 @@ fn get_documentation(
|
||||
format!(
|
||||
" (optional, default: {})",
|
||||
nu_highlight_string(
|
||||
&value.to_parsable_string(", ", &engine_state.config),
|
||||
&value.to_parsable_string(", ", &nu_config),
|
||||
engine_state,
|
||||
stack
|
||||
)
|
||||
@ -339,7 +352,7 @@ fn get_documentation(
|
||||
let _ = writeln!(
|
||||
long_desc,
|
||||
" {}",
|
||||
item.to_expanded_string("", engine_state.get_config())
|
||||
item.to_expanded_string("", &nu_config)
|
||||
.replace('\n', "\n ")
|
||||
.trim()
|
||||
);
|
||||
@ -358,15 +371,16 @@ fn get_documentation(
|
||||
|
||||
fn get_ansi_color_for_component_or_default(
|
||||
engine_state: &EngineState,
|
||||
nu_config: &Config,
|
||||
theme_component: &str,
|
||||
default: &str,
|
||||
) -> String {
|
||||
if let Some(color) = &engine_state.get_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 span = Span::unknown();
|
||||
let span_id = UNKNOWN_SPAN_ID;
|
||||
|
||||
let argument_opt = get_argument_for_color_value(engine_state, color, span, span_id);
|
||||
let argument_opt = get_argument_for_color_value(nu_config, color, span, span_id);
|
||||
|
||||
// Call ansi command using argument
|
||||
if let Some(argument) = argument_opt {
|
||||
@ -394,8 +408,8 @@ fn get_ansi_color_for_component_or_default(
|
||||
}
|
||||
|
||||
fn get_argument_for_color_value(
|
||||
engine_state: &EngineState,
|
||||
color: &&Value,
|
||||
nu_config: &Config,
|
||||
color: &Value,
|
||||
span: Span,
|
||||
span_id: SpanId,
|
||||
) -> Option<Argument> {
|
||||
@ -412,9 +426,7 @@ fn get_argument_for_color_value(
|
||||
Type::String,
|
||||
),
|
||||
Expression::new_existing(
|
||||
Expr::String(
|
||||
v.clone().to_expanded_string("", engine_state.get_config()),
|
||||
),
|
||||
Expr::String(v.clone().to_expanded_string("", nu_config)),
|
||||
span,
|
||||
span_id,
|
||||
Type::String,
|
||||
@ -456,6 +468,7 @@ pub fn document_shape(shape: SyntaxShape) -> SyntaxShape {
|
||||
|
||||
pub fn get_flags_section<F>(
|
||||
engine_state_opt: Option<&EngineState>,
|
||||
nu_config_opt: Option<&Config>,
|
||||
signature: &Signature,
|
||||
mut value_formatter: F, // format default Value (because some calls cant access config or nu-highlight)
|
||||
) -> String
|
||||
@ -470,13 +483,26 @@ where
|
||||
// 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 {
|
||||
help_section_name =
|
||||
get_ansi_color_for_component_or_default(engine_state, "shape_string", "\x1b[32m"); // default: green
|
||||
help_subcolor_one =
|
||||
get_ansi_color_for_component_or_default(engine_state, "shape_external", "\x1b[36m"); // default: cyan
|
||||
// was const bb: &str = "\x1b[1;34m"; // bold blue
|
||||
help_subcolor_two =
|
||||
get_ansi_color_for_component_or_default(engine_state, "shape_block", "\x1b[94m");
|
||||
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
|
||||
// was const bb: &str = "\x1b[1;34m"; // bold blue
|
||||
help_subcolor_two = get_ansi_color_for_component_or_default(
|
||||
engine_state,
|
||||
nu_config,
|
||||
"shape_block",
|
||||
"\x1b[94m",
|
||||
);
|
||||
// default: light blue (nobold, should be bolding the *names*)
|
||||
} else {
|
||||
help_section_name = "\x1b[32m".to_string();
|
||||
|
@ -3,7 +3,7 @@ use nu_path::canonicalize_with;
|
||||
use nu_protocol::{
|
||||
ast::Expr,
|
||||
engine::{Call, EngineState, Stack, StateWorkingSet},
|
||||
Config, ShellError, Span, Value, VarId,
|
||||
ShellError, Span, Value, VarId,
|
||||
};
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
@ -323,18 +323,6 @@ pub fn find_in_dirs_env(
|
||||
Ok(check_dir(lib_dirs).or_else(|| check_dir(lib_dirs_fallback)))
|
||||
}
|
||||
|
||||
/// Get config
|
||||
///
|
||||
/// This combines config stored in permanent state and any runtime updates to the environment. This
|
||||
/// is the canonical way to fetch config at runtime when you have Stack available.
|
||||
pub fn get_config(engine_state: &EngineState, stack: &Stack) -> Config {
|
||||
if let Some(mut config_record) = stack.get_env_var(engine_state, "config") {
|
||||
config_record.parse_as_config(engine_state.get_config()).0
|
||||
} else {
|
||||
engine_state.get_config().clone()
|
||||
}
|
||||
}
|
||||
|
||||
fn get_converted_value(
|
||||
engine_state: &EngineState,
|
||||
stack: &Stack,
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::eval_ir_block;
|
||||
#[allow(deprecated)]
|
||||
use crate::{current_dir, get_config, get_full_help};
|
||||
use crate::{current_dir, get_full_help};
|
||||
use nu_path::{expand_path_with, AbsolutePathBuf};
|
||||
use nu_protocol::{
|
||||
ast::{
|
||||
@ -14,7 +14,7 @@ use nu_protocol::{
|
||||
Spanned, Type, Value, VarId, ENV_VARIABLE_ID,
|
||||
};
|
||||
use nu_utils::IgnoreCaseExt;
|
||||
use std::{borrow::Cow, fs::OpenOptions, path::PathBuf};
|
||||
use std::{fs::OpenOptions, path::PathBuf, sync::Arc};
|
||||
|
||||
pub fn eval_call<D: DebugContext>(
|
||||
engine_state: &EngineState,
|
||||
@ -196,6 +196,9 @@ pub fn redirect_env(engine_state: &EngineState, caller_stack: &mut Stack, callee
|
||||
for (var, value) in callee_stack.get_stack_env_vars() {
|
||||
caller_stack.add_env_var(var, value);
|
||||
}
|
||||
|
||||
// set config to callee config, to capture any updates to that
|
||||
caller_stack.config = callee_stack.config.clone();
|
||||
}
|
||||
|
||||
fn eval_external(
|
||||
@ -652,8 +655,8 @@ impl Eval for EvalRuntime {
|
||||
|
||||
type MutState = Stack;
|
||||
|
||||
fn get_config<'a>(engine_state: Self::State<'a>, stack: &mut Stack) -> Cow<'a, Config> {
|
||||
Cow::Owned(get_config(engine_state, stack))
|
||||
fn get_config(engine_state: Self::State<'_>, stack: &mut Stack) -> Arc<Config> {
|
||||
stack.get_config(engine_state)
|
||||
}
|
||||
|
||||
fn eval_filepath(
|
||||
@ -843,7 +846,14 @@ impl Eval for EvalRuntime {
|
||||
});
|
||||
}
|
||||
|
||||
let is_config = original_key == "config";
|
||||
|
||||
stack.add_env_var(original_key, value);
|
||||
|
||||
// Trigger the update to config, if we modified that.
|
||||
if is_config {
|
||||
stack.update_config(engine_state)?;
|
||||
}
|
||||
} else {
|
||||
lhs.upsert_data_at_cell_path(&cell_path.tail, rhs)?;
|
||||
stack.add_var(*var_id, lhs);
|
||||
|
Reference in New Issue
Block a user