mirror of
https://github.com/nushell/nushell
synced 2024-12-27 21:43:09 +00: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:
parent
deaa711ca6
commit
f65bc97a54
46 changed files with 327 additions and 222 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -3257,6 +3257,7 @@ dependencies = [
|
||||||
"nu-plugin-core",
|
"nu-plugin-core",
|
||||||
"nu-plugin-protocol",
|
"nu-plugin-protocol",
|
||||||
"nu-protocol",
|
"nu-protocol",
|
||||||
|
"nu-utils",
|
||||||
"serde",
|
"serde",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"typetag",
|
"typetag",
|
||||||
|
@ -3286,6 +3287,7 @@ dependencies = [
|
||||||
"nu-plugin-protocol",
|
"nu-plugin-protocol",
|
||||||
"nu-protocol",
|
"nu-protocol",
|
||||||
"nu-system",
|
"nu-system",
|
||||||
|
"nu-utils",
|
||||||
"serde",
|
"serde",
|
||||||
"typetag",
|
"typetag",
|
||||||
"windows 0.54.0",
|
"windows 0.54.0",
|
||||||
|
|
|
@ -53,9 +53,8 @@ pub fn evaluate_commands(
|
||||||
// Parse the source code
|
// Parse the source code
|
||||||
let (block, delta) = {
|
let (block, delta) = {
|
||||||
if let Some(ref t_mode) = table_mode {
|
if let Some(ref t_mode) = table_mode {
|
||||||
let mut config = engine_state.get_config().clone();
|
Arc::make_mut(&mut engine_state.config).table_mode =
|
||||||
config.table_mode = t_mode.coerce_str()?.parse().unwrap_or_default();
|
t_mode.coerce_str()?.parse().unwrap_or_default();
|
||||||
engine_state.set_config(config);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut working_set = StateWorkingSet::new(engine_state);
|
let mut working_set = StateWorkingSet::new(engine_state);
|
||||||
|
|
|
@ -1,25 +1,31 @@
|
||||||
use nu_engine::documentation::get_flags_section;
|
use nu_engine::documentation::get_flags_section;
|
||||||
use nu_protocol::{engine::EngineState, levenshtein_distance};
|
use nu_protocol::{engine::EngineState, levenshtein_distance, Config};
|
||||||
use nu_utils::IgnoreCaseExt;
|
use nu_utils::IgnoreCaseExt;
|
||||||
use reedline::{Completer, Suggestion};
|
use reedline::{Completer, Suggestion};
|
||||||
use std::{fmt::Write, sync::Arc};
|
use std::{fmt::Write, sync::Arc};
|
||||||
|
|
||||||
pub struct NuHelpCompleter(Arc<EngineState>);
|
pub struct NuHelpCompleter {
|
||||||
|
engine_state: Arc<EngineState>,
|
||||||
|
config: Arc<Config>,
|
||||||
|
}
|
||||||
|
|
||||||
impl NuHelpCompleter {
|
impl NuHelpCompleter {
|
||||||
pub fn new(engine_state: Arc<EngineState>) -> Self {
|
pub fn new(engine_state: Arc<EngineState>, config: Arc<Config>) -> Self {
|
||||||
Self(engine_state)
|
Self {
|
||||||
|
engine_state,
|
||||||
|
config,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 commands = self
|
let mut commands = self
|
||||||
.0
|
.engine_state
|
||||||
.get_decls_sorted(false)
|
.get_decls_sorted(false)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(|(_, decl_id)| {
|
.filter_map(|(_, decl_id)| {
|
||||||
let decl = self.0.get_decl(decl_id);
|
let decl = self.engine_state.get_decl(decl_id);
|
||||||
(decl.name().to_folded_case().contains(&folded_line)
|
(decl.name().to_folded_case().contains(&folded_line)
|
||||||
|| decl.usage().to_folded_case().contains(&folded_line)
|
|| decl.usage().to_folded_case().contains(&folded_line)
|
||||||
|| decl
|
|| decl
|
||||||
|
@ -54,9 +60,12 @@ 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(Some(&*self.0.clone()), &sig, |v| {
|
long_desc.push_str(&get_flags_section(
|
||||||
v.to_parsable_string(", ", &self.0.config)
|
Some(&self.engine_state),
|
||||||
}))
|
Some(&self.config),
|
||||||
|
&sig,
|
||||||
|
|v| v.to_parsable_string(", ", &self.config),
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
if !sig.required_positional.is_empty()
|
if !sig.required_positional.is_empty()
|
||||||
|
@ -71,7 +80,7 @@ impl NuHelpCompleter {
|
||||||
let opt_suffix = if let Some(value) = &positional.default_value {
|
let opt_suffix = if let Some(value) = &positional.default_value {
|
||||||
format!(
|
format!(
|
||||||
" (optional, default: {})",
|
" (optional, default: {})",
|
||||||
&value.to_parsable_string(", ", &self.0.config),
|
&value.to_parsable_string(", ", &self.config),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
(" (optional)").to_string()
|
(" (optional)").to_string()
|
||||||
|
@ -138,7 +147,8 @@ mod test {
|
||||||
) {
|
) {
|
||||||
let engine_state =
|
let engine_state =
|
||||||
nu_command::add_shell_command_context(nu_cmd_lang::create_default_context());
|
nu_command::add_shell_command_context(nu_cmd_lang::create_default_context());
|
||||||
let mut completer = NuHelpCompleter::new(engine_state.into());
|
let config = engine_state.get_config().clone();
|
||||||
|
let mut completer = NuHelpCompleter::new(engine_state.into(), config);
|
||||||
let suggestions = completer.complete(line, end);
|
let suggestions = completer.complete(line, end);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use nu_engine::command_prelude::*;
|
use nu_engine::command_prelude::*;
|
||||||
use reedline::{Highlighter, StyledText};
|
use reedline::{Highlighter, StyledText};
|
||||||
|
|
||||||
|
@ -33,13 +35,10 @@ impl Command for NuHighlight {
|
||||||
let head = call.head;
|
let head = call.head;
|
||||||
|
|
||||||
let signals = engine_state.signals();
|
let signals = engine_state.signals();
|
||||||
let engine_state = std::sync::Arc::new(engine_state.clone());
|
|
||||||
let config = engine_state.get_config().clone();
|
|
||||||
|
|
||||||
let highlighter = crate::NuHighlighter {
|
let highlighter = crate::NuHighlighter {
|
||||||
engine_state,
|
engine_state: Arc::new(engine_state.clone()),
|
||||||
stack: std::sync::Arc::new(stack.clone()),
|
stack: Arc::new(stack.clone()),
|
||||||
config,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
input.map(
|
input.map(
|
||||||
|
|
|
@ -77,13 +77,19 @@ pub(crate) fn add_menus(
|
||||||
mut line_editor: Reedline,
|
mut line_editor: Reedline,
|
||||||
engine_state_ref: Arc<EngineState>,
|
engine_state_ref: Arc<EngineState>,
|
||||||
stack: &Stack,
|
stack: &Stack,
|
||||||
config: &Config,
|
config: Arc<Config>,
|
||||||
) -> Result<Reedline, ShellError> {
|
) -> Result<Reedline, ShellError> {
|
||||||
//log::trace!("add_menus: config: {:#?}", &config);
|
//log::trace!("add_menus: config: {:#?}", &config);
|
||||||
line_editor = line_editor.clear_menus();
|
line_editor = line_editor.clear_menus();
|
||||||
|
|
||||||
for menu in &config.menus {
|
for menu in &config.menus {
|
||||||
line_editor = add_menu(line_editor, menu, engine_state_ref.clone(), stack, config)?
|
line_editor = add_menu(
|
||||||
|
line_editor,
|
||||||
|
menu,
|
||||||
|
engine_state_ref.clone(),
|
||||||
|
stack,
|
||||||
|
config.clone(),
|
||||||
|
)?
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checking if the default menus have been added from the config file
|
// Checking if the default menus have been added from the config file
|
||||||
|
@ -100,7 +106,7 @@ pub(crate) fn add_menus(
|
||||||
if !config
|
if !config
|
||||||
.menus
|
.menus
|
||||||
.iter()
|
.iter()
|
||||||
.any(|menu| menu.name.to_expanded_string("", config) == name)
|
.any(|menu| menu.name.to_expanded_string("", &config) == name)
|
||||||
{
|
{
|
||||||
let (block, delta) = {
|
let (block, delta) = {
|
||||||
let mut working_set = StateWorkingSet::new(&engine_state);
|
let mut working_set = StateWorkingSet::new(&engine_state);
|
||||||
|
@ -137,7 +143,7 @@ pub(crate) fn add_menus(
|
||||||
&menu,
|
&menu,
|
||||||
new_engine_state_ref.clone(),
|
new_engine_state_ref.clone(),
|
||||||
stack,
|
stack,
|
||||||
config,
|
config.clone(),
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -151,27 +157,27 @@ fn add_menu(
|
||||||
menu: &ParsedMenu,
|
menu: &ParsedMenu,
|
||||||
engine_state: Arc<EngineState>,
|
engine_state: Arc<EngineState>,
|
||||||
stack: &Stack,
|
stack: &Stack,
|
||||||
config: &Config,
|
config: Arc<Config>,
|
||||||
) -> Result<Reedline, ShellError> {
|
) -> Result<Reedline, ShellError> {
|
||||||
let span = menu.menu_type.span();
|
let span = menu.menu_type.span();
|
||||||
if let Value::Record { val, .. } = &menu.menu_type {
|
if let Value::Record { val, .. } = &menu.menu_type {
|
||||||
let layout = extract_value("layout", val, span)?.to_expanded_string("", config);
|
let layout = extract_value("layout", val, span)?.to_expanded_string("", &config);
|
||||||
|
|
||||||
match layout.as_str() {
|
match layout.as_str() {
|
||||||
"columnar" => add_columnar_menu(line_editor, menu, engine_state, stack, config),
|
"columnar" => add_columnar_menu(line_editor, menu, engine_state, stack, &config),
|
||||||
"list" => add_list_menu(line_editor, menu, engine_state, stack, config),
|
"list" => add_list_menu(line_editor, menu, engine_state, stack, config),
|
||||||
"ide" => add_ide_menu(line_editor, menu, engine_state, stack, config),
|
"ide" => add_ide_menu(line_editor, menu, engine_state, stack, config),
|
||||||
"description" => add_description_menu(line_editor, menu, engine_state, stack, config),
|
"description" => add_description_menu(line_editor, menu, engine_state, stack, config),
|
||||||
_ => Err(ShellError::UnsupportedConfigValue {
|
_ => Err(ShellError::UnsupportedConfigValue {
|
||||||
expected: "columnar, list, ide or description".to_string(),
|
expected: "columnar, list, ide or description".to_string(),
|
||||||
value: menu.menu_type.to_abbreviated_string(config),
|
value: menu.menu_type.to_abbreviated_string(&config),
|
||||||
span: menu.menu_type.span(),
|
span: menu.menu_type.span(),
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Err(ShellError::UnsupportedConfigValue {
|
Err(ShellError::UnsupportedConfigValue {
|
||||||
expected: "only record type".to_string(),
|
expected: "only record type".to_string(),
|
||||||
value: menu.menu_type.to_abbreviated_string(config),
|
value: menu.menu_type.to_abbreviated_string(&config),
|
||||||
span: menu.menu_type.span(),
|
span: menu.menu_type.span(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -282,9 +288,9 @@ pub(crate) fn add_list_menu(
|
||||||
menu: &ParsedMenu,
|
menu: &ParsedMenu,
|
||||||
engine_state: Arc<EngineState>,
|
engine_state: Arc<EngineState>,
|
||||||
stack: &Stack,
|
stack: &Stack,
|
||||||
config: &Config,
|
config: Arc<Config>,
|
||||||
) -> Result<Reedline, ShellError> {
|
) -> Result<Reedline, ShellError> {
|
||||||
let name = menu.name.to_expanded_string("", config);
|
let name = menu.name.to_expanded_string("", &config);
|
||||||
let mut list_menu = ListMenu::default().with_name(&name);
|
let mut list_menu = ListMenu::default().with_name(&name);
|
||||||
|
|
||||||
let span = menu.menu_type.span();
|
let span = menu.menu_type.span();
|
||||||
|
@ -311,7 +317,7 @@ pub(crate) fn add_list_menu(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let marker = menu.marker.to_expanded_string("", config);
|
let marker = menu.marker.to_expanded_string("", &config);
|
||||||
list_menu = list_menu.with_marker(&marker);
|
list_menu = list_menu.with_marker(&marker);
|
||||||
|
|
||||||
let only_buffer_difference = menu.only_buffer_difference.as_bool()?;
|
let only_buffer_difference = menu.only_buffer_difference.as_bool()?;
|
||||||
|
@ -337,7 +343,7 @@ pub(crate) fn add_list_menu(
|
||||||
}
|
}
|
||||||
_ => Err(ShellError::UnsupportedConfigValue {
|
_ => Err(ShellError::UnsupportedConfigValue {
|
||||||
expected: "block or omitted value".to_string(),
|
expected: "block or omitted value".to_string(),
|
||||||
value: menu.source.to_abbreviated_string(config),
|
value: menu.source.to_abbreviated_string(&config),
|
||||||
span: menu.source.span(),
|
span: menu.source.span(),
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
|
@ -349,10 +355,10 @@ pub(crate) fn add_ide_menu(
|
||||||
menu: &ParsedMenu,
|
menu: &ParsedMenu,
|
||||||
engine_state: Arc<EngineState>,
|
engine_state: Arc<EngineState>,
|
||||||
stack: &Stack,
|
stack: &Stack,
|
||||||
config: &Config,
|
config: Arc<Config>,
|
||||||
) -> Result<Reedline, ShellError> {
|
) -> Result<Reedline, ShellError> {
|
||||||
let span = menu.menu_type.span();
|
let span = menu.menu_type.span();
|
||||||
let name = menu.name.to_expanded_string("", config);
|
let name = menu.name.to_expanded_string("", &config);
|
||||||
let mut ide_menu = IdeMenu::default().with_name(&name);
|
let mut ide_menu = IdeMenu::default().with_name(&name);
|
||||||
|
|
||||||
if let Value::Record { val, .. } = &menu.menu_type {
|
if let Value::Record { val, .. } = &menu.menu_type {
|
||||||
|
@ -417,7 +423,7 @@ pub(crate) fn add_ide_menu(
|
||||||
} else {
|
} else {
|
||||||
return Err(ShellError::UnsupportedConfigValue {
|
return Err(ShellError::UnsupportedConfigValue {
|
||||||
expected: "bool or record".to_string(),
|
expected: "bool or record".to_string(),
|
||||||
value: border.to_abbreviated_string(config),
|
value: border.to_abbreviated_string(&config),
|
||||||
span: border.span(),
|
span: border.span(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -441,7 +447,7 @@ pub(crate) fn add_ide_menu(
|
||||||
_ => {
|
_ => {
|
||||||
return Err(ShellError::UnsupportedConfigValue {
|
return Err(ShellError::UnsupportedConfigValue {
|
||||||
expected: "\"left\", \"right\" or \"prefer_right\"".to_string(),
|
expected: "\"left\", \"right\" or \"prefer_right\"".to_string(),
|
||||||
value: description_mode.to_abbreviated_string(config),
|
value: description_mode.to_abbreviated_string(&config),
|
||||||
span: description_mode.span(),
|
span: description_mode.span(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -509,7 +515,7 @@ pub(crate) fn add_ide_menu(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let marker = menu.marker.to_expanded_string("", config);
|
let marker = menu.marker.to_expanded_string("", &config);
|
||||||
ide_menu = ide_menu.with_marker(&marker);
|
ide_menu = ide_menu.with_marker(&marker);
|
||||||
|
|
||||||
let only_buffer_difference = menu.only_buffer_difference.as_bool()?;
|
let only_buffer_difference = menu.only_buffer_difference.as_bool()?;
|
||||||
|
@ -535,7 +541,7 @@ pub(crate) fn add_ide_menu(
|
||||||
}
|
}
|
||||||
_ => Err(ShellError::UnsupportedConfigValue {
|
_ => Err(ShellError::UnsupportedConfigValue {
|
||||||
expected: "block or omitted value".to_string(),
|
expected: "block or omitted value".to_string(),
|
||||||
value: menu.source.to_abbreviated_string(config),
|
value: menu.source.to_abbreviated_string(&config),
|
||||||
span,
|
span,
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
|
@ -547,9 +553,9 @@ pub(crate) fn add_description_menu(
|
||||||
menu: &ParsedMenu,
|
menu: &ParsedMenu,
|
||||||
engine_state: Arc<EngineState>,
|
engine_state: Arc<EngineState>,
|
||||||
stack: &Stack,
|
stack: &Stack,
|
||||||
config: &Config,
|
config: Arc<Config>,
|
||||||
) -> Result<Reedline, ShellError> {
|
) -> Result<Reedline, ShellError> {
|
||||||
let name = menu.name.to_expanded_string("", config);
|
let name = menu.name.to_expanded_string("", &config);
|
||||||
let mut description_menu = DescriptionMenu::default().with_name(&name);
|
let mut description_menu = DescriptionMenu::default().with_name(&name);
|
||||||
|
|
||||||
let span = menu.menu_type.span();
|
let span = menu.menu_type.span();
|
||||||
|
@ -608,7 +614,7 @@ pub(crate) fn add_description_menu(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let marker = menu.marker.to_expanded_string("", config);
|
let marker = menu.marker.to_expanded_string("", &config);
|
||||||
description_menu = description_menu.with_marker(&marker);
|
description_menu = description_menu.with_marker(&marker);
|
||||||
|
|
||||||
let only_buffer_difference = menu.only_buffer_difference.as_bool()?;
|
let only_buffer_difference = menu.only_buffer_difference.as_bool()?;
|
||||||
|
@ -617,7 +623,7 @@ pub(crate) fn add_description_menu(
|
||||||
let span = menu.source.span();
|
let span = menu.source.span();
|
||||||
match &menu.source {
|
match &menu.source {
|
||||||
Value::Nothing { .. } => {
|
Value::Nothing { .. } => {
|
||||||
let completer = Box::new(NuHelpCompleter::new(engine_state));
|
let completer = Box::new(NuHelpCompleter::new(engine_state, config));
|
||||||
Ok(line_editor.with_menu(ReedlineMenu::WithCompleter {
|
Ok(line_editor.with_menu(ReedlineMenu::WithCompleter {
|
||||||
menu: Box::new(description_menu),
|
menu: Box::new(description_menu),
|
||||||
completer,
|
completer,
|
||||||
|
@ -638,7 +644,7 @@ pub(crate) fn add_description_menu(
|
||||||
}
|
}
|
||||||
_ => Err(ShellError::UnsupportedConfigValue {
|
_ => Err(ShellError::UnsupportedConfigValue {
|
||||||
expected: "closure or omitted value".to_string(),
|
expected: "closure or omitted value".to_string(),
|
||||||
value: menu.source.to_abbreviated_string(config),
|
value: menu.source.to_abbreviated_string(&config),
|
||||||
span: menu.source.span(),
|
span: menu.source.span(),
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
|
|
|
@ -297,7 +297,7 @@ fn loop_iteration(ctx: LoopContext) -> (bool, Stack, Reedline) {
|
||||||
perf!("env-change hook", start_time, use_color);
|
perf!("env-change hook", start_time, use_color);
|
||||||
|
|
||||||
let engine_reference = Arc::new(engine_state.clone());
|
let engine_reference = Arc::new(engine_state.clone());
|
||||||
let config = engine_state.get_config();
|
let config = stack.get_config(engine_state);
|
||||||
|
|
||||||
start_time = std::time::Instant::now();
|
start_time = std::time::Instant::now();
|
||||||
// Find the configured cursor shapes for each mode
|
// Find the configured cursor shapes for each mode
|
||||||
|
@ -323,7 +323,6 @@ fn loop_iteration(ctx: LoopContext) -> (bool, Stack, Reedline) {
|
||||||
engine_state: engine_reference.clone(),
|
engine_state: engine_reference.clone(),
|
||||||
// STACK-REFERENCE 1
|
// STACK-REFERENCE 1
|
||||||
stack: stack_arc.clone(),
|
stack: stack_arc.clone(),
|
||||||
config: config.clone(),
|
|
||||||
}))
|
}))
|
||||||
.with_validator(Box::new(NuValidator {
|
.with_validator(Box::new(NuValidator {
|
||||||
engine_state: engine_reference.clone(),
|
engine_state: engine_reference.clone(),
|
||||||
|
|
|
@ -6,7 +6,7 @@ use nu_parser::{flatten_block, parse, FlatShape};
|
||||||
use nu_protocol::{
|
use nu_protocol::{
|
||||||
ast::{Block, Expr, Expression, PipelineRedirection, RecordItem},
|
ast::{Block, Expr, Expression, PipelineRedirection, RecordItem},
|
||||||
engine::{EngineState, Stack, StateWorkingSet},
|
engine::{EngineState, Stack, StateWorkingSet},
|
||||||
Config, Span,
|
Span,
|
||||||
};
|
};
|
||||||
use reedline::{Highlighter, StyledText};
|
use reedline::{Highlighter, StyledText};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
@ -14,15 +14,14 @@ use std::sync::Arc;
|
||||||
pub struct NuHighlighter {
|
pub struct NuHighlighter {
|
||||||
pub engine_state: Arc<EngineState>,
|
pub engine_state: Arc<EngineState>,
|
||||||
pub stack: Arc<Stack>,
|
pub stack: Arc<Stack>,
|
||||||
pub config: Config,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Highlighter for NuHighlighter {
|
impl Highlighter for NuHighlighter {
|
||||||
fn highlight(&self, line: &str, _cursor: usize) -> StyledText {
|
fn highlight(&self, line: &str, _cursor: usize) -> StyledText {
|
||||||
trace!("highlighting: {}", line);
|
trace!("highlighting: {}", line);
|
||||||
|
|
||||||
let highlight_resolved_externals =
|
let config = self.stack.get_config(&self.engine_state);
|
||||||
self.engine_state.get_config().highlight_resolved_externals;
|
let highlight_resolved_externals = config.highlight_resolved_externals;
|
||||||
let mut working_set = StateWorkingSet::new(&self.engine_state);
|
let mut working_set = StateWorkingSet::new(&self.engine_state);
|
||||||
let block = parse(&mut working_set, None, line.as_bytes(), false);
|
let block = parse(&mut working_set, None, line.as_bytes(), false);
|
||||||
let (shapes, global_span_offset) = {
|
let (shapes, global_span_offset) = {
|
||||||
|
@ -88,7 +87,7 @@ impl Highlighter for NuHighlighter {
|
||||||
.to_string();
|
.to_string();
|
||||||
|
|
||||||
let mut add_colored_token = |shape: &FlatShape, text: String| {
|
let mut add_colored_token = |shape: &FlatShape, text: String| {
|
||||||
output.push((get_shape_color(shape.as_str(), &self.config), text));
|
output.push((get_shape_color(shape.as_str(), &config), text));
|
||||||
};
|
};
|
||||||
|
|
||||||
match shape.1 {
|
match shape.1 {
|
||||||
|
@ -128,9 +127,9 @@ impl Highlighter for NuHighlighter {
|
||||||
let start = part.start - span.start;
|
let start = part.start - span.start;
|
||||||
let end = part.end - span.start;
|
let end = part.end - span.start;
|
||||||
let text = next_token[start..end].to_string();
|
let text = next_token[start..end].to_string();
|
||||||
let mut style = get_shape_color(shape.as_str(), &self.config);
|
let mut style = get_shape_color(shape.as_str(), &config);
|
||||||
if highlight {
|
if highlight {
|
||||||
style = get_matching_brackets_style(style, &self.config);
|
style = get_matching_brackets_style(style, &config);
|
||||||
}
|
}
|
||||||
output.push((style, text));
|
output.push((style, text));
|
||||||
}
|
}
|
||||||
|
|
|
@ -239,7 +239,7 @@ fn to_html(
|
||||||
let partial = call.has_flag(engine_state, stack, "partial")?;
|
let partial = call.has_flag(engine_state, stack, "partial")?;
|
||||||
let list = call.has_flag(engine_state, stack, "list")?;
|
let list = call.has_flag(engine_state, stack, "list")?;
|
||||||
let theme: Option<Spanned<String>> = call.get_flag(engine_state, stack, "theme")?;
|
let theme: Option<Spanned<String>> = call.get_flag(engine_state, stack, "theme")?;
|
||||||
let config = engine_state.get_config();
|
let config = &stack.get_config(engine_state);
|
||||||
|
|
||||||
let vec_of_values = input.into_iter().collect::<Vec<Value>>();
|
let vec_of_values = input.into_iter().collect::<Vec<Value>>();
|
||||||
let headers = merge_descriptors(&vec_of_values);
|
let headers = merge_descriptors(&vec_of_values);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use nu_engine::command_prelude::*;
|
use nu_engine::command_prelude::*;
|
||||||
use nu_protocol::{ast::PathMember, engine::StateWorkingSet, ListStream};
|
use nu_protocol::{ast::PathMember, engine::StateWorkingSet, Config, ListStream};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct FormatPattern;
|
pub struct FormatPattern;
|
||||||
|
@ -43,6 +43,8 @@ impl Command for FormatPattern {
|
||||||
let it_id = working_set.add_variable(b"$it".to_vec(), call.head, Type::Any, false);
|
let it_id = working_set.add_variable(b"$it".to_vec(), call.head, Type::Any, false);
|
||||||
stack.add_var(it_id, input_val.clone());
|
stack.add_var(it_id, input_val.clone());
|
||||||
|
|
||||||
|
let config = stack.get_config(engine_state);
|
||||||
|
|
||||||
match specified_pattern {
|
match specified_pattern {
|
||||||
Err(e) => Err(e),
|
Err(e) => Err(e),
|
||||||
Ok(pattern) => {
|
Ok(pattern) => {
|
||||||
|
@ -56,7 +58,7 @@ impl Command for FormatPattern {
|
||||||
string_span.start + 1,
|
string_span.start + 1,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
format(input_val, &ops, engine_state, call.head)
|
format(input_val, &ops, engine_state, &config, call.head)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -181,33 +183,30 @@ fn format(
|
||||||
input_data: Value,
|
input_data: Value,
|
||||||
format_operations: &[FormatOperation],
|
format_operations: &[FormatOperation],
|
||||||
engine_state: &EngineState,
|
engine_state: &EngineState,
|
||||||
|
config: &Config,
|
||||||
head_span: Span,
|
head_span: Span,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
let data_as_value = input_data;
|
let data_as_value = input_data;
|
||||||
|
|
||||||
// We can only handle a Record or a List of Records
|
// We can only handle a Record or a List of Records
|
||||||
match data_as_value {
|
match data_as_value {
|
||||||
Value::Record { .. } => {
|
Value::Record { .. } => match format_record(format_operations, &data_as_value, config) {
|
||||||
match format_record(format_operations, &data_as_value, engine_state) {
|
|
||||||
Ok(value) => Ok(PipelineData::Value(Value::string(value, head_span), None)),
|
Ok(value) => Ok(PipelineData::Value(Value::string(value, head_span), None)),
|
||||||
Err(value) => Err(value),
|
Err(value) => Err(value),
|
||||||
}
|
},
|
||||||
}
|
|
||||||
|
|
||||||
Value::List { vals, .. } => {
|
Value::List { vals, .. } => {
|
||||||
let mut list = vec![];
|
let mut list = vec![];
|
||||||
for val in vals.iter() {
|
for val in vals.iter() {
|
||||||
match val {
|
match val {
|
||||||
Value::Record { .. } => {
|
Value::Record { .. } => match format_record(format_operations, val, config) {
|
||||||
match format_record(format_operations, val, engine_state) {
|
|
||||||
Ok(value) => {
|
Ok(value) => {
|
||||||
list.push(Value::string(value, head_span));
|
list.push(Value::string(value, head_span));
|
||||||
}
|
}
|
||||||
Err(value) => {
|
Err(value) => {
|
||||||
return Err(value);
|
return Err(value);
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
|
||||||
Value::Error { error, .. } => return Err(*error.clone()),
|
Value::Error { error, .. } => return Err(*error.clone()),
|
||||||
_ => {
|
_ => {
|
||||||
return Err(ShellError::OnlySupportsThisInputType {
|
return Err(ShellError::OnlySupportsThisInputType {
|
||||||
|
@ -237,9 +236,8 @@ fn format(
|
||||||
fn format_record(
|
fn format_record(
|
||||||
format_operations: &[FormatOperation],
|
format_operations: &[FormatOperation],
|
||||||
data_as_value: &Value,
|
data_as_value: &Value,
|
||||||
engine_state: &EngineState,
|
config: &Config,
|
||||||
) -> Result<String, ShellError> {
|
) -> Result<String, ShellError> {
|
||||||
let config = engine_state.get_config();
|
|
||||||
let mut output = String::new();
|
let mut output = String::new();
|
||||||
|
|
||||||
for op in format_operations {
|
for op in format_operations {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::{color_record_to_nustyle, lookup_ansi_color_style, text_style::Alignment, TextStyle};
|
use crate::{color_record_to_nustyle, lookup_ansi_color_style, text_style::Alignment, TextStyle};
|
||||||
use nu_ansi_term::{Color, Style};
|
use nu_ansi_term::{Color, Style};
|
||||||
use nu_engine::{env::get_config, ClosureEvalOnce};
|
use nu_engine::ClosureEvalOnce;
|
||||||
use nu_protocol::{
|
use nu_protocol::{
|
||||||
cli_error::CliError,
|
cli_error::CliError,
|
||||||
engine::{Closure, EngineState, Stack, StateWorkingSet},
|
engine::{Closure, EngineState, Stack, StateWorkingSet},
|
||||||
|
@ -114,7 +114,7 @@ impl<'a> StyleComputer<'a> {
|
||||||
|
|
||||||
// The main constructor.
|
// The main constructor.
|
||||||
pub fn from_config(engine_state: &'a EngineState, stack: &'a Stack) -> StyleComputer<'a> {
|
pub fn from_config(engine_state: &'a EngineState, stack: &'a Stack) -> StyleComputer<'a> {
|
||||||
let config = get_config(engine_state, stack);
|
let config = stack.get_config(engine_state);
|
||||||
|
|
||||||
// Create the hashmap
|
// Create the hashmap
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use nu_cmd_base::input_handler::{operate, CmdArgument};
|
use nu_cmd_base::input_handler::{operate, CmdArgument};
|
||||||
use nu_engine::command_prelude::*;
|
use nu_engine::command_prelude::*;
|
||||||
use nu_protocol::{into_code, Config};
|
use nu_protocol::{into_code, Config};
|
||||||
|
@ -7,7 +9,7 @@ use num_format::ToFormattedString;
|
||||||
struct Arguments {
|
struct Arguments {
|
||||||
decimals_value: Option<i64>,
|
decimals_value: Option<i64>,
|
||||||
cell_paths: Option<Vec<CellPath>>,
|
cell_paths: Option<Vec<CellPath>>,
|
||||||
config: Config,
|
config: Arc<Config>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CmdArgument for Arguments {
|
impl CmdArgument for Arguments {
|
||||||
|
@ -174,7 +176,7 @@ fn string_helper(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let config = engine_state.get_config().clone();
|
let config = stack.get_config(engine_state);
|
||||||
let args = Arguments {
|
let args = Arguments {
|
||||||
decimals_value,
|
decimals_value,
|
||||||
cell_paths,
|
cell_paths,
|
||||||
|
|
|
@ -33,7 +33,7 @@ impl Command for Debug {
|
||||||
input: PipelineData,
|
input: PipelineData,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
let head = call.head;
|
let head = call.head;
|
||||||
let config = engine_state.get_config().clone();
|
let config = stack.get_config(engine_state);
|
||||||
let raw = call.has_flag(engine_state, stack, "raw")?;
|
let raw = call.has_flag(engine_state, stack, "raw")?;
|
||||||
|
|
||||||
// Should PipelineData::Empty result in an error here?
|
// Should PipelineData::Empty result in an error here?
|
||||||
|
|
|
@ -170,7 +170,7 @@ fn rm(
|
||||||
}
|
}
|
||||||
|
|
||||||
let span = call.head;
|
let span = call.head;
|
||||||
let rm_always_trash = engine_state.get_config().rm_always_trash;
|
let rm_always_trash = stack.get_config(engine_state).rm_always_trash;
|
||||||
|
|
||||||
if !TRASH_SUPPORTED {
|
if !TRASH_SUPPORTED {
|
||||||
if rm_always_trash {
|
if rm_always_trash {
|
||||||
|
|
|
@ -213,7 +213,7 @@ fn find_with_regex(
|
||||||
input: PipelineData,
|
input: PipelineData,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
let span = call.head;
|
let span = call.head;
|
||||||
let config = engine_state.get_config().clone();
|
let config = stack.get_config(engine_state);
|
||||||
|
|
||||||
let insensitive = call.has_flag(engine_state, stack, "ignore-case")?;
|
let insensitive = call.has_flag(engine_state, stack, "ignore-case")?;
|
||||||
let multiline = call.has_flag(engine_state, stack, "multiline")?;
|
let multiline = call.has_flag(engine_state, stack, "multiline")?;
|
||||||
|
@ -348,8 +348,8 @@ fn find_with_rest_and_highlight(
|
||||||
input: PipelineData,
|
input: PipelineData,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
let span = call.head;
|
let span = call.head;
|
||||||
let config = engine_state.get_config().clone();
|
let config = stack.get_config(engine_state);
|
||||||
let filter_config = engine_state.get_config().clone();
|
let filter_config = config.clone();
|
||||||
let invert = call.has_flag(engine_state, stack, "invert")?;
|
let invert = call.has_flag(engine_state, stack, "invert")?;
|
||||||
let terms = call.rest::<Value>(engine_state, stack, 0)?;
|
let terms = call.rest::<Value>(engine_state, stack, 0)?;
|
||||||
let lower_terms = terms
|
let lower_terms = terms
|
||||||
|
|
|
@ -70,8 +70,8 @@ impl Command for ToMd {
|
||||||
let head = call.head;
|
let head = call.head;
|
||||||
let pretty = call.has_flag(engine_state, stack, "pretty")?;
|
let pretty = call.has_flag(engine_state, stack, "pretty")?;
|
||||||
let per_element = call.has_flag(engine_state, stack, "per-element")?;
|
let per_element = call.has_flag(engine_state, stack, "per-element")?;
|
||||||
let config = engine_state.get_config();
|
let config = stack.get_config(engine_state);
|
||||||
to_md(input, pretty, per_element, config, head)
|
to_md(input, pretty, per_element, &config, head)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,18 +31,19 @@ impl Command for ToText {
|
||||||
fn run(
|
fn run(
|
||||||
&self,
|
&self,
|
||||||
engine_state: &EngineState,
|
engine_state: &EngineState,
|
||||||
_stack: &mut Stack,
|
stack: &mut Stack,
|
||||||
call: &Call,
|
call: &Call,
|
||||||
input: PipelineData,
|
input: PipelineData,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
let span = call.head;
|
let span = call.head;
|
||||||
let input = input.try_expand_range()?;
|
let input = input.try_expand_range()?;
|
||||||
|
let config = stack.get_config(engine_state);
|
||||||
|
|
||||||
match input {
|
match input {
|
||||||
PipelineData::Empty => Ok(Value::string(String::new(), span)
|
PipelineData::Empty => Ok(Value::string(String::new(), span)
|
||||||
.into_pipeline_data_with_metadata(update_metadata(None))),
|
.into_pipeline_data_with_metadata(update_metadata(None))),
|
||||||
PipelineData::Value(value, ..) => {
|
PipelineData::Value(value, ..) => {
|
||||||
let str = local_into_string(value, LINE_ENDING, engine_state.get_config());
|
let str = local_into_string(value, LINE_ENDING, &config);
|
||||||
Ok(
|
Ok(
|
||||||
Value::string(str, span)
|
Value::string(str, span)
|
||||||
.into_pipeline_data_with_metadata(update_metadata(None)),
|
.into_pipeline_data_with_metadata(update_metadata(None)),
|
||||||
|
@ -50,7 +51,6 @@ impl Command for ToText {
|
||||||
}
|
}
|
||||||
PipelineData::ListStream(stream, meta) => {
|
PipelineData::ListStream(stream, meta) => {
|
||||||
let span = stream.span();
|
let span = stream.span();
|
||||||
let config = engine_state.get_config().clone();
|
|
||||||
let iter = stream.into_inner().map(move |value| {
|
let iter = stream.into_inner().map(move |value| {
|
||||||
let mut str = local_into_string(value, LINE_ENDING, &config);
|
let mut str = local_into_string(value, LINE_ENDING, &config);
|
||||||
str.push_str(LINE_ENDING);
|
str.push_str(LINE_ENDING);
|
||||||
|
|
|
@ -143,7 +143,7 @@ pub fn help_aliases(
|
||||||
long_desc.push_str("\n\n");
|
long_desc.push_str("\n\n");
|
||||||
long_desc.push_str(&format!("{G}Expansion{RESET}:\n {alias_expansion}"));
|
long_desc.push_str(&format!("{G}Expansion{RESET}:\n {alias_expansion}"));
|
||||||
|
|
||||||
let config = engine_state.get_config();
|
let config = stack.get_config(engine_state);
|
||||||
if !config.use_ansi_coloring {
|
if !config.use_ansi_coloring {
|
||||||
long_desc = nu_utils::strip_ansi_string_likely(long_desc);
|
long_desc = nu_utils::strip_ansi_string_likely(long_desc);
|
||||||
}
|
}
|
||||||
|
|
|
@ -230,7 +230,7 @@ pub fn help_modules(
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
let config = engine_state.get_config();
|
let config = stack.get_config(engine_state);
|
||||||
if !config.use_ansi_coloring {
|
if !config.use_ansi_coloring {
|
||||||
long_desc = nu_utils::strip_ansi_string_likely(long_desc);
|
long_desc = nu_utils::strip_ansi_string_likely(long_desc);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use nu_engine::command_prelude::*;
|
use nu_engine::command_prelude::*;
|
||||||
|
use nu_protocol::Config;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
@ -38,11 +39,15 @@ impl Command for SubCommand {
|
||||||
fn run(
|
fn run(
|
||||||
&self,
|
&self,
|
||||||
engine_state: &EngineState,
|
engine_state: &EngineState,
|
||||||
_: &mut Stack,
|
stack: &mut Stack,
|
||||||
call: &Call,
|
call: &Call,
|
||||||
input: PipelineData,
|
input: PipelineData,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
parse(input.into_value(call.head)?, call.head, engine_state)
|
parse(
|
||||||
|
input.into_value(call.head)?,
|
||||||
|
call.head,
|
||||||
|
&stack.get_config(engine_state),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
|
@ -68,12 +73,12 @@ impl Command for SubCommand {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_url_string(value: &Value, engine_state: &EngineState) -> String {
|
fn get_url_string(value: &Value, config: &Config) -> String {
|
||||||
value.to_expanded_string("", engine_state.get_config())
|
value.to_expanded_string("", config)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse(value: Value, head: Span, engine_state: &EngineState) -> Result<PipelineData, ShellError> {
|
fn parse(value: Value, head: Span, config: &Config) -> Result<PipelineData, ShellError> {
|
||||||
let url_string = get_url_string(&value, engine_state);
|
let url_string = get_url_string(&value, config);
|
||||||
|
|
||||||
let result_url = Url::parse(url_string.as_str());
|
let result_url = Url::parse(url_string.as_str());
|
||||||
|
|
||||||
|
|
|
@ -653,7 +653,7 @@ Operating system commands:
|
||||||
let list: bool = call.has_flag(engine_state, stack, "list")?;
|
let list: bool = call.has_flag(engine_state, stack, "list")?;
|
||||||
let escape: bool = call.has_flag(engine_state, stack, "escape")?;
|
let escape: bool = call.has_flag(engine_state, stack, "escape")?;
|
||||||
let osc: bool = call.has_flag(engine_state, stack, "osc")?;
|
let osc: bool = call.has_flag(engine_state, stack, "osc")?;
|
||||||
let use_ansi_coloring = engine_state.get_config().use_ansi_coloring;
|
let use_ansi_coloring = stack.get_config(engine_state).use_ansi_coloring;
|
||||||
|
|
||||||
if list {
|
if list {
|
||||||
return Ok(generate_ansi_code_list(
|
return Ok(generate_ansi_code_list(
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use nu_cmd_base::input_handler::{operate, CmdArgument};
|
use nu_cmd_base::input_handler::{operate, CmdArgument};
|
||||||
use nu_engine::command_prelude::*;
|
use nu_engine::command_prelude::*;
|
||||||
use nu_protocol::Config;
|
use nu_protocol::Config;
|
||||||
|
|
||||||
pub struct Arguments {
|
pub struct Arguments {
|
||||||
cell_paths: Option<Vec<CellPath>>,
|
cell_paths: Option<Vec<CellPath>>,
|
||||||
config: Config,
|
config: Arc<Config>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CmdArgument for Arguments {
|
impl CmdArgument for Arguments {
|
||||||
|
@ -51,11 +53,8 @@ impl Command for SubCommand {
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
let cell_paths: Vec<CellPath> = call.rest(engine_state, stack, 1)?;
|
let cell_paths: Vec<CellPath> = call.rest(engine_state, stack, 1)?;
|
||||||
let cell_paths = (!cell_paths.is_empty()).then_some(cell_paths);
|
let cell_paths = (!cell_paths.is_empty()).then_some(cell_paths);
|
||||||
let config = engine_state.get_config();
|
let config = stack.get_config(engine_state);
|
||||||
let args = Arguments {
|
let args = Arguments { cell_paths, config };
|
||||||
cell_paths,
|
|
||||||
config: config.clone(),
|
|
||||||
};
|
|
||||||
operate(action, args, input, call.head, engine_state.signals())
|
operate(action, args, input, call.head, engine_state.signals())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -79,6 +79,7 @@ impl Command for InputList {
|
||||||
let fuzzy = call.has_flag(engine_state, stack, "fuzzy")?;
|
let fuzzy = call.has_flag(engine_state, stack, "fuzzy")?;
|
||||||
let index = call.has_flag(engine_state, stack, "index")?;
|
let index = call.has_flag(engine_state, stack, "index")?;
|
||||||
let display_path: Option<CellPath> = call.get_flag(engine_state, stack, "display")?;
|
let display_path: Option<CellPath> = call.get_flag(engine_state, stack, "display")?;
|
||||||
|
let config = stack.get_config(engine_state);
|
||||||
|
|
||||||
let options: Vec<Options> = match input {
|
let options: Vec<Options> = match input {
|
||||||
PipelineData::Value(Value::Range { .. }, ..)
|
PipelineData::Value(Value::Range { .. }, ..)
|
||||||
|
@ -89,9 +90,9 @@ impl Command for InputList {
|
||||||
let display_value = if let Some(ref cellpath) = display_path {
|
let display_value = if let Some(ref cellpath) = display_path {
|
||||||
val.clone()
|
val.clone()
|
||||||
.follow_cell_path(&cellpath.members, false)?
|
.follow_cell_path(&cellpath.members, false)?
|
||||||
.to_expanded_string(", ", engine_state.get_config())
|
.to_expanded_string(", ", &config)
|
||||||
} else {
|
} else {
|
||||||
val.to_expanded_string(", ", engine_state.get_config())
|
val.to_expanded_string(", ", &config)
|
||||||
};
|
};
|
||||||
Ok(Options {
|
Ok(Options {
|
||||||
name: display_value,
|
name: display_value,
|
||||||
|
|
|
@ -65,7 +65,7 @@ impl Command for StorInsert {
|
||||||
let span = call.head;
|
let span = call.head;
|
||||||
let table_name: Option<String> = call.get_flag(engine_state, stack, "table-name")?;
|
let table_name: Option<String> = call.get_flag(engine_state, stack, "table-name")?;
|
||||||
let data_record: Option<Record> = call.get_flag(engine_state, stack, "data-record")?;
|
let data_record: Option<Record> = call.get_flag(engine_state, stack, "data-record")?;
|
||||||
// let config = engine_state.get_config();
|
// let config = stack.get_config(engine_state);
|
||||||
let db = Box::new(SQLiteDatabase::new(
|
let db = Box::new(SQLiteDatabase::new(
|
||||||
std::path::Path::new(MEMORY_DB),
|
std::path::Path::new(MEMORY_DB),
|
||||||
Signals::empty(),
|
Signals::empty(),
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use nu_engine::command_prelude::*;
|
use nu_engine::command_prelude::*;
|
||||||
use nu_protocol::Range;
|
use nu_protocol::{Config, Range};
|
||||||
use std::{io::Cursor, iter::Peekable, str::CharIndices};
|
use std::{io::Cursor, iter::Peekable, str::CharIndices, sync::Arc};
|
||||||
|
|
||||||
type Input<'t> = Peekable<CharIndices<'t>>;
|
type Input<'t> = Peekable<CharIndices<'t>>;
|
||||||
|
|
||||||
|
@ -110,11 +110,13 @@ none 8150224 4 8150220 1% /mnt/c' | detect columns --gue
|
||||||
let num_rows_to_skip: Option<usize> = call.get_flag(engine_state, stack, "skip")?;
|
let num_rows_to_skip: Option<usize> = call.get_flag(engine_state, stack, "skip")?;
|
||||||
let noheader = call.has_flag(engine_state, stack, "no-headers")?;
|
let noheader = call.has_flag(engine_state, stack, "no-headers")?;
|
||||||
let range: Option<Range> = call.get_flag(engine_state, stack, "combine-columns")?;
|
let range: Option<Range> = call.get_flag(engine_state, stack, "combine-columns")?;
|
||||||
|
let config = stack.get_config(engine_state);
|
||||||
|
|
||||||
let args = Arguments {
|
let args = Arguments {
|
||||||
noheader,
|
noheader,
|
||||||
num_rows_to_skip,
|
num_rows_to_skip,
|
||||||
range,
|
range,
|
||||||
|
config,
|
||||||
};
|
};
|
||||||
|
|
||||||
if call.has_flag(engine_state, stack, "guess")? {
|
if call.has_flag(engine_state, stack, "guess")? {
|
||||||
|
@ -133,11 +135,13 @@ none 8150224 4 8150220 1% /mnt/c' | detect columns --gue
|
||||||
let num_rows_to_skip: Option<usize> = call.get_flag_const(working_set, "skip")?;
|
let num_rows_to_skip: Option<usize> = call.get_flag_const(working_set, "skip")?;
|
||||||
let noheader = call.has_flag_const(working_set, "no-headers")?;
|
let noheader = call.has_flag_const(working_set, "no-headers")?;
|
||||||
let range: Option<Range> = call.get_flag_const(working_set, "combine-columns")?;
|
let range: Option<Range> = call.get_flag_const(working_set, "combine-columns")?;
|
||||||
|
let config = working_set.get_config().clone();
|
||||||
|
|
||||||
let args = Arguments {
|
let args = Arguments {
|
||||||
noheader,
|
noheader,
|
||||||
num_rows_to_skip,
|
num_rows_to_skip,
|
||||||
range,
|
range,
|
||||||
|
config,
|
||||||
};
|
};
|
||||||
|
|
||||||
if call.has_flag_const(working_set, "guess")? {
|
if call.has_flag_const(working_set, "guess")? {
|
||||||
|
@ -152,6 +156,7 @@ struct Arguments {
|
||||||
num_rows_to_skip: Option<usize>,
|
num_rows_to_skip: Option<usize>,
|
||||||
noheader: bool,
|
noheader: bool,
|
||||||
range: Option<Range>,
|
range: Option<Range>,
|
||||||
|
config: Arc<Config>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn guess_width(
|
fn guess_width(
|
||||||
|
@ -163,7 +168,7 @@ fn guess_width(
|
||||||
use super::guess_width::GuessWidth;
|
use super::guess_width::GuessWidth;
|
||||||
let input_span = input.span().unwrap_or(call.head);
|
let input_span = input.span().unwrap_or(call.head);
|
||||||
|
|
||||||
let mut input = input.collect_string("", engine_state.get_config())?;
|
let mut input = input.collect_string("", &args.config)?;
|
||||||
if let Some(rows) = args.num_rows_to_skip {
|
if let Some(rows) = args.num_rows_to_skip {
|
||||||
input = input.lines().skip(rows).map(|x| x.to_string()).join("\n");
|
input = input.lines().skip(rows).map(|x| x.to_string()).join("\n");
|
||||||
}
|
}
|
||||||
|
@ -235,8 +240,7 @@ fn detect_columns(
|
||||||
args: Arguments,
|
args: Arguments,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
let name_span = call.head;
|
let name_span = call.head;
|
||||||
let config = engine_state.get_config();
|
let input = input.collect_string("", &args.config)?;
|
||||||
let input = input.collect_string("", config)?;
|
|
||||||
|
|
||||||
let input: Vec<_> = input
|
let input: Vec<_> = input
|
||||||
.lines()
|
.lines()
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use nu_engine::{command_prelude::*, env::get_config, find_in_dirs_env, get_dirs_var_from_call};
|
use nu_engine::{command_prelude::*, find_in_dirs_env, get_dirs_var_from_call};
|
||||||
use nu_parser::{parse, parse_module_block, parse_module_file_or_dir, unescape_unquote_string};
|
use nu_parser::{parse, parse_module_block, parse_module_file_or_dir, unescape_unquote_string};
|
||||||
use nu_protocol::engine::{FileStack, StateWorkingSet};
|
use nu_protocol::engine::{FileStack, StateWorkingSet};
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
@ -59,7 +59,7 @@ impl Command for NuCheck {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PipelineData::ListStream(stream, ..) => {
|
PipelineData::ListStream(stream, ..) => {
|
||||||
let config = get_config(engine_state, stack);
|
let config = stack.get_config(engine_state);
|
||||||
let list_stream = stream.into_string("\n", &config);
|
let list_stream = stream.into_string("\n", &config);
|
||||||
let contents = Vec::from(list_stream);
|
let contents = Vec::from(list_stream);
|
||||||
|
|
||||||
|
|
|
@ -366,7 +366,7 @@ pub fn command_not_found(
|
||||||
stack: &mut Stack,
|
stack: &mut Stack,
|
||||||
) -> ShellError {
|
) -> ShellError {
|
||||||
// Run the `command_not_found` hook if there is one.
|
// Run the `command_not_found` hook if there is one.
|
||||||
if let Some(hook) = &engine_state.config.hooks.command_not_found {
|
if let Some(hook) = &stack.get_config(engine_state).hooks.command_not_found {
|
||||||
let mut stack = stack.start_capture();
|
let mut stack = stack.start_capture();
|
||||||
// Set a special environment variable to avoid infinite loops when the
|
// Set a special environment variable to avoid infinite loops when the
|
||||||
// `command_not_found` hook triggers itself.
|
// `command_not_found` hook triggers itself.
|
||||||
|
|
|
@ -61,7 +61,7 @@ prints out the list properly."#
|
||||||
let width_param: Option<i64> = call.get_flag(engine_state, stack, "width")?;
|
let width_param: Option<i64> = call.get_flag(engine_state, stack, "width")?;
|
||||||
let color_param: bool = call.has_flag(engine_state, stack, "color")?;
|
let color_param: bool = call.has_flag(engine_state, stack, "color")?;
|
||||||
let separator_param: Option<String> = call.get_flag(engine_state, stack, "separator")?;
|
let separator_param: Option<String> = call.get_flag(engine_state, stack, "separator")?;
|
||||||
let config = engine_state.get_config();
|
let config = &stack.get_config(engine_state);
|
||||||
let env_str = match stack.get_env_var(engine_state, "LS_COLORS") {
|
let env_str = match stack.get_env_var(engine_state, "LS_COLORS") {
|
||||||
Some(v) => Some(env_to_string("LS_COLORS", &v, engine_state, stack)?),
|
Some(v) => Some(env_to_string("LS_COLORS", &v, engine_state, stack)?),
|
||||||
None => None,
|
None => None,
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
use lscolors::{LsColors, Style};
|
use lscolors::{LsColors, Style};
|
||||||
use nu_color_config::{color_from_hex, StyleComputer, TextStyle};
|
use nu_color_config::{color_from_hex, StyleComputer, TextStyle};
|
||||||
use nu_engine::{command_prelude::*, env::get_config, env_to_string};
|
use nu_engine::{command_prelude::*, env_to_string};
|
||||||
use nu_pretty_hex::HexConfig;
|
use nu_pretty_hex::HexConfig;
|
||||||
use nu_protocol::{
|
use nu_protocol::{
|
||||||
ByteStream, Config, DataSource, ListStream, PipelineMetadata, Signals, TableMode, ValueIterator,
|
ByteStream, Config, DataSource, ListStream, PipelineMetadata, Signals, TableMode, ValueIterator,
|
||||||
|
@ -258,7 +258,7 @@ fn parse_table_config(
|
||||||
let flatten_separator: Option<String> = call.get_flag(state, stack, "flatten-separator")?;
|
let flatten_separator: Option<String> = call.get_flag(state, stack, "flatten-separator")?;
|
||||||
let abbrivation: Option<usize> = call
|
let abbrivation: Option<usize> = call
|
||||||
.get_flag(state, stack, "abbreviated")?
|
.get_flag(state, stack, "abbreviated")?
|
||||||
.or_else(|| get_config(state, stack).table_abbreviation_threshold);
|
.or_else(|| stack.get_config(state).table_abbreviation_threshold);
|
||||||
let table_view = match (expand, collapse) {
|
let table_view = match (expand, collapse) {
|
||||||
(false, false) => TableView::General,
|
(false, false) => TableView::General,
|
||||||
(_, true) => TableView::Collapsed,
|
(_, true) => TableView::Collapsed,
|
||||||
|
@ -269,7 +269,7 @@ fn parse_table_config(
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
let theme =
|
let theme =
|
||||||
get_theme_flag(call, state, stack)?.unwrap_or_else(|| get_config(state, stack).table_mode);
|
get_theme_flag(call, state, stack)?.unwrap_or_else(|| stack.get_config(state).table_mode);
|
||||||
let index = get_index_flag(call, state, stack)?;
|
let index = get_index_flag(call, state, stack)?;
|
||||||
|
|
||||||
let term_width = get_width_param(width_param);
|
let term_width = get_width_param(width_param);
|
||||||
|
@ -493,7 +493,11 @@ fn handle_record(
|
||||||
cfg: TableConfig,
|
cfg: TableConfig,
|
||||||
mut record: Record,
|
mut record: Record,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
let config = get_config(input.engine_state, input.stack);
|
let config = {
|
||||||
|
let state = input.engine_state;
|
||||||
|
let stack: &Stack = input.stack;
|
||||||
|
stack.get_config(state)
|
||||||
|
};
|
||||||
let span = input.data.span().unwrap_or(input.call.head);
|
let span = input.data.span().unwrap_or(input.call.head);
|
||||||
let styles = &StyleComputer::from_config(input.engine_state, input.stack);
|
let styles = &StyleComputer::from_config(input.engine_state, input.stack);
|
||||||
|
|
||||||
|
@ -608,7 +612,11 @@ fn handle_row_stream(
|
||||||
data_source: DataSource::Ls,
|
data_source: DataSource::Ls,
|
||||||
..
|
..
|
||||||
}) => {
|
}) => {
|
||||||
let config = get_config(input.engine_state, input.stack);
|
let config = {
|
||||||
|
let state = input.engine_state;
|
||||||
|
let stack: &Stack = input.stack;
|
||||||
|
stack.get_config(state)
|
||||||
|
};
|
||||||
let ls_colors_env_str = match input.stack.get_env_var(input.engine_state, "LS_COLORS") {
|
let ls_colors_env_str = match input.stack.get_env_var(input.engine_state, "LS_COLORS") {
|
||||||
Some(v) => Some(env_to_string(
|
Some(v) => Some(env_to_string(
|
||||||
"LS_COLORS",
|
"LS_COLORS",
|
||||||
|
@ -758,7 +766,11 @@ impl PagingTableCreator {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
|
|
||||||
let cfg = get_config(&self.engine_state, &self.stack);
|
let cfg = {
|
||||||
|
let state = &self.engine_state;
|
||||||
|
let stack = &self.stack;
|
||||||
|
stack.get_config(state)
|
||||||
|
};
|
||||||
let style_comp = StyleComputer::from_config(&self.engine_state, &self.stack);
|
let style_comp = StyleComputer::from_config(&self.engine_state, &self.stack);
|
||||||
let opts = self.create_table_opts(&cfg, &style_comp);
|
let opts = self.create_table_opts(&cfg, &style_comp);
|
||||||
let view = TableView::Expanded {
|
let view = TableView::Expanded {
|
||||||
|
@ -775,7 +787,11 @@ impl PagingTableCreator {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
|
|
||||||
let cfg = get_config(&self.engine_state, &self.stack);
|
let cfg = {
|
||||||
|
let state = &self.engine_state;
|
||||||
|
let stack = &self.stack;
|
||||||
|
stack.get_config(state)
|
||||||
|
};
|
||||||
let style_comp = StyleComputer::from_config(&self.engine_state, &self.stack);
|
let style_comp = StyleComputer::from_config(&self.engine_state, &self.stack);
|
||||||
let opts = self.create_table_opts(&cfg, &style_comp);
|
let opts = self.create_table_opts(&cfg, &style_comp);
|
||||||
|
|
||||||
|
@ -783,7 +799,11 @@ impl PagingTableCreator {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_general(&mut self, batch: Vec<Value>) -> StringResult {
|
fn build_general(&mut self, batch: Vec<Value>) -> StringResult {
|
||||||
let cfg = get_config(&self.engine_state, &self.stack);
|
let cfg = {
|
||||||
|
let state = &self.engine_state;
|
||||||
|
let stack = &self.stack;
|
||||||
|
stack.get_config(state)
|
||||||
|
};
|
||||||
let style_comp = StyleComputer::from_config(&self.engine_state, &self.stack);
|
let style_comp = StyleComputer::from_config(&self.engine_state, &self.stack);
|
||||||
let opts = self.create_table_opts(&cfg, &style_comp);
|
let opts = self.create_table_opts(&cfg, &style_comp);
|
||||||
|
|
||||||
|
@ -872,7 +892,11 @@ impl Iterator for PagingTableCreator {
|
||||||
|
|
||||||
self.row_offset += batch_size;
|
self.row_offset += batch_size;
|
||||||
|
|
||||||
let config = get_config(&self.engine_state, &self.stack);
|
let config = {
|
||||||
|
let state = &self.engine_state;
|
||||||
|
let stack = &self.stack;
|
||||||
|
stack.get_config(state)
|
||||||
|
};
|
||||||
convert_table_to_output(
|
convert_table_to_output(
|
||||||
table,
|
table,
|
||||||
&config,
|
&config,
|
||||||
|
@ -1049,7 +1073,7 @@ fn create_empty_placeholder(
|
||||||
engine_state: &EngineState,
|
engine_state: &EngineState,
|
||||||
stack: &Stack,
|
stack: &Stack,
|
||||||
) -> String {
|
) -> String {
|
||||||
let config = get_config(engine_state, stack);
|
let config = stack.get_config(engine_state);
|
||||||
if !config.table_show_empty {
|
if !config.table_show_empty {
|
||||||
return String::new();
|
return String::new();
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,8 @@ use nu_protocol::{
|
||||||
ast::{Argument, Call, Expr, Expression, RecordItem},
|
ast::{Argument, Call, Expr, Expression, RecordItem},
|
||||||
debugger::WithoutDebug,
|
debugger::WithoutDebug,
|
||||||
engine::{Command, EngineState, Stack, UNKNOWN_SPAN_ID},
|
engine::{Command, EngineState, Stack, UNKNOWN_SPAN_ID},
|
||||||
record, Category, Example, IntoPipelineData, PipelineData, Signature, Span, SpanId, Spanned,
|
record, Category, Config, Example, IntoPipelineData, PipelineData, Signature, Span, SpanId,
|
||||||
SyntaxShape, Type, Value,
|
Spanned, SyntaxShape, Type, Value,
|
||||||
};
|
};
|
||||||
use std::{collections::HashMap, fmt::Write};
|
use std::{collections::HashMap, fmt::Write};
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ pub fn get_full_help(
|
||||||
engine_state: &EngineState,
|
engine_state: &EngineState,
|
||||||
stack: &mut Stack,
|
stack: &mut Stack,
|
||||||
) -> String {
|
) -> String {
|
||||||
let config = engine_state.get_config();
|
let config = stack.get_config(engine_state);
|
||||||
let doc_config = DocumentationConfig {
|
let doc_config = DocumentationConfig {
|
||||||
no_subcommands: false,
|
no_subcommands: false,
|
||||||
no_color: !config.use_ansi_coloring,
|
no_color: !config.use_ansi_coloring,
|
||||||
|
@ -70,16 +70,30 @@ fn get_documentation(
|
||||||
config: &DocumentationConfig,
|
config: &DocumentationConfig,
|
||||||
is_parser_keyword: bool,
|
is_parser_keyword: bool,
|
||||||
) -> String {
|
) -> String {
|
||||||
|
let nu_config = stack.get_config(engine_state);
|
||||||
|
|
||||||
// Create ansi colors
|
// Create ansi colors
|
||||||
//todo make these configurable -- pull from enginestate.config
|
//todo make these configurable -- pull from enginestate.config
|
||||||
let help_section_name: String =
|
let help_section_name: String = get_ansi_color_for_component_or_default(
|
||||||
get_ansi_color_for_component_or_default(engine_state, "shape_string", "\x1b[32m"); // default: green
|
engine_state,
|
||||||
|
&nu_config,
|
||||||
|
"shape_string",
|
||||||
|
"\x1b[32m",
|
||||||
|
); // default: green
|
||||||
|
|
||||||
let help_subcolor_one: String =
|
let help_subcolor_one: String = get_ansi_color_for_component_or_default(
|
||||||
get_ansi_color_for_component_or_default(engine_state, "shape_external", "\x1b[36m"); // default: cyan
|
engine_state,
|
||||||
|
&nu_config,
|
||||||
|
"shape_external",
|
||||||
|
"\x1b[36m",
|
||||||
|
); // default: cyan
|
||||||
// was const bb: &str = "\x1b[1;34m"; // bold blue
|
// was const bb: &str = "\x1b[1;34m"; // bold blue
|
||||||
let help_subcolor_two: String =
|
let help_subcolor_two: String = get_ansi_color_for_component_or_default(
|
||||||
get_ansi_color_for_component_or_default(engine_state, "shape_block", "\x1b[94m"); // default: light blue (nobold, should be bolding the *names*)
|
engine_state,
|
||||||
|
&nu_config,
|
||||||
|
"shape_block",
|
||||||
|
"\x1b[94m",
|
||||||
|
); // default: light blue (nobold, should be bolding the *names*)
|
||||||
|
|
||||||
const RESET: &str = "\x1b[0m"; // reset
|
const RESET: &str = "\x1b[0m"; // reset
|
||||||
|
|
||||||
|
@ -139,13 +153,12 @@ fn get_documentation(
|
||||||
}
|
}
|
||||||
|
|
||||||
if !sig.named.is_empty() {
|
if !sig.named.is_empty() {
|
||||||
long_desc.push_str(&get_flags_section(Some(engine_state), sig, |v| {
|
long_desc.push_str(&get_flags_section(
|
||||||
nu_highlight_string(
|
Some(engine_state),
|
||||||
&v.to_parsable_string(", ", &engine_state.config),
|
Some(&nu_config),
|
||||||
engine_state,
|
sig,
|
||||||
stack,
|
|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()
|
||||||
|
@ -189,7 +202,7 @@ fn get_documentation(
|
||||||
format!(
|
format!(
|
||||||
" (optional, default: {})",
|
" (optional, default: {})",
|
||||||
nu_highlight_string(
|
nu_highlight_string(
|
||||||
&value.to_parsable_string(", ", &engine_state.config),
|
&value.to_parsable_string(", ", &nu_config),
|
||||||
engine_state,
|
engine_state,
|
||||||
stack
|
stack
|
||||||
)
|
)
|
||||||
|
@ -339,7 +352,7 @@ fn get_documentation(
|
||||||
let _ = writeln!(
|
let _ = writeln!(
|
||||||
long_desc,
|
long_desc,
|
||||||
" {}",
|
" {}",
|
||||||
item.to_expanded_string("", engine_state.get_config())
|
item.to_expanded_string("", &nu_config)
|
||||||
.replace('\n', "\n ")
|
.replace('\n', "\n ")
|
||||||
.trim()
|
.trim()
|
||||||
);
|
);
|
||||||
|
@ -358,15 +371,16 @@ fn get_documentation(
|
||||||
|
|
||||||
fn get_ansi_color_for_component_or_default(
|
fn get_ansi_color_for_component_or_default(
|
||||||
engine_state: &EngineState,
|
engine_state: &EngineState,
|
||||||
|
nu_config: &Config,
|
||||||
theme_component: &str,
|
theme_component: &str,
|
||||||
default: &str,
|
default: &str,
|
||||||
) -> String {
|
) -> 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 caller_stack = &mut Stack::new().capture();
|
||||||
let span = Span::unknown();
|
let span = Span::unknown();
|
||||||
let span_id = UNKNOWN_SPAN_ID;
|
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
|
// Call ansi command using argument
|
||||||
if let Some(argument) = argument_opt {
|
if let Some(argument) = argument_opt {
|
||||||
|
@ -394,8 +408,8 @@ fn get_ansi_color_for_component_or_default(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_argument_for_color_value(
|
fn get_argument_for_color_value(
|
||||||
engine_state: &EngineState,
|
nu_config: &Config,
|
||||||
color: &&Value,
|
color: &Value,
|
||||||
span: Span,
|
span: Span,
|
||||||
span_id: SpanId,
|
span_id: SpanId,
|
||||||
) -> Option<Argument> {
|
) -> Option<Argument> {
|
||||||
|
@ -412,9 +426,7 @@ fn get_argument_for_color_value(
|
||||||
Type::String,
|
Type::String,
|
||||||
),
|
),
|
||||||
Expression::new_existing(
|
Expression::new_existing(
|
||||||
Expr::String(
|
Expr::String(v.clone().to_expanded_string("", nu_config)),
|
||||||
v.clone().to_expanded_string("", engine_state.get_config()),
|
|
||||||
),
|
|
||||||
span,
|
span,
|
||||||
span_id,
|
span_id,
|
||||||
Type::String,
|
Type::String,
|
||||||
|
@ -456,6 +468,7 @@ pub fn document_shape(shape: SyntaxShape) -> SyntaxShape {
|
||||||
|
|
||||||
pub fn get_flags_section<F>(
|
pub fn get_flags_section<F>(
|
||||||
engine_state_opt: Option<&EngineState>,
|
engine_state_opt: Option<&EngineState>,
|
||||||
|
nu_config_opt: Option<&Config>,
|
||||||
signature: &Signature,
|
signature: &Signature,
|
||||||
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
|
||||||
|
@ -470,13 +483,26 @@ where
|
||||||
// Sometimes we want to get the flags without engine_state
|
// Sometimes we want to get the flags without engine_state
|
||||||
// For example, in nu-plugin. In that case, we fall back on default values
|
// For example, in nu-plugin. In that case, we fall back on default values
|
||||||
if let Some(engine_state) = engine_state_opt {
|
if let Some(engine_state) = engine_state_opt {
|
||||||
help_section_name =
|
let nu_config = nu_config_opt.unwrap_or_else(|| engine_state.get_config());
|
||||||
get_ansi_color_for_component_or_default(engine_state, "shape_string", "\x1b[32m"); // default: green
|
help_section_name = get_ansi_color_for_component_or_default(
|
||||||
help_subcolor_one =
|
engine_state,
|
||||||
get_ansi_color_for_component_or_default(engine_state, "shape_external", "\x1b[36m"); // default: cyan
|
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
|
// was const bb: &str = "\x1b[1;34m"; // bold blue
|
||||||
help_subcolor_two =
|
help_subcolor_two = get_ansi_color_for_component_or_default(
|
||||||
get_ansi_color_for_component_or_default(engine_state, "shape_block", "\x1b[94m");
|
engine_state,
|
||||||
|
nu_config,
|
||||||
|
"shape_block",
|
||||||
|
"\x1b[94m",
|
||||||
|
);
|
||||||
// default: light blue (nobold, should be bolding the *names*)
|
// default: light blue (nobold, should be bolding the *names*)
|
||||||
} else {
|
} else {
|
||||||
help_section_name = "\x1b[32m".to_string();
|
help_section_name = "\x1b[32m".to_string();
|
||||||
|
|
|
@ -3,7 +3,7 @@ use nu_path::canonicalize_with;
|
||||||
use nu_protocol::{
|
use nu_protocol::{
|
||||||
ast::Expr,
|
ast::Expr,
|
||||||
engine::{Call, EngineState, Stack, StateWorkingSet},
|
engine::{Call, EngineState, Stack, StateWorkingSet},
|
||||||
Config, ShellError, Span, Value, VarId,
|
ShellError, Span, Value, VarId,
|
||||||
};
|
};
|
||||||
use std::{
|
use std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
|
@ -323,18 +323,6 @@ pub fn find_in_dirs_env(
|
||||||
Ok(check_dir(lib_dirs).or_else(|| check_dir(lib_dirs_fallback)))
|
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(
|
fn get_converted_value(
|
||||||
engine_state: &EngineState,
|
engine_state: &EngineState,
|
||||||
stack: &Stack,
|
stack: &Stack,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::eval_ir_block;
|
use crate::eval_ir_block;
|
||||||
#[allow(deprecated)]
|
#[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_path::{expand_path_with, AbsolutePathBuf};
|
||||||
use nu_protocol::{
|
use nu_protocol::{
|
||||||
ast::{
|
ast::{
|
||||||
|
@ -14,7 +14,7 @@ use nu_protocol::{
|
||||||
Spanned, Type, Value, VarId, ENV_VARIABLE_ID,
|
Spanned, Type, Value, VarId, ENV_VARIABLE_ID,
|
||||||
};
|
};
|
||||||
use nu_utils::IgnoreCaseExt;
|
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>(
|
pub fn eval_call<D: DebugContext>(
|
||||||
engine_state: &EngineState,
|
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() {
|
for (var, value) in callee_stack.get_stack_env_vars() {
|
||||||
caller_stack.add_env_var(var, value);
|
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(
|
fn eval_external(
|
||||||
|
@ -652,8 +655,8 @@ impl Eval for EvalRuntime {
|
||||||
|
|
||||||
type MutState = Stack;
|
type MutState = Stack;
|
||||||
|
|
||||||
fn get_config<'a>(engine_state: Self::State<'a>, stack: &mut Stack) -> Cow<'a, Config> {
|
fn get_config(engine_state: Self::State<'_>, stack: &mut Stack) -> Arc<Config> {
|
||||||
Cow::Owned(get_config(engine_state, stack))
|
stack.get_config(engine_state)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eval_filepath(
|
fn eval_filepath(
|
||||||
|
@ -843,7 +846,14 @@ impl Eval for EvalRuntime {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let is_config = original_key == "config";
|
||||||
|
|
||||||
stack.add_env_var(original_key, value);
|
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 {
|
} else {
|
||||||
lhs.upsert_data_at_cell_path(&cell_path.tail, rhs)?;
|
lhs.upsert_data_at_cell_path(&cell_path.tail, rhs)?;
|
||||||
stack.add_var(*var_id, lhs);
|
stack.add_var(*var_id, lhs);
|
||||||
|
|
|
@ -64,8 +64,8 @@ fn convert_value_to_string(
|
||||||
let has_no_head = cols.is_empty() || (cols.len() == 1 && cols[0].is_empty());
|
let has_no_head = cols.is_empty() || (cols.len() == 1 && cols[0].is_empty());
|
||||||
let has_single_value = vals.len() == 1 && vals[0].len() == 1;
|
let has_single_value = vals.len() == 1 && vals[0].len() == 1;
|
||||||
if !has_no_head && has_single_value {
|
if !has_no_head && has_single_value {
|
||||||
let config = engine_state.get_config();
|
let config = stack.get_config(engine_state);
|
||||||
Ok(vals[0][0].to_abbreviated_string(config))
|
Ok(vals[0][0].to_abbreviated_string(&config))
|
||||||
} else {
|
} else {
|
||||||
let config = engine_state.get_config();
|
let config = engine_state.get_config();
|
||||||
let style_computer = StyleComputer::from_config(engine_state, stack);
|
let style_computer = StyleComputer::from_config(engine_state, stack);
|
||||||
|
|
|
@ -63,10 +63,10 @@ impl Command for Explore {
|
||||||
let tail: bool = call.has_flag(engine_state, stack, "tail")?;
|
let tail: bool = call.has_flag(engine_state, stack, "tail")?;
|
||||||
let peek_value: bool = call.has_flag(engine_state, stack, "peek")?;
|
let peek_value: bool = call.has_flag(engine_state, stack, "peek")?;
|
||||||
|
|
||||||
let nu_config = engine_state.get_config();
|
let nu_config = stack.get_config(engine_state);
|
||||||
let style_computer = StyleComputer::from_config(engine_state, stack);
|
let style_computer = StyleComputer::from_config(engine_state, stack);
|
||||||
|
|
||||||
let mut explore_config = ExploreConfig::from_nu_config(nu_config);
|
let mut explore_config = ExploreConfig::from_nu_config(&nu_config);
|
||||||
explore_config.table.show_header = show_head;
|
explore_config.table.show_header = show_head;
|
||||||
explore_config.table.show_index = show_index;
|
explore_config.table.show_index = show_index;
|
||||||
explore_config.table.separator_style = lookup_color(&style_computer, "separator");
|
explore_config.table.separator_style = lookup_color(&style_computer, "separator");
|
||||||
|
@ -74,7 +74,7 @@ impl Command for Explore {
|
||||||
let lscolors = create_lscolors(engine_state, stack);
|
let lscolors = create_lscolors(engine_state, stack);
|
||||||
|
|
||||||
let config = PagerConfig::new(
|
let config = PagerConfig::new(
|
||||||
nu_config,
|
&nu_config,
|
||||||
&explore_config,
|
&explore_config,
|
||||||
&style_computer,
|
&style_computer,
|
||||||
&lscolors,
|
&lscolors,
|
||||||
|
|
|
@ -16,6 +16,7 @@ nu-protocol = { path = "../nu-protocol", version = "0.95.1" }
|
||||||
nu-system = { path = "../nu-system", version = "0.95.1" }
|
nu-system = { path = "../nu-system", version = "0.95.1" }
|
||||||
nu-plugin-protocol = { path = "../nu-plugin-protocol", version = "0.95.1" }
|
nu-plugin-protocol = { path = "../nu-plugin-protocol", version = "0.95.1" }
|
||||||
nu-plugin-core = { path = "../nu-plugin-core", version = "0.95.1", default-features = false }
|
nu-plugin-core = { path = "../nu-plugin-core", version = "0.95.1", default-features = false }
|
||||||
|
nu-utils = { path = "../nu-utils", version = "0.95.1" }
|
||||||
|
|
||||||
serde = { workspace = true }
|
serde = { workspace = true }
|
||||||
log = { workspace = true }
|
log = { workspace = true }
|
||||||
|
|
|
@ -20,7 +20,7 @@ pub trait PluginExecutionContext: Send + Sync {
|
||||||
/// The pipeline externals state, for tracking the foreground process group, if present
|
/// The pipeline externals state, for tracking the foreground process group, if present
|
||||||
fn pipeline_externals_state(&self) -> Option<&Arc<(AtomicU32, AtomicU32)>>;
|
fn pipeline_externals_state(&self) -> Option<&Arc<(AtomicU32, AtomicU32)>>;
|
||||||
/// Get engine configuration
|
/// Get engine configuration
|
||||||
fn get_config(&self) -> Result<Config, ShellError>;
|
fn get_config(&self) -> Result<Arc<Config>, ShellError>;
|
||||||
/// Get plugin configuration
|
/// Get plugin configuration
|
||||||
fn get_plugin_config(&self) -> Result<Option<Value>, ShellError>;
|
fn get_plugin_config(&self) -> Result<Option<Value>, ShellError>;
|
||||||
/// Get an environment variable from `$env`
|
/// Get an environment variable from `$env`
|
||||||
|
@ -85,8 +85,8 @@ impl<'a> PluginExecutionContext for PluginExecutionCommandContext<'a> {
|
||||||
Some(&self.engine_state.pipeline_externals_state)
|
Some(&self.engine_state.pipeline_externals_state)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_config(&self) -> Result<Config, ShellError> {
|
fn get_config(&self) -> Result<Arc<Config>, ShellError> {
|
||||||
Ok(nu_engine::get_config(&self.engine_state, &self.stack))
|
Ok(self.stack.get_config(&self.engine_state))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_plugin_config(&self) -> Result<Option<Value>, ShellError> {
|
fn get_plugin_config(&self) -> Result<Option<Value>, ShellError> {
|
||||||
|
@ -239,7 +239,7 @@ impl PluginExecutionContext for PluginExecutionBogusContext {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_config(&self) -> Result<Config, ShellError> {
|
fn get_config(&self) -> Result<Arc<Config>, ShellError> {
|
||||||
Err(ShellError::NushellFailed {
|
Err(ShellError::NushellFailed {
|
||||||
msg: "get_config not implemented on bogus".into(),
|
msg: "get_config not implemented on bogus".into(),
|
||||||
})
|
})
|
||||||
|
|
|
@ -76,7 +76,7 @@ impl Command for PluginDeclaration {
|
||||||
EvaluatedCall::try_from_call(call, engine_state, stack, eval_expression)?;
|
EvaluatedCall::try_from_call(call, engine_state, stack, eval_expression)?;
|
||||||
|
|
||||||
// Get the engine config
|
// Get the engine config
|
||||||
let engine_config = nu_engine::get_config(engine_state, stack);
|
let engine_config = stack.get_config(engine_state);
|
||||||
|
|
||||||
// Get, or start, the plugin.
|
// Get, or start, the plugin.
|
||||||
let plugin = self
|
let plugin = self
|
||||||
|
|
|
@ -14,6 +14,7 @@ use nu_protocol::{
|
||||||
ast::Operator, CustomValue, IntoSpanned, PipelineData, PluginMetadata, PluginSignature,
|
ast::Operator, CustomValue, IntoSpanned, PipelineData, PluginMetadata, PluginSignature,
|
||||||
ShellError, Signals, Span, Spanned, Value,
|
ShellError, Signals, Span, Spanned, Value,
|
||||||
};
|
};
|
||||||
|
use nu_utils::SharedCow;
|
||||||
use std::{
|
use std::{
|
||||||
collections::{btree_map, BTreeMap},
|
collections::{btree_map, BTreeMap},
|
||||||
sync::{mpsc, Arc, OnceLock},
|
sync::{mpsc, Arc, OnceLock},
|
||||||
|
@ -1260,7 +1261,7 @@ pub(crate) fn handle_engine_call(
|
||||||
|
|
||||||
match call {
|
match call {
|
||||||
EngineCall::GetConfig => {
|
EngineCall::GetConfig => {
|
||||||
let config = Box::new(context.get_config()?);
|
let config = SharedCow::from(context.get_config()?);
|
||||||
Ok(EngineCallResponse::Config(config))
|
Ok(EngineCallResponse::Config(config))
|
||||||
}
|
}
|
||||||
EngineCall::GetPluginConfig => {
|
EngineCall::GetPluginConfig => {
|
||||||
|
|
|
@ -25,6 +25,7 @@ use nu_protocol::{
|
||||||
ast::Operator, engine::Closure, ByteStreamType, Config, LabeledError, PipelineData,
|
ast::Operator, engine::Closure, ByteStreamType, Config, LabeledError, PipelineData,
|
||||||
PluginMetadata, PluginSignature, ShellError, Span, Spanned, Value,
|
PluginMetadata, PluginSignature, ShellError, Span, Spanned, Value,
|
||||||
};
|
};
|
||||||
|
use nu_utils::SharedCow;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
@ -553,7 +554,7 @@ impl<D> EngineCall<D> {
|
||||||
pub enum EngineCallResponse<D> {
|
pub enum EngineCallResponse<D> {
|
||||||
Error(ShellError),
|
Error(ShellError),
|
||||||
PipelineData(D),
|
PipelineData(D),
|
||||||
Config(Box<Config>),
|
Config(SharedCow<Config>),
|
||||||
ValueMap(HashMap<String, Value>),
|
ValueMap(HashMap<String, Value>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ nu-engine = { path = "../nu-engine", version = "0.95.1" }
|
||||||
nu-protocol = { path = "../nu-protocol", version = "0.95.1" }
|
nu-protocol = { path = "../nu-protocol", version = "0.95.1" }
|
||||||
nu-plugin-protocol = { path = "../nu-plugin-protocol", version = "0.95.1" }
|
nu-plugin-protocol = { path = "../nu-plugin-protocol", version = "0.95.1" }
|
||||||
nu-plugin-core = { path = "../nu-plugin-core", version = "0.95.1", default-features = false }
|
nu-plugin-core = { path = "../nu-plugin-core", version = "0.95.1", default-features = false }
|
||||||
|
nu-utils = { path = "../nu-utils", version = "0.95.1" }
|
||||||
|
|
||||||
log = { workspace = true }
|
log = { workspace = true }
|
||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
|
|
|
@ -14,6 +14,7 @@ use nu_protocol::{
|
||||||
engine::Closure, Config, LabeledError, PipelineData, PluginMetadata, PluginSignature,
|
engine::Closure, Config, LabeledError, PipelineData, PluginMetadata, PluginSignature,
|
||||||
ShellError, Signals, Span, Spanned, Value,
|
ShellError, Signals, Span, Spanned, Value,
|
||||||
};
|
};
|
||||||
|
use nu_utils::SharedCow;
|
||||||
use std::{
|
use std::{
|
||||||
collections::{btree_map, BTreeMap, HashMap},
|
collections::{btree_map, BTreeMap, HashMap},
|
||||||
sync::{mpsc, Arc},
|
sync::{mpsc, Arc},
|
||||||
|
@ -525,9 +526,9 @@ impl EngineInterface {
|
||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn get_config(&self) -> Result<Box<Config>, ShellError> {
|
pub fn get_config(&self) -> Result<Arc<Config>, ShellError> {
|
||||||
match self.engine_call(EngineCall::GetConfig)? {
|
match self.engine_call(EngineCall::GetConfig)? {
|
||||||
EngineCallResponse::Config(config) => Ok(config),
|
EngineCallResponse::Config(config) => Ok(SharedCow::into_arc(config)),
|
||||||
EngineCallResponse::Error(err) => Err(err),
|
EngineCallResponse::Error(err) => Err(err),
|
||||||
_ => Err(ShellError::PluginFailedToDecode {
|
_ => Err(ShellError::PluginFailedToDecode {
|
||||||
msg: "Received unexpected response for EngineCall::GetConfig".into(),
|
msg: "Received unexpected response for EngineCall::GetConfig".into(),
|
||||||
|
|
|
@ -670,7 +670,7 @@ fn print_help(plugin: &impl Plugin, encoder: impl PluginEncoder) {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.and_then(|_| {
|
.and_then(|_| {
|
||||||
let flags = get_flags_section(None, &signature, |v| format!("{:#?}", v));
|
let flags = get_flags_section(None, None, &signature, |v| format!("{:#?}", v));
|
||||||
write!(help, "{flags}")
|
write!(help, "{flags}")
|
||||||
})
|
})
|
||||||
.and_then(|_| writeln!(help, "\nParameters:"))
|
.and_then(|_| writeln!(help, "\nParameters:"))
|
||||||
|
|
|
@ -301,28 +301,11 @@ impl EngineState {
|
||||||
stack: &mut Stack,
|
stack: &mut Stack,
|
||||||
cwd: impl AsRef<Path>,
|
cwd: impl AsRef<Path>,
|
||||||
) -> Result<(), ShellError> {
|
) -> Result<(), ShellError> {
|
||||||
let mut config_updated = false;
|
|
||||||
|
|
||||||
for mut scope in stack.env_vars.drain(..) {
|
for mut scope in stack.env_vars.drain(..) {
|
||||||
for (overlay_name, mut env) in Arc::make_mut(&mut scope).drain() {
|
for (overlay_name, mut env) in Arc::make_mut(&mut scope).drain() {
|
||||||
if let Some(env_vars) = Arc::make_mut(&mut self.env_vars).get_mut(&overlay_name) {
|
if let Some(env_vars) = Arc::make_mut(&mut self.env_vars).get_mut(&overlay_name) {
|
||||||
// Updating existing overlay
|
// Updating existing overlay
|
||||||
for (k, v) in env.drain() {
|
env_vars.extend(env.drain());
|
||||||
if k == "config" {
|
|
||||||
// Don't insert the record as the "config" env var as-is.
|
|
||||||
// Instead, mutate a clone of it with into_config(), and put THAT in env_vars.
|
|
||||||
let mut new_record = v.clone();
|
|
||||||
let (config, error) = new_record.parse_as_config(&self.config);
|
|
||||||
self.config = Arc::new(config);
|
|
||||||
config_updated = true;
|
|
||||||
env_vars.insert(k, new_record);
|
|
||||||
if let Some(e) = error {
|
|
||||||
return Err(e);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
env_vars.insert(k, v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// Pushing a new overlay
|
// Pushing a new overlay
|
||||||
Arc::make_mut(&mut self.env_vars).insert(overlay_name, env);
|
Arc::make_mut(&mut self.env_vars).insert(overlay_name, env);
|
||||||
|
@ -333,7 +316,10 @@ impl EngineState {
|
||||||
// TODO: better error
|
// TODO: better error
|
||||||
std::env::set_current_dir(cwd)?;
|
std::env::set_current_dir(cwd)?;
|
||||||
|
|
||||||
if config_updated {
|
if let Some(config) = stack.config.take() {
|
||||||
|
// If config was updated in the stack, replace it.
|
||||||
|
self.config = config;
|
||||||
|
|
||||||
// Make plugin GC config changes take effect immediately.
|
// Make plugin GC config changes take effect immediately.
|
||||||
#[cfg(feature = "plugin")]
|
#[cfg(feature = "plugin")]
|
||||||
self.update_plugin_gc_configs(&self.config.plugin_gc);
|
self.update_plugin_gc_configs(&self.config.plugin_gc);
|
||||||
|
@ -738,18 +724,24 @@ impl EngineState {
|
||||||
&[0u8; 0]
|
&[0u8; 0]
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_config(&self) -> &Config {
|
/// Get the global config from the engine state.
|
||||||
|
///
|
||||||
|
/// Use [`Stack::get_config()`] instead whenever the `Stack` is available, as it takes into
|
||||||
|
/// account local changes to `$env.config`.
|
||||||
|
pub fn get_config(&self) -> &Arc<Config> {
|
||||||
&self.config
|
&self.config
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_config(&mut self, conf: Config) {
|
pub fn set_config(&mut self, conf: impl Into<Arc<Config>>) {
|
||||||
|
let conf = conf.into();
|
||||||
|
|
||||||
#[cfg(feature = "plugin")]
|
#[cfg(feature = "plugin")]
|
||||||
if conf.plugin_gc != self.config.plugin_gc {
|
if conf.plugin_gc != self.config.plugin_gc {
|
||||||
// Make plugin GC config changes take effect immediately.
|
// Make plugin GC config changes take effect immediately.
|
||||||
self.update_plugin_gc_configs(&conf.plugin_gc);
|
self.update_plugin_gc_configs(&conf.plugin_gc);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.config = Arc::new(conf);
|
self.config = conf;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Fetch the configuration for a plugin
|
/// Fetch the configuration for a plugin
|
||||||
|
@ -1137,7 +1129,7 @@ mod engine_state_tests {
|
||||||
let mut plugins = HashMap::new();
|
let mut plugins = HashMap::new();
|
||||||
plugins.insert("example".into(), Value::string("value", Span::test_data()));
|
plugins.insert("example".into(), Value::string("value", Span::test_data()));
|
||||||
|
|
||||||
let mut config = engine_state.get_config().clone();
|
let mut config = Config::clone(engine_state.get_config());
|
||||||
config.plugins = plugins;
|
config.plugins = plugins;
|
||||||
|
|
||||||
engine_state.set_config(config);
|
engine_state.set_config(config);
|
||||||
|
|
|
@ -3,7 +3,7 @@ use crate::{
|
||||||
ArgumentStack, EngineState, ErrorHandlerStack, Redirection, StackCallArgGuard,
|
ArgumentStack, EngineState, ErrorHandlerStack, Redirection, StackCallArgGuard,
|
||||||
StackCaptureGuard, StackIoGuard, StackOutDest, DEFAULT_OVERLAY_NAME,
|
StackCaptureGuard, StackIoGuard, StackOutDest, DEFAULT_OVERLAY_NAME,
|
||||||
},
|
},
|
||||||
OutDest, ShellError, Span, Value, VarId, ENV_VARIABLE_ID, NU_VARIABLE_ID,
|
Config, OutDest, ShellError, Span, Value, VarId, ENV_VARIABLE_ID, NU_VARIABLE_ID,
|
||||||
};
|
};
|
||||||
use std::{
|
use std::{
|
||||||
collections::{HashMap, HashSet},
|
collections::{HashMap, HashSet},
|
||||||
|
@ -51,6 +51,8 @@ pub struct Stack {
|
||||||
pub parent_stack: Option<Arc<Stack>>,
|
pub parent_stack: Option<Arc<Stack>>,
|
||||||
/// Variables that have been deleted (this is used to hide values from parent stack lookups)
|
/// Variables that have been deleted (this is used to hide values from parent stack lookups)
|
||||||
pub parent_deletions: Vec<VarId>,
|
pub parent_deletions: Vec<VarId>,
|
||||||
|
/// Locally updated config. Use [`.get_config()`] to access correctly.
|
||||||
|
pub config: Option<Arc<Config>>,
|
||||||
pub(crate) out_dest: StackOutDest,
|
pub(crate) out_dest: StackOutDest,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,6 +82,7 @@ impl Stack {
|
||||||
recursion_count: 0,
|
recursion_count: 0,
|
||||||
parent_stack: None,
|
parent_stack: None,
|
||||||
parent_deletions: vec![],
|
parent_deletions: vec![],
|
||||||
|
config: None,
|
||||||
out_dest: StackOutDest::new(),
|
out_dest: StackOutDest::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -100,6 +103,7 @@ impl Stack {
|
||||||
recursion_count: parent.recursion_count,
|
recursion_count: parent.recursion_count,
|
||||||
vars: vec![],
|
vars: vec![],
|
||||||
parent_deletions: vec![],
|
parent_deletions: vec![],
|
||||||
|
config: parent.config.clone(),
|
||||||
out_dest: parent.out_dest.clone(),
|
out_dest: parent.out_dest.clone(),
|
||||||
parent_stack: Some(parent),
|
parent_stack: Some(parent),
|
||||||
}
|
}
|
||||||
|
@ -126,6 +130,7 @@ impl Stack {
|
||||||
unique_stack.env_vars = child.env_vars;
|
unique_stack.env_vars = child.env_vars;
|
||||||
unique_stack.env_hidden = child.env_hidden;
|
unique_stack.env_hidden = child.env_hidden;
|
||||||
unique_stack.active_overlays = child.active_overlays;
|
unique_stack.active_overlays = child.active_overlays;
|
||||||
|
unique_stack.config = child.config;
|
||||||
unique_stack
|
unique_stack
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,6 +197,36 @@ impl Stack {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the local config if set, otherwise the config from the engine state.
|
||||||
|
///
|
||||||
|
/// This is the canonical way to get [`Config`] when [`Stack`] is available.
|
||||||
|
pub fn get_config(&self, engine_state: &EngineState) -> Arc<Config> {
|
||||||
|
self.config
|
||||||
|
.clone()
|
||||||
|
.unwrap_or_else(|| engine_state.config.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Update the local config with the config stored in the `config` environment variable. Run
|
||||||
|
/// this after assigning to `$env.config`.
|
||||||
|
///
|
||||||
|
/// The config will be updated with successfully parsed values even if an error occurs.
|
||||||
|
pub fn update_config(&mut self, engine_state: &EngineState) -> Result<(), ShellError> {
|
||||||
|
if let Some(mut config) = self.get_env_var(engine_state, "config") {
|
||||||
|
let existing_config = self.get_config(engine_state);
|
||||||
|
let (new_config, error) = config.parse_as_config(&existing_config);
|
||||||
|
self.config = Some(new_config.into());
|
||||||
|
// The config value is modified by the update, so we should add it again
|
||||||
|
self.add_env_var("config".into(), config);
|
||||||
|
match error {
|
||||||
|
None => Ok(()),
|
||||||
|
Some(err) => Err(err),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
self.config = None;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn add_var(&mut self, var_id: VarId, value: Value) {
|
pub fn add_var(&mut self, var_id: VarId, value: Value) {
|
||||||
//self.vars.insert(var_id, value);
|
//self.vars.insert(var_id, value);
|
||||||
for (id, val) in &mut self.vars {
|
for (id, val) in &mut self.vars {
|
||||||
|
@ -272,6 +307,7 @@ impl Stack {
|
||||||
recursion_count: self.recursion_count,
|
recursion_count: self.recursion_count,
|
||||||
parent_stack: None,
|
parent_stack: None,
|
||||||
parent_deletions: vec![],
|
parent_deletions: vec![],
|
||||||
|
config: self.config.clone(),
|
||||||
out_dest: self.out_dest.clone(),
|
out_dest: self.out_dest.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -305,6 +341,7 @@ impl Stack {
|
||||||
recursion_count: self.recursion_count,
|
recursion_count: self.recursion_count,
|
||||||
parent_stack: None,
|
parent_stack: None,
|
||||||
parent_deletions: vec![],
|
parent_deletions: vec![],
|
||||||
|
config: self.config.clone(),
|
||||||
out_dest: self.out_dest.clone(),
|
out_dest: self.out_dest.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -627,9 +627,9 @@ impl<'a> StateWorkingSet<'a> {
|
||||||
|
|
||||||
/// Returns a reference to the config stored at permanent state
|
/// Returns a reference to the config stored at permanent state
|
||||||
///
|
///
|
||||||
/// At runtime, you most likely want to call nu_engine::env::get_config because this method
|
/// At runtime, you most likely want to call [`Stack::get_config()`][super::Stack::get_config()]
|
||||||
/// does not capture environment updates during runtime.
|
/// because this method does not capture environment updates during runtime.
|
||||||
pub fn get_config(&self) -> &Config {
|
pub fn get_config(&self) -> &Arc<Config> {
|
||||||
&self.permanent_state.config
|
&self.permanent_state.config
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ use crate::{
|
||||||
debugger::DebugContext,
|
debugger::DebugContext,
|
||||||
Config, GetSpan, Range, Record, ShellError, Span, Value, VarId, ENV_VARIABLE_ID,
|
Config, GetSpan, Range, Record, ShellError, Span, Value, VarId, ENV_VARIABLE_ID,
|
||||||
};
|
};
|
||||||
use std::{borrow::Cow, collections::HashMap};
|
use std::{collections::HashMap, sync::Arc};
|
||||||
|
|
||||||
/// To share implementations for regular eval and const eval
|
/// To share implementations for regular eval and const eval
|
||||||
pub trait Eval {
|
pub trait Eval {
|
||||||
|
@ -316,7 +316,7 @@ pub trait Eval {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_config<'a>(state: Self::State<'a>, mut_state: &mut Self::MutState) -> Cow<'a, Config>;
|
fn get_config(state: Self::State<'_>, mut_state: &mut Self::MutState) -> Arc<Config>;
|
||||||
|
|
||||||
fn eval_filepath(
|
fn eval_filepath(
|
||||||
state: Self::State<'_>,
|
state: Self::State<'_>,
|
||||||
|
|
|
@ -11,8 +11,8 @@ use crate::{
|
||||||
};
|
};
|
||||||
use nu_system::os_info::{get_kernel_version, get_os_arch, get_os_family, get_os_name};
|
use nu_system::os_info::{get_kernel_version, get_os_arch, get_os_family, get_os_name};
|
||||||
use std::{
|
use std::{
|
||||||
borrow::Cow,
|
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
|
sync::Arc,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Create a Value for `$nu`.
|
/// Create a Value for `$nu`.
|
||||||
|
@ -364,8 +364,8 @@ impl Eval for EvalConst {
|
||||||
|
|
||||||
type MutState = ();
|
type MutState = ();
|
||||||
|
|
||||||
fn get_config<'a>(state: Self::State<'a>, _: &mut ()) -> Cow<'a, Config> {
|
fn get_config(state: Self::State<'_>, _: &mut ()) -> Arc<Config> {
|
||||||
Cow::Borrowed(state.get_config())
|
state.get_config().clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eval_filepath(
|
fn eval_filepath(
|
||||||
|
|
Loading…
Reference in a new issue