Move config to be an env var (#5230)

* Move config to be an env var

* fix fmt and tests
This commit is contained in:
JT 2022-04-19 10:28:01 +12:00 committed by GitHub
parent 409f1480f5
commit 76079d5183
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
52 changed files with 455 additions and 608 deletions

View File

@ -6,7 +6,7 @@ use nu_parser::{parse, trim_quotes};
use nu_protocol::engine::Stack; use nu_protocol::engine::Stack;
use nu_protocol::{ use nu_protocol::{
engine::{EngineState, StateDelta, StateWorkingSet}, engine::{EngineState, StateDelta, StateWorkingSet},
Config, PipelineData, Spanned, PipelineData, Spanned,
}; };
use std::path::Path; use std::path::Path;
@ -46,15 +46,7 @@ pub fn evaluate_commands(
report_error(&working_set, &err); report_error(&working_set, &err);
} }
let config = match stack.get_config() { let config = engine_state.get_config().clone();
Ok(config) => config,
Err(e) => {
let working_set = StateWorkingSet::new(engine_state);
report_error(&working_set, &e);
Config::default()
}
};
// Merge the delta in case env vars changed in the config // Merge the delta in case env vars changed in the config
match nu_engine::env::current_dir(engine_state, stack) { match nu_engine::env::current_dir(engine_state, stack) {

View File

@ -5,7 +5,7 @@ use crate::completions::{
use nu_parser::{flatten_expression, parse, FlatShape}; use nu_parser::{flatten_expression, parse, FlatShape};
use nu_protocol::{ use nu_protocol::{
engine::{EngineState, Stack, StateWorkingSet}, engine::{EngineState, Stack, StateWorkingSet},
Span, Value, Span,
}; };
use reedline::{Completer as ReedlineCompleter, Suggestion}; use reedline::{Completer as ReedlineCompleter, Suggestion};
use std::str; use std::str;
@ -15,15 +15,13 @@ use std::sync::Arc;
pub struct NuCompleter { pub struct NuCompleter {
engine_state: Arc<EngineState>, engine_state: Arc<EngineState>,
stack: Stack, stack: Stack,
config: Option<Value>,
} }
impl NuCompleter { impl NuCompleter {
pub fn new(engine_state: Arc<EngineState>, stack: Stack, config: Option<Value>) -> Self { pub fn new(engine_state: Arc<EngineState>, stack: Stack) -> Self {
Self { Self {
engine_state, engine_state,
stack, stack,
config,
} }
} }
@ -146,7 +144,6 @@ impl NuCompleter {
let mut completer = CustomCompletion::new( let mut completer = CustomCompletion::new(
self.engine_state.clone(), self.engine_state.clone(),
self.stack.clone(), self.stack.clone(),
self.config.clone(),
*decl_id, *decl_id,
line, line,
); );

View File

@ -3,7 +3,7 @@ use nu_engine::eval_call;
use nu_protocol::{ use nu_protocol::{
ast::{Argument, Call, Expr, Expression}, ast::{Argument, Call, Expr, Expression},
engine::{EngineState, Stack, StateWorkingSet}, engine::{EngineState, Stack, StateWorkingSet},
PipelineData, Span, Type, Value, CONFIG_VARIABLE_ID, PipelineData, Span, Type, Value,
}; };
use reedline::Suggestion; use reedline::Suggestion;
use std::sync::Arc; use std::sync::Arc;
@ -11,23 +11,15 @@ use std::sync::Arc;
pub struct CustomCompletion { pub struct CustomCompletion {
engine_state: Arc<EngineState>, engine_state: Arc<EngineState>,
stack: Stack, stack: Stack,
config: Option<Value>,
decl_id: usize, decl_id: usize,
line: String, line: String,
} }
impl CustomCompletion { impl CustomCompletion {
pub fn new( pub fn new(engine_state: Arc<EngineState>, stack: Stack, decl_id: usize, line: String) -> Self {
engine_state: Arc<EngineState>,
stack: Stack,
config: Option<Value>,
decl_id: usize,
line: String,
) -> Self {
Self { Self {
engine_state, engine_state,
stack, stack,
config,
decl_id, decl_id,
line, line,
} }
@ -71,20 +63,6 @@ impl Completer for CustomCompletion {
// Line position // Line position
let line_pos = pos - offset; let line_pos = pos - offset;
// Set up our initial config to start from
if let Some(conf) = &self.config {
self.stack.vars.insert(CONFIG_VARIABLE_ID, conf.clone());
} else {
self.stack.vars.insert(
CONFIG_VARIABLE_ID,
Value::Record {
cols: vec![],
vals: vec![],
span: Span { start: 0, end: 0 },
},
);
}
// Call custom declaration // Call custom declaration
let result = eval_call( let result = eval_call(
&self.engine_state, &self.engine_state,

View File

@ -22,7 +22,7 @@ impl Command for NuHighlight {
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> {
@ -30,7 +30,7 @@ impl Command for NuHighlight {
let ctrlc = engine_state.ctrlc.clone(); let ctrlc = engine_state.ctrlc.clone();
let engine_state = engine_state.clone(); let engine_state = engine_state.clone();
let config = stack.get_config()?; let config = engine_state.get_config().clone();
let highlighter = crate::NuHighlighter { let highlighter = crate::NuHighlighter {
engine_state, engine_state,

View File

@ -15,7 +15,7 @@ use nu_protocol::engine::Stack;
use nu_protocol::PipelineData; use nu_protocol::PipelineData;
use nu_protocol::{ use nu_protocol::{
engine::{EngineState, StateWorkingSet}, engine::{EngineState, StateWorkingSet},
Config, ShellError, Span, Value, CONFIG_VARIABLE_ID, ShellError, Span, Value,
}; };
use reedline::{DefaultHinter, Emacs, Vi}; use reedline::{DefaultHinter, Emacs, Vi};
use std::path::PathBuf; use std::path::PathBuf;
@ -76,15 +76,7 @@ pub fn evaluate_repl(
// Get the config once for the history `max_history_size` // Get the config once for the history `max_history_size`
// Updating that will not be possible in one session // Updating that will not be possible in one session
let mut config = match stack.get_config() { let mut config = engine_state.get_config();
Ok(config) => config,
Err(e) => {
let working_set = StateWorkingSet::new(engine_state);
report_error(&working_set, &e);
Config::default()
}
};
if is_perf_true { if is_perf_true {
info!("setup reedline {}:{}:{}", file!(), line!(), column!()); info!("setup reedline {}:{}:{}", file!(), line!(), column!());
@ -114,26 +106,18 @@ pub fn evaluate_repl(
); );
} }
config = match stack.get_config() { //Reset the ctrl-c handler
Ok(config) => config, if let Some(ctrlc) = &mut engine_state.ctrlc {
Err(e) => { ctrlc.store(false, Ordering::SeqCst);
let working_set = StateWorkingSet::new(engine_state); }
report_error(&working_set, &e); config = engine_state.get_config();
Config::default()
}
};
if is_perf_true { if is_perf_true {
info!("setup colors {}:{}:{}", file!(), line!(), column!()); info!("setup colors {}:{}:{}", file!(), line!(), column!());
} }
let color_hm = get_color_config(&config); let color_hm = get_color_config(config);
//Reset the ctrl-c handler
if let Some(ctrlc) = &mut engine_state.ctrlc {
ctrlc.store(false, Ordering::SeqCst);
}
if is_perf_true { if is_perf_true {
info!("update reedline {}:{}:{}", file!(), line!(), column!()); info!("update reedline {}:{}:{}", file!(), line!(), column!());
@ -151,7 +135,6 @@ pub fn evaluate_repl(
.with_completer(Box::new(NuCompleter::new( .with_completer(Box::new(NuCompleter::new(
engine_reference.clone(), engine_reference.clone(),
stack.clone(), stack.clone(),
stack.vars.get(&CONFIG_VARIABLE_ID).cloned(),
))) )))
.with_quick_completions(config.quick_completions) .with_quick_completions(config.quick_completions)
.with_partial_completions(config.partial_completions) .with_partial_completions(config.partial_completions)
@ -165,7 +148,7 @@ pub fn evaluate_repl(
line_editor.disable_hints() line_editor.disable_hints()
}; };
line_editor = match add_menus(line_editor, engine_reference, stack, &config) { line_editor = match add_menus(line_editor, engine_reference, stack, config) {
Ok(line_editor) => line_editor, Ok(line_editor) => line_editor,
Err(e) => { Err(e) => {
let working_set = StateWorkingSet::new(engine_state); let working_set = StateWorkingSet::new(engine_state);
@ -186,7 +169,7 @@ pub fn evaluate_repl(
} }
// Changing the line editor based on the found keybindings // Changing the line editor based on the found keybindings
line_editor = match reedline_config::create_keybindings(&config) { line_editor = match reedline_config::create_keybindings(config) {
Ok(keybindings) => match keybindings { Ok(keybindings) => match keybindings {
KeybindingsMode::Emacs(keybindings) => { KeybindingsMode::Emacs(keybindings) => {
let edit_mode = Box::new(Emacs::new(keybindings)); let edit_mode = Box::new(Emacs::new(keybindings));
@ -211,13 +194,8 @@ pub fn evaluate_repl(
info!("prompt_update {}:{}:{}", file!(), line!(), column!()); info!("prompt_update {}:{}:{}", file!(), line!(), column!());
} }
let prompt = prompt_update::update_prompt( let prompt =
&config, prompt_update::update_prompt(config, engine_state, stack, &mut nu_prompt, is_perf_true);
engine_state,
stack,
&mut nu_prompt,
is_perf_true,
);
entry_num += 1; entry_num += 1;

View File

@ -21,7 +21,7 @@ pub fn print_pipeline_data(
// If the table function is in the declarations, then we can use it // If the table function is in the declarations, then we can use it
// to create the table value that will be printed in the terminal // to create the table value that will be printed in the terminal
let config = stack.get_config().unwrap_or_default(); let config = engine_state.get_config();
let stdout = std::io::stdout(); let stdout = std::io::stdout();
@ -61,7 +61,7 @@ pub fn print_pipeline_data(
return Err(error); return Err(error);
} }
let mut out = item.into_string("\n", &config); let mut out = item.into_string("\n", config);
out.push('\n'); out.push('\n');
match stdout.lock().write_all(out.as_bytes()) { match stdout.lock().write_all(out.as_bytes()) {
@ -78,7 +78,7 @@ pub fn print_pipeline_data(
return Err(error); return Err(error);
} }
let mut out = item.into_string("\n", &config); let mut out = item.into_string("\n", config);
out.push('\n'); out.push('\n');
match stdout.lock().write_all(out.as_bytes()) { match stdout.lock().write_all(out.as_bytes()) {

View File

@ -138,7 +138,7 @@ fn string_helper(
let head = call.head; let head = call.head;
let decimals_value: Option<i64> = call.get_flag(engine_state, stack, "decimals")?; let decimals_value: Option<i64> = call.get_flag(engine_state, stack, "decimals")?;
let column_paths: Vec<CellPath> = call.rest(engine_state, stack, 0)?; let column_paths: Vec<CellPath> = call.rest(engine_state, stack, 0)?;
let config = stack.get_config().unwrap_or_default(); let config = engine_state.get_config().clone();
if let Some(decimal_val) = decimals_value { if let Some(decimal_val) = decimals_value {
if decimals && decimal_val.is_negative() { if decimals && decimal_val.is_negative() {

View File

@ -25,12 +25,12 @@ impl Command for Debug {
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 head = call.head; let head = call.head;
let config = stack.get_config().unwrap_or_default(); let config = engine_state.get_config().clone();
let raw = call.has_flag("raw"); let raw = call.has_flag("raw");
input.map( input.map(

View File

@ -2,7 +2,7 @@ use nu_engine::eval_block;
use nu_parser::parse; use nu_parser::parse;
use nu_protocol::{ use nu_protocol::{
engine::{Command, EngineState, Stack, StateWorkingSet}, engine::{Command, EngineState, Stack, StateWorkingSet},
PipelineData, Span, Value, CONFIG_VARIABLE_ID, PipelineData, Span,
}; };
use super::eager::ToDataFrame; use super::eager::ToDataFrame;
@ -63,16 +63,6 @@ pub fn test_dataframe(cmds: Vec<Box<dyn Command + 'static>>) {
let mut stack = Stack::new(); let mut stack = Stack::new();
// Set up our initial config to start from
stack.vars.insert(
CONFIG_VARIABLE_ID,
Value::Record {
cols: vec![],
vals: vec![],
span: Span::test_data(),
},
);
match eval_block( match eval_block(
&engine_state, &engine_state,
&mut stack, &mut stack,

View File

@ -5,7 +5,7 @@ use nu_parser::parse;
#[cfg(test)] #[cfg(test)]
use nu_protocol::{ use nu_protocol::{
engine::{Command, EngineState, Stack, StateWorkingSet}, engine::{Command, EngineState, Stack, StateWorkingSet},
PipelineData, Span, Value, CONFIG_VARIABLE_ID, PipelineData, Span, Value,
}; };
#[cfg(test)] #[cfg(test)]
@ -112,16 +112,6 @@ pub fn test_examples(cmd: impl Command + 'static) {
}, },
); );
// Set up our initial config to start from
stack.vars.insert(
CONFIG_VARIABLE_ID,
Value::Record {
cols: vec![],
vals: vec![],
span: Span::test_data(),
},
);
match eval_block( match eval_block(
&engine_state, &engine_state,
&mut stack, &mut stack,

View File

@ -378,31 +378,22 @@ mod test {
vals: vec![ vals: vec![
Value::Record { Value::Record {
cols: vec!["id".to_string(), "name".to_string()], cols: vec!["id".to_string(), "name".to_string()],
vals: vec![ vals: vec![Value::Int { val: 123, span }, Value::Nothing { span }],
Value::Int { span,
val: 123,
span: span,
},
Value::Nothing { span: span },
],
span: span,
}, },
Value::Record { Value::Record {
cols: vec!["id".to_string(), "name".to_string()], cols: vec!["id".to_string(), "name".to_string()],
vals: vec![ vals: vec![
Value::Int { Value::Int { val: 456, span },
val: 456,
span: span,
},
Value::String { Value::String {
val: "foo bar".to_string(), val: "foo bar".to_string(),
span: span, span,
}, },
], ],
span: span, span,
}, },
], ],
span: span, span,
}], }],
span, span,
}; };

View File

@ -133,7 +133,7 @@ fn rm(
let targets: Vec<Spanned<String>> = call.rest(engine_state, stack, 0)?; let targets: Vec<Spanned<String>> = call.rest(engine_state, stack, 0)?;
let span = call.head; let span = call.head;
let config = stack.get_config()?; let config = engine_state.get_config();
let rm_always_trash = config.rm_always_trash; let rm_always_trash = config.rm_always_trash;

View File

@ -157,13 +157,13 @@ impl Command for Find {
fn find_with_regex( fn find_with_regex(
regex: String, regex: String,
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 ctrlc = engine_state.ctrlc.clone(); let ctrlc = engine_state.ctrlc.clone();
let config = stack.get_config()?; let config = engine_state.get_config().clone();
let insensitive = call.has_flag("insensitive"); let insensitive = call.has_flag("insensitive");
let multiline = call.has_flag("multiline"); let multiline = call.has_flag("multiline");
@ -271,7 +271,7 @@ fn find_with_rest(
let ctrlc = engine_state.ctrlc.clone(); let ctrlc = engine_state.ctrlc.clone();
let metadata = input.metadata(); let metadata = input.metadata();
let engine_state = engine_state.clone(); let engine_state = engine_state.clone();
let config = stack.get_config()?; let config = engine_state.get_config().clone();
let invert = call.has_flag("invert"); let invert = call.has_flag("invert");
let terms = call.rest::<Value>(&engine_state, stack, 0)?; let terms = call.rest::<Value>(&engine_state, stack, 0)?;

View File

@ -71,15 +71,15 @@ impl Command for Headers {
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<nu_protocol::PipelineData, ShellError> { ) -> Result<nu_protocol::PipelineData, ShellError> {
let config = stack.get_config()?; let config = engine_state.get_config();
let metadata = input.metadata(); let metadata = input.metadata();
let value = input.into_value(call.head); let value = input.into_value(call.head);
let headers = extract_headers(&value, &config)?; let headers = extract_headers(&value, config)?;
let new_headers = replace_headers(value, &headers)?; let new_headers = replace_headers(value, &headers)?;
Ok(new_headers.into_pipeline_data().set_metadata(metadata)) Ok(new_headers.into_pipeline_data().set_metadata(metadata))

View File

@ -79,7 +79,7 @@ fn from_csv(
let noheaders = call.has_flag("noheaders"); let noheaders = call.has_flag("noheaders");
let separator: Option<Value> = call.get_flag(engine_state, stack, "separator")?; let separator: Option<Value> = call.get_flag(engine_state, stack, "separator")?;
let config = stack.get_config().unwrap_or_default(); let config = engine_state.get_config();
let sep = match separator { let sep = match separator {
Some(Value::String { val: s, span }) => { Some(Value::String { val: s, span }) => {
@ -99,7 +99,7 @@ fn from_csv(
_ => ',', _ => ',',
}; };
from_delimited_data(noheaders, sep, input, name, &config) from_delimited_data(noheaders, sep, input, name, config)
} }
#[cfg(test)] #[cfg(test)]

View File

@ -45,8 +45,8 @@ impl Command for FromEml {
let head = call.head; let head = call.head;
let preview_body: Option<Spanned<i64>> = let preview_body: Option<Spanned<i64>> =
call.get_flag(engine_state, stack, "preview-body")?; call.get_flag(engine_state, stack, "preview-body")?;
let config = stack.get_config().unwrap_or_default(); let config = engine_state.get_config();
from_eml(input, preview_body, head, &config) from_eml(input, preview_body, head, config)
} }
fn examples(&self) -> Vec<Example> { fn examples(&self) -> Vec<Example> {

View File

@ -28,14 +28,14 @@ impl Command for FromIcs {
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<nu_protocol::PipelineData, ShellError> { ) -> Result<nu_protocol::PipelineData, ShellError> {
let head = call.head; let head = call.head;
let config = stack.get_config().unwrap_or_default(); let config = engine_state.get_config();
from_ics(input, head, &config) from_ics(input, head, config)
} }
fn examples(&self) -> Vec<Example> { fn examples(&self) -> Vec<Example> {

View File

@ -50,14 +50,14 @@ b=2' | from ini",
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<nu_protocol::PipelineData, ShellError> { ) -> Result<nu_protocol::PipelineData, ShellError> {
let head = call.head; let head = call.head;
let config = stack.get_config().unwrap_or_default(); let config = engine_state.get_config();
from_ini(input, head, &config) from_ini(input, head, config)
} }
} }

View File

@ -70,13 +70,13 @@ impl Command for FromJson {
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<nu_protocol::PipelineData, ShellError> { ) -> Result<nu_protocol::PipelineData, ShellError> {
let span = call.head; let span = call.head;
let config = stack.get_config().unwrap_or_default(); let config = engine_state.get_config();
let string_input = input.collect_string("", &config)?; let string_input = input.collect_string("", config)?;
if string_input.is_empty() { if string_input.is_empty() {
return Ok(PipelineData::new(span)); return Ok(PipelineData::new(span));

View File

@ -66,14 +66,14 @@ impl Command for FromNuon {
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<nu_protocol::PipelineData, ShellError> { ) -> Result<nu_protocol::PipelineData, ShellError> {
let head = call.head; let head = call.head;
let config = stack.get_config().unwrap_or_default(); let config = engine_state.get_config();
let string_input = input.collect_string("", &config)?; let string_input = input.collect_string("", config)?;
let engine_state = EngineState::new(); let engine_state = EngineState::new();

View File

@ -267,7 +267,7 @@ fn from_ssv(
call: &Call, call: &Call,
input: PipelineData, input: PipelineData,
) -> Result<PipelineData, ShellError> { ) -> Result<PipelineData, ShellError> {
let config = stack.get_config().unwrap_or_default(); let config = engine_state.get_config();
let name = call.head; let name = call.head;
let noheaders = call.has_flag("noheaders"); let noheaders = call.has_flag("noheaders");
@ -275,7 +275,7 @@ fn from_ssv(
let minimum_spaces: Option<Spanned<usize>> = let minimum_spaces: Option<Spanned<usize>> =
call.get_flag(engine_state, stack, "minimum-spaces")?; call.get_flag(engine_state, stack, "minimum-spaces")?;
let concat_string = input.collect_string("", &config)?; let concat_string = input.collect_string("", config)?;
let split_at = match minimum_spaces { let split_at = match minimum_spaces {
Some(number) => number.item, Some(number) => number.item,
None => DEFAULT_MINIMUM_SPACES, None => DEFAULT_MINIMUM_SPACES,

View File

@ -67,14 +67,14 @@ b = [1, 2]' | from toml",
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<nu_protocol::PipelineData, ShellError> { ) -> Result<nu_protocol::PipelineData, ShellError> {
let span = call.head; let span = call.head;
let config = stack.get_config().unwrap_or_default(); let config = engine_state.get_config();
let mut string_input = input.collect_string("", &config)?; let mut string_input = input.collect_string("", config)?;
string_input.push('\n'); string_input.push('\n');
Ok(convert_string_to_value(string_input, span)?.into_pipeline_data()) Ok(convert_string_to_value(string_input, span)?.into_pipeline_data())
} }

View File

@ -28,13 +28,13 @@ impl Command for FromTsv {
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<nu_protocol::PipelineData, ShellError> { ) -> Result<nu_protocol::PipelineData, ShellError> {
let config = stack.get_config().unwrap_or_default(); let config = engine_state.get_config();
from_tsv(call, input, &config) from_tsv(call, input, config)
} }
fn examples(&self) -> Vec<Example> { fn examples(&self) -> Vec<Example> {

View File

@ -20,14 +20,14 @@ impl Command for FromUrl {
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<nu_protocol::PipelineData, ShellError> { ) -> Result<nu_protocol::PipelineData, ShellError> {
let head = call.head; let head = call.head;
let config = stack.get_config().unwrap_or_default(); let config = engine_state.get_config();
from_url(input, head, &config) from_url(input, head, config)
} }
fn examples(&self) -> Vec<Example> { fn examples(&self) -> Vec<Example> {

View File

@ -26,14 +26,14 @@ impl Command for FromVcf {
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<nu_protocol::PipelineData, ShellError> { ) -> Result<nu_protocol::PipelineData, ShellError> {
let head = call.head; let head = call.head;
let config = stack.get_config().unwrap_or_default(); let config = engine_state.get_config();
from_vcf(input, head, &config) from_vcf(input, head, config)
} }
fn examples(&self) -> Vec<Example> { fn examples(&self) -> Vec<Example> {

View File

@ -24,14 +24,14 @@ impl Command for FromXml {
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<nu_protocol::PipelineData, ShellError> { ) -> Result<nu_protocol::PipelineData, ShellError> {
let head = call.head; let head = call.head;
let config = stack.get_config().unwrap_or_default(); let config = engine_state.get_config();
from_xml(input, head, &config) from_xml(input, head, config)
} }
fn examples(&self) -> Vec<Example> { fn examples(&self) -> Vec<Example> {

View File

@ -30,14 +30,14 @@ impl Command for FromYaml {
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<nu_protocol::PipelineData, ShellError> { ) -> Result<nu_protocol::PipelineData, ShellError> {
let head = call.head; let head = call.head;
let config = stack.get_config().unwrap_or_default(); let config = engine_state.get_config();
from_yaml(input, head, &config) from_yaml(input, head, config)
} }
} }
@ -59,14 +59,14 @@ impl Command for FromYml {
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<nu_protocol::PipelineData, ShellError> { ) -> Result<nu_protocol::PipelineData, ShellError> {
let head = call.head; let head = call.head;
let config = stack.get_config().unwrap_or_default(); let config = engine_state.get_config();
from_yaml(input, head, &config) from_yaml(input, head, config)
} }
fn examples(&self) -> Vec<Example> { fn examples(&self) -> Vec<Example> {

View File

@ -60,7 +60,7 @@ impl Command for ToCsv {
let head = call.head; let head = call.head;
let noheaders = call.has_flag("noheaders"); let noheaders = call.has_flag("noheaders");
let separator: Option<Spanned<String>> = call.get_flag(engine_state, stack, "separator")?; let separator: Option<Spanned<String>> = call.get_flag(engine_state, stack, "separator")?;
let config = stack.get_config().unwrap_or_default(); let config = engine_state.get_config();
to_csv(input, noheaders, separator, head, config) to_csv(input, noheaders, separator, head, config)
} }
} }
@ -70,7 +70,7 @@ fn to_csv(
noheaders: bool, noheaders: bool,
separator: Option<Spanned<String>>, separator: Option<Spanned<String>>,
head: Span, head: Span,
config: Config, config: &Config,
) -> Result<PipelineData, ShellError> { ) -> Result<PipelineData, ShellError> {
let sep = match separator { let sep = match separator {
Some(Spanned { item: s, span, .. }) => { Some(Spanned { item: s, span, .. }) => {

View File

@ -125,10 +125,10 @@ pub fn to_delimited_data(
format_name: &'static str, format_name: &'static str,
input: PipelineData, input: PipelineData,
span: Span, span: Span,
config: Config, config: &Config,
) -> Result<PipelineData, ShellError> { ) -> Result<PipelineData, ShellError> {
let value = input.into_value(span); let value = input.into_value(span);
let output = match from_value_to_delimited_string(&value, sep, &config, span) { let output = match from_value_to_delimited_string(&value, sep, config, span) {
Ok(mut x) => { Ok(mut x) => {
if noheaders { if noheaders {
if let Some(second_line) = x.find('\n') { if let Some(second_line) = x.find('\n') {

View File

@ -295,7 +295,7 @@ fn to_html(
let partial = call.has_flag("partial"); let partial = call.has_flag("partial");
let list = call.has_flag("list"); let list = call.has_flag("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 = stack.get_config().unwrap_or_default(); let config = engine_state.get_config();
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);
@ -365,15 +365,15 @@ fn to_html(
let inner_value = match vec_of_values.len() { let inner_value = match vec_of_values.len() {
0 => String::default(), 0 => String::default(),
1 => match headers { 1 => match headers {
Some(headers) => html_table(vec_of_values, headers, &config), Some(headers) => html_table(vec_of_values, headers, config),
None => { None => {
let value = &vec_of_values[0]; let value = &vec_of_values[0];
html_value(value.clone(), &config) html_value(value.clone(), config)
} }
}, },
_ => match headers { _ => match headers {
Some(headers) => html_table(vec_of_values, headers, &config), Some(headers) => html_table(vec_of_values, headers, config),
None => html_list(vec_of_values, &config), None => html_list(vec_of_values, config),
}, },
}; };

View File

@ -59,15 +59,15 @@ impl Command for ToMd {
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<nu_protocol::PipelineData, ShellError> { ) -> Result<nu_protocol::PipelineData, ShellError> {
let head = call.head; let head = call.head;
let pretty = call.has_flag("pretty"); let pretty = call.has_flag("pretty");
let per_element = call.has_flag("per-element"); let per_element = call.has_flag("per-element");
let config = stack.get_config().unwrap_or_default(); let config = engine_state.get_config();
to_md(input, pretty, per_element, config, head) to_md(input, pretty, per_element, config, head)
} }
} }
@ -76,17 +76,17 @@ fn to_md(
input: PipelineData, input: PipelineData,
pretty: bool, pretty: bool,
per_element: bool, per_element: bool,
config: Config, config: &Config,
head: Span, head: Span,
) -> Result<PipelineData, ShellError> { ) -> Result<PipelineData, ShellError> {
let (grouped_input, single_list) = group_by(input, head, &config); let (grouped_input, single_list) = group_by(input, head, config);
if per_element || single_list { if per_element || single_list {
return Ok(Value::string( return Ok(Value::string(
grouped_input grouped_input
.into_iter() .into_iter()
.map(move |val| match val { .map(move |val| match val {
Value::List { .. } => table(val.into_pipeline_data(), pretty, &config), Value::List { .. } => table(val.into_pipeline_data(), pretty, config),
other => fragment(other, pretty, &config), other => fragment(other, pretty, config),
}) })
.collect::<Vec<String>>() .collect::<Vec<String>>()
.join(""), .join(""),
@ -94,7 +94,7 @@ fn to_md(
) )
.into_pipeline_data()); .into_pipeline_data());
} }
Ok(Value::string(table(grouped_input, pretty, &config), head).into_pipeline_data()) Ok(Value::string(table(grouped_input, pretty, config), head).into_pipeline_data())
} }
fn fragment(input: Value, pretty: bool, config: &Config) -> String { fn fragment(input: Value, pretty: bool, config: &Config) -> String {

View File

@ -35,14 +35,14 @@ impl Command for ToTsv {
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<nu_protocol::PipelineData, ShellError> { ) -> Result<nu_protocol::PipelineData, ShellError> {
let head = call.head; let head = call.head;
let noheaders = call.has_flag("noheaders"); let noheaders = call.has_flag("noheaders");
let config = stack.get_config().unwrap_or_default(); let config = engine_state.get_config();
to_tsv(input, noheaders, head, config) to_tsv(input, noheaders, head, config)
} }
} }
@ -51,7 +51,7 @@ fn to_tsv(
input: PipelineData, input: PipelineData,
noheaders: bool, noheaders: bool,
head: Span, head: Span,
config: Config, config: &Config,
) -> Result<PipelineData, ShellError> { ) -> Result<PipelineData, ShellError> {
to_delimited_data(noheaders, '\t', "TSV", input, head, config) to_delimited_data(noheaders, '\t', "TSV", input, head, config)
} }

View File

@ -61,9 +61,9 @@ impl Command for ToXml {
input: PipelineData, input: PipelineData,
) -> Result<nu_protocol::PipelineData, ShellError> { ) -> Result<nu_protocol::PipelineData, ShellError> {
let head = call.head; let head = call.head;
let config = stack.get_config().unwrap_or_default(); let config = engine_state.get_config();
let pretty: Option<Spanned<i64>> = call.get_flag(engine_state, stack, "pretty")?; let pretty: Option<Spanned<i64>> = call.get_flag(engine_state, stack, "pretty")?;
to_xml(input, head, pretty, &config) to_xml(input, head, pretty, config)
} }
} }

View File

@ -317,7 +317,7 @@ Format: #
let list: bool = call.has_flag("list"); let list: bool = call.has_flag("list");
let escape: bool = call.has_flag("escape"); let escape: bool = call.has_flag("escape");
let osc: bool = call.has_flag("osc"); let osc: bool = call.has_flag("osc");
let use_ansi_coloring = stack.get_config()?.use_ansi_coloring; let use_ansi_coloring = engine_state.get_config().use_ansi_coloring;
if list { if list {
return generate_ansi_code_list(engine_state, call.head, use_ansi_coloring); return generate_ansi_code_list(engine_state, call.head, use_ansi_coloring);

View File

@ -25,14 +25,14 @@ impl Command for KeybindingsListen {
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> {
println!("Type any key combination to see key details. Press ESC to abort."); println!("Type any key combination to see key details. Press ESC to abort.");
match print_events(stack) { match print_events(engine_state) {
Ok(v) => Ok(v.into_pipeline_data()), Ok(v) => Ok(v.into_pipeline_data()),
Err(e) => { Err(e) => {
terminal::disable_raw_mode()?; terminal::disable_raw_mode()?;
@ -56,8 +56,8 @@ impl Command for KeybindingsListen {
} }
} }
pub fn print_events(stack: &mut Stack) -> Result<Value, ShellError> { pub fn print_events(engine_state: &EngineState) -> Result<Value, ShellError> {
let config = stack.get_config()?; let config = engine_state.get_config();
stdout().flush()?; stdout().flush()?;
terminal::enable_raw_mode()?; terminal::enable_raw_mode()?;
@ -78,7 +78,7 @@ pub fn print_events(stack: &mut Stack) -> Result<Value, ShellError> {
Value::Record { cols, vals, .. } => cols Value::Record { cols, vals, .. } => cols
.iter() .iter()
.zip(vals.iter()) .zip(vals.iter())
.map(|(x, y)| format!("{}: {}", x, y.into_string("", &config))) .map(|(x, y)| format!("{}: {}", x, y.into_string("", config)))
.collect::<Vec<String>>() .collect::<Vec<String>>()
.join(", "), .join(", "),

View File

@ -52,11 +52,11 @@ impl Command for BuildString {
call: &Call, call: &Call,
_input: PipelineData, _input: PipelineData,
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> { ) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
let config = stack.get_config().unwrap_or_default(); let config = engine_state.get_config();
let output = call let output = call
.positional_iter() .positional_iter()
.map(|expr| { .map(|expr| {
eval_expression(engine_state, stack, expr).map(|val| val.into_string(", ", &config)) eval_expression(engine_state, stack, expr).map(|val| val.into_string(", ", config))
}) })
.collect::<Result<Vec<String>, ShellError>>()?; .collect::<Result<Vec<String>, ShellError>>()?;

View File

@ -87,8 +87,8 @@ fn detect_columns(
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("no-headers"); let noheader = call.has_flag("no-headers");
let ctrlc = engine_state.ctrlc.clone(); let ctrlc = engine_state.ctrlc.clone();
let config = stack.get_config()?; let config = engine_state.get_config();
let input = input.collect_string("", &config)?; let input = input.collect_string("", config)?;
#[allow(clippy::needless_collect)] #[allow(clippy::needless_collect)]
let input: Vec<_> = input let input: Vec<_> = input

View File

@ -35,14 +35,14 @@ impl Command for Format {
call: &Call, call: &Call,
input: PipelineData, input: PipelineData,
) -> Result<PipelineData, ShellError> { ) -> Result<PipelineData, ShellError> {
let config = stack.get_config()?; let config = engine_state.get_config();
let specified_pattern: Result<Value, ShellError> = call.req(engine_state, stack, 0); let specified_pattern: Result<Value, ShellError> = call.req(engine_state, stack, 0);
match specified_pattern { match specified_pattern {
Err(e) => Err(e), Err(e) => Err(e),
Ok(pattern) => { Ok(pattern) => {
let string_pattern = pattern.as_string()?; let string_pattern = pattern.as_string()?;
let ops = extract_formatting_operations(string_pattern); let ops = extract_formatting_operations(string_pattern);
format(input, &ops, call.head, &config) format(input, &ops, call.head, config)
} }
} }
} }

View File

@ -41,7 +41,7 @@ impl Command for StrCollect {
) -> Result<PipelineData, ShellError> { ) -> Result<PipelineData, ShellError> {
let separator: Option<String> = call.opt(engine_state, stack, 0)?; let separator: Option<String> = call.opt(engine_state, stack, 0)?;
let config = stack.get_config().unwrap_or_default(); let config = engine_state.get_config();
// let output = input.collect_string(&separator.unwrap_or_default(), &config)?; // let output = input.collect_string(&separator.unwrap_or_default(), &config)?;
// Hmm, not sure what we actually want. If you don't use debug_string, Date comes out as human readable // Hmm, not sure what we actually want. If you don't use debug_string, Date comes out as human readable
@ -54,7 +54,7 @@ impl Command for StrCollect {
return Err(error); return Err(error);
} }
value => { value => {
strings.push(value.debug_string("\n", &config)); strings.push(value.debug_string("\n", config));
} }
} }
} }

View File

@ -147,15 +147,12 @@ impl ExternalCommand {
)), )),
Ok(mut child) => { Ok(mut child) => {
if !input.is_nothing() { if !input.is_nothing() {
let engine_state = engine_state.clone(); let mut engine_state = engine_state.clone();
let mut stack = stack.clone(); let mut stack = stack.clone();
stack.update_config(
"use_ansi_coloring", // Turn off color as we pass data through
Value::Bool { engine_state.config.use_ansi_coloring = false;
val: false,
span: Span::new(0, 0),
},
);
// if there is a string or a stream, that is sent to the pipe std // if there is a string or a stream, that is sent to the pipe std
if let Some(mut stdin_write) = child.stdin.take() { if let Some(mut stdin_write) = child.stdin.take() {
std::thread::spawn(move || { std::thread::spawn(move || {

View File

@ -64,7 +64,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("color"); let color_param: bool = call.has_flag("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 = stack.get_config().unwrap_or_default(); let config = engine_state.get_config();
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,
@ -74,7 +74,7 @@ prints out the list properly."#
match input { match input {
PipelineData::Value(Value::List { vals, .. }, ..) => { PipelineData::Value(Value::List { vals, .. }, ..) => {
// dbg!("value::list"); // dbg!("value::list");
let data = convert_to_list(vals, &config, call.head); let data = convert_to_list(vals, config, call.head);
if let Some(items) = data { if let Some(items) = data {
Ok(create_grid_output( Ok(create_grid_output(
items, items,
@ -91,7 +91,7 @@ prints out the list properly."#
} }
PipelineData::ListStream(stream, ..) => { PipelineData::ListStream(stream, ..) => {
// dbg!("value::stream"); // dbg!("value::stream");
let data = convert_to_list(stream, &config, call.head); let data = convert_to_list(stream, config, call.head);
if let Some(items) = data { if let Some(items) = data {
Ok(create_grid_output( Ok(create_grid_output(
items, items,
@ -112,7 +112,7 @@ prints out the list properly."#
let mut items = vec![]; let mut items = vec![];
for (i, (c, v)) in cols.into_iter().zip(vals.into_iter()).enumerate() { for (i, (c, v)) in cols.into_iter().zip(vals.into_iter()).enumerate() {
items.push((i, c, v.into_string(", ", &config))) items.push((i, c, v.into_string(", ", config)))
} }
Ok(create_grid_output( Ok(create_grid_output(

View File

@ -56,8 +56,8 @@ impl Command for Table {
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> { ) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
let head = call.head; let head = call.head;
let ctrlc = engine_state.ctrlc.clone(); let ctrlc = engine_state.ctrlc.clone();
let config = stack.get_config().unwrap_or_default(); let config = engine_state.get_config();
let color_hm = get_color_config(&config); let color_hm = get_color_config(config);
let start_num: Option<i64> = call.get_flag(engine_state, stack, "start-number")?; let start_num: Option<i64> = call.get_flag(engine_state, stack, "start-number")?;
let row_offset = start_num.unwrap_or_default() as usize; let row_offset = start_num.unwrap_or_default() as usize;
@ -99,7 +99,6 @@ impl Command for Table {
ListStream::from_stream(vals.into_iter(), ctrlc.clone()), ListStream::from_stream(vals.into_iter(), ctrlc.clone()),
call, call,
row_offset, row_offset,
config,
ctrlc, ctrlc,
metadata, metadata,
), ),
@ -109,7 +108,6 @@ impl Command for Table {
stream, stream,
call, call,
row_offset, row_offset,
config,
ctrlc, ctrlc,
metadata, metadata,
), ),
@ -123,7 +121,7 @@ impl Command for Table {
style: TextStyle::default_field(), style: TextStyle::default_field(),
}, },
StyledString { StyledString {
contents: v.into_abbreviated_string(&config), contents: v.into_abbreviated_string(config),
style: TextStyle::default(), style: TextStyle::default(),
}, },
]) ])
@ -132,10 +130,10 @@ impl Command for Table {
let table = nu_table::Table { let table = nu_table::Table {
headers: vec![], headers: vec![],
data: output, data: output,
theme: load_theme_from_config(&config), theme: load_theme_from_config(config),
}; };
let result = nu_table::draw_table(&table, term_width, &color_hm, &config); let result = nu_table::draw_table(&table, term_width, &color_hm, config);
Ok(Value::String { Ok(Value::String {
val: result, val: result,
@ -149,7 +147,7 @@ impl Command for Table {
self.run(engine_state, stack, call, base_pipeline) self.run(engine_state, stack, call, base_pipeline)
} }
PipelineData::Value(x @ Value::Range { .. }, ..) => Ok(Value::String { PipelineData::Value(x @ Value::Range { .. }, ..) => Ok(Value::String {
val: x.into_string("", &config), val: x.into_string("", config),
span: call.head, span: call.head,
} }
.into_pipeline_data()), .into_pipeline_data()),
@ -195,7 +193,6 @@ fn handle_row_stream(
stream: ListStream, stream: ListStream,
call: &Call, call: &Call,
row_offset: usize, row_offset: usize,
config: Config,
ctrlc: Option<Arc<AtomicBool>>, ctrlc: Option<Arc<AtomicBool>>,
metadata: Option<PipelineMetadata>, metadata: Option<PipelineMetadata>,
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> { ) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
@ -203,7 +200,7 @@ fn handle_row_stream(
Some(PipelineMetadata { Some(PipelineMetadata {
data_source: DataSource::Ls, data_source: DataSource::Ls,
}) => { }) => {
let config = config.clone(); let config = engine_state.config.clone();
let ctrlc = ctrlc.clone(); let ctrlc = ctrlc.clone();
let ls_colors = match stack.get_env_var(engine_state, "LS_COLORS") { let ls_colors = match stack.get_env_var(engine_state, "LS_COLORS") {
@ -281,7 +278,7 @@ fn handle_row_stream(
stdout: Some(RawStream::new( stdout: Some(RawStream::new(
Box::new(PagingTableCreator { Box::new(PagingTableCreator {
row_offset, row_offset,
config, config: engine_state.get_config().clone(),
ctrlc: ctrlc.clone(), ctrlc: ctrlc.clone(),
head, head,
stream, stream,

View File

@ -506,12 +506,12 @@ pub fn eval_expression(
parts.push(eval_expression(engine_state, stack, expr)?); parts.push(eval_expression(engine_state, stack, expr)?);
} }
let config = stack.get_config().unwrap_or_default(); let config = engine_state.get_config();
parts parts
.into_iter() .into_iter()
.into_pipeline_data(None) .into_pipeline_data(None)
.collect_string("", &config) .collect_string("", config)
.map(|x| Value::String { .map(|x| Value::String {
val: x, val: x,
span: expr.span, span: expr.span,
@ -634,7 +634,7 @@ pub fn eval_block(
let exit_code = exit_code.take(); let exit_code = exit_code.take();
// Drain the input to the screen via tabular output // Drain the input to the screen via tabular output
let config = stack.get_config().unwrap_or_default(); let config = engine_state.get_config();
match engine_state.find_decl("table".as_bytes()) { match engine_state.find_decl("table".as_bytes()) {
Some(decl_id) => { Some(decl_id) => {
@ -652,7 +652,7 @@ pub fn eval_block(
return Err(error); return Err(error);
} }
let mut out = item.into_string("\n", &config); let mut out = item.into_string("\n", config);
out.push('\n'); out.push('\n');
match stdout.lock().write_all(out.as_bytes()) { match stdout.lock().write_all(out.as_bytes()) {
@ -669,7 +669,7 @@ pub fn eval_block(
return Err(error); return Err(error);
} }
let mut out = item.into_string("\n", &config); let mut out = item.into_string("\n", config);
out.push('\n'); out.push('\n');
match stdout.lock().write_all(out.as_bytes()) { match stdout.lock().write_all(out.as_bytes()) {
@ -690,7 +690,7 @@ pub fn eval_block(
} }
_ => { _ => {
// Drain the input to the screen via tabular output // Drain the input to the screen via tabular output
let config = stack.get_config().unwrap_or_default(); let config = engine_state.get_config();
match engine_state.find_decl("table".as_bytes()) { match engine_state.find_decl("table".as_bytes()) {
Some(decl_id) => { Some(decl_id) => {
@ -708,7 +708,7 @@ pub fn eval_block(
return Err(error); return Err(error);
} }
let mut out = item.into_string("\n", &config); let mut out = item.into_string("\n", config);
out.push('\n'); out.push('\n');
match stdout.lock().write_all(out.as_bytes()) { match stdout.lock().write_all(out.as_bytes()) {
@ -725,7 +725,7 @@ pub fn eval_block(
return Err(error); return Err(error);
} }
let mut out = item.into_string("\n", &config); let mut out = item.into_string("\n", config);
out.push('\n'); out.push('\n');
match stdout.lock().write_all(out.as_bytes()) { match stdout.lock().write_all(out.as_bytes()) {

View File

@ -5,7 +5,7 @@ use nu_protocol::{
ImportPatternMember, Pipeline, ImportPatternMember, Pipeline,
}, },
engine::StateWorkingSet, engine::StateWorkingSet,
span, Exportable, Overlay, PositionalArg, Span, SyntaxShape, Type, CONFIG_VARIABLE_ID, span, Exportable, Overlay, PositionalArg, Span, SyntaxShape, Type,
}; };
use std::collections::HashSet; use std::collections::HashSet;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
@ -1710,9 +1710,7 @@ pub fn parse_let(
let rhs_type = rvalue.ty.clone(); let rhs_type = rvalue.ty.clone();
if let Some(var_id) = var_id { if let Some(var_id) = var_id {
if var_id != CONFIG_VARIABLE_ID { working_set.set_variable_type(var_id, rhs_type);
working_set.set_variable_type(var_id, rhs_type);
}
} }
let call = Box::new(Call { let call = Box::new(Call {

View File

@ -14,7 +14,7 @@ use nu_protocol::{
}, },
engine::StateWorkingSet, engine::StateWorkingSet,
span, BlockId, Flag, PositionalArg, Signature, Span, Spanned, SyntaxShape, Type, Unit, VarId, span, BlockId, Flag, PositionalArg, Signature, Span, Spanned, SyntaxShape, Type, Unit, VarId,
CONFIG_VARIABLE_ID, ENV_VARIABLE_ID, IN_VARIABLE_ID, ENV_VARIABLE_ID, IN_VARIABLE_ID,
}; };
use crate::parse_keywords::{ use crate::parse_keywords::{
@ -1689,16 +1689,6 @@ pub fn parse_variable_expr(
}, },
None, None,
); );
} else if contents == b"$config" {
return (
Expression {
expr: Expr::Var(nu_protocol::CONFIG_VARIABLE_ID),
span,
ty: Type::Any,
custom_completion: None,
},
None,
);
} else if contents == b"$env" { } else if contents == b"$env" {
return ( return (
Expression { Expression {
@ -2818,16 +2808,6 @@ pub fn parse_var_with_opt_type(
Some(ParseError::MissingType(spans[*spans_idx])), Some(ParseError::MissingType(spans[*spans_idx])),
) )
} }
} else if bytes == b"$config" || bytes == b"config" {
(
Expression {
expr: Expr::Var(CONFIG_VARIABLE_ID),
span: spans[*spans_idx],
ty: Type::Any,
custom_completion: None,
},
None,
)
} else { } else {
let id = let id =
working_set.add_variable(bytes, span(&spans[*spans_idx..*spans_idx + 1]), Type::Any); working_set.add_variable(bytes, span(&spans[*spans_idx..*spans_idx + 1]), Type::Any);

View File

@ -1,7 +1,7 @@
use super::{Command, Stack}; use super::{Command, Stack};
use crate::{ use crate::{
ast::Block, AliasId, BlockId, DeclId, Example, Overlay, OverlayId, ShellError, Signature, Span, ast::Block, AliasId, BlockId, Config, DeclId, Example, Overlay, OverlayId, ShellError,
Type, VarId, Variable, Signature, Span, Type, VarId, Variable,
}; };
use core::panic; use core::panic;
use std::{ use std::{
@ -176,14 +176,14 @@ pub struct EngineState {
pub scope: Vec<ScopeFrame>, pub scope: Vec<ScopeFrame>,
pub ctrlc: Option<Arc<AtomicBool>>, pub ctrlc: Option<Arc<AtomicBool>>,
pub env_vars: HashMap<String, Value>, pub env_vars: HashMap<String, Value>,
pub config: Config,
#[cfg(feature = "plugin")] #[cfg(feature = "plugin")]
pub plugin_signatures: Option<PathBuf>, pub plugin_signatures: Option<PathBuf>,
} }
pub const NU_VARIABLE_ID: usize = 0; pub const NU_VARIABLE_ID: usize = 0;
pub const IN_VARIABLE_ID: usize = 1; pub const IN_VARIABLE_ID: usize = 1;
pub const CONFIG_VARIABLE_ID: usize = 2; pub const ENV_VARIABLE_ID: usize = 2;
pub const ENV_VARIABLE_ID: usize = 3;
// NOTE: If you add more to this list, make sure to update the > checks based on the last in the list // NOTE: If you add more to this list, make sure to update the > checks based on the last in the list
impl EngineState { impl EngineState {
@ -205,6 +205,7 @@ impl EngineState {
scope: vec![ScopeFrame::new()], scope: vec![ScopeFrame::new()],
ctrlc: None, ctrlc: None,
env_vars: HashMap::new(), env_vars: HashMap::new(),
config: Config::default(),
#[cfg(feature = "plugin")] #[cfg(feature = "plugin")]
plugin_signatures: None, plugin_signatures: None,
} }
@ -263,6 +264,10 @@ impl EngineState {
if let Some(stack) = stack { if let Some(stack) = stack {
for mut env_scope in stack.env_vars.drain(..) { for mut env_scope in stack.env_vars.drain(..) {
for (k, v) in env_scope.drain() { for (k, v) in env_scope.drain() {
if k == "config" {
self.config = v.clone().into_config().unwrap_or_default();
}
self.env_vars.insert(k, v); self.env_vars.insert(k, v);
} }
} }
@ -474,6 +479,10 @@ impl EngineState {
panic!("internal error: span missing in file contents cache") panic!("internal error: span missing in file contents cache")
} }
pub fn get_config(&self) -> &Config {
&self.config
}
pub fn get_var(&self, var_id: VarId) -> &Variable { pub fn get_var(&self, var_id: VarId) -> &Variable {
self.vars self.vars
.get(var_id) .get(var_id)
@ -1233,6 +1242,10 @@ impl<'a> StateWorkingSet<'a> {
self.permanent_state.env_vars.get(name) self.permanent_state.env_vars.get(name)
} }
pub fn get_config(&self) -> &Config {
&self.permanent_state.config
}
pub fn list_env(&self) -> Vec<String> { pub fn list_env(&self) -> Vec<String> {
let mut env_vars = vec![]; let mut env_vars = vec![];

View File

@ -1,7 +1,7 @@
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use crate::engine::EngineState; use crate::engine::EngineState;
use crate::{Config, ShellError, Span, Value, VarId, CONFIG_VARIABLE_ID}; use crate::{ShellError, Span, Value, VarId};
/// A runtime value stack used during evaluation /// A runtime value stack used during evaluation
/// ///
@ -97,11 +97,6 @@ impl Stack {
output.env_vars = self.env_vars.clone(); output.env_vars = self.env_vars.clone();
output.env_vars.push(HashMap::new()); output.env_vars.push(HashMap::new());
let config = self
.get_var(CONFIG_VARIABLE_ID, Span::new(0, 0))
.expect("internal error: config is missing");
output.vars.insert(CONFIG_VARIABLE_ID, config);
output output
} }
@ -122,11 +117,6 @@ impl Stack {
output.env_vars = self.env_vars.clone(); output.env_vars = self.env_vars.clone();
output.env_vars.push(HashMap::new()); output.env_vars.push(HashMap::new());
let config = self
.get_var(CONFIG_VARIABLE_ID, fake_span)
.expect("internal error: config is missing");
output.vars.insert(CONFIG_VARIABLE_ID, config);
output output
} }
@ -212,27 +202,27 @@ impl Stack {
} }
} }
pub fn get_config(&self) -> Result<Config, ShellError> { // pub fn get_config(&self) -> Result<Config, ShellError> {
let config = self.get_var(CONFIG_VARIABLE_ID, Span::new(0, 0)); // let config = self.get_var(CONFIG_VARIABLE_ID, Span::new(0, 0));
match config { // match config {
Ok(config) => config.into_config(), // Ok(config) => config.into_config(),
Err(e) => Err(e), // Err(e) => Err(e),
} // }
} // }
pub fn update_config(&mut self, name: &str, value: Value) { // pub fn update_config(&mut self, name: &str, value: Value) {
if let Some(Value::Record { cols, vals, .. }) = self.vars.get_mut(&CONFIG_VARIABLE_ID) { // if let Some(Value::Record { cols, vals, .. }) = self.vars.get_mut(&CONFIG_VARIABLE_ID) {
for col_val in cols.iter().zip(vals.iter_mut()) { // for col_val in cols.iter().zip(vals.iter_mut()) {
if col_val.0 == name { // if col_val.0 == name {
*col_val.1 = value; // *col_val.1 = value;
return; // return;
} // }
} // }
cols.push(name.to_string()); // cols.push(name.to_string());
vals.push(value); // vals.push(value);
} // }
} // }
pub fn print_stack(&self) { pub fn print_stack(&self) {
println!("vars:"); println!("vars:");

View File

@ -15,7 +15,7 @@ mod value;
mod variable; mod variable;
pub use config::*; pub use config::*;
pub use engine::{CONFIG_VARIABLE_ID, ENV_VARIABLE_ID, IN_VARIABLE_ID, NU_VARIABLE_ID}; pub use engine::{ENV_VARIABLE_ID, IN_VARIABLE_ID, NU_VARIABLE_ID};
pub use example::*; pub use example::*;
pub use exportable::*; pub use exportable::*;
pub use id::*; pub use id::*;

View File

@ -74,262 +74,3 @@ module completions {
# Get just the extern definitions without the custom completion commands # Get just the extern definitions without the custom completion commands
use completions * use completions *
# for more information on themes see
# https://www.nushell.sh/book/coloring_and_theming.html
let default_theme = {
# color for nushell primitives
separator: white
leading_trailing_space_bg: { attr: n } # no fg, no bg, attr none effectively turns this off
header: green_bold
empty: blue
bool: white
int: white
filesize: white
duration: white
date: white
range: white
float: white
string: white
nothing: white
binary: white
cellpath: white
row_index: green_bold
record: white
list: white
block: white
hints: dark_gray
# shapes are used to change the cli syntax highlighting
shape_garbage: { fg: "#FFFFFF" bg: "#FF0000" attr: b}
shape_binary: purple_bold
shape_bool: light_cyan
shape_int: purple_bold
shape_float: purple_bold
shape_range: yellow_bold
shape_internalcall: cyan_bold
shape_external: cyan
shape_externalarg: green_bold
shape_literal: blue
shape_operator: yellow
shape_signature: green_bold
shape_string: green
shape_string_interpolation: cyan_bold
shape_datetime: cyan_bold
shape_list: cyan_bold
shape_table: blue_bold
shape_record: cyan_bold
shape_block: blue_bold
shape_filepath: cyan
shape_globpattern: cyan_bold
shape_variable: purple
shape_flag: blue_bold
shape_custom: green
shape_nothing: light_cyan
}
# The default config record. This is where much of your global configuration is setup.
let $config = {
filesize_metric: false
table_mode: rounded # basic, compact, compact_double, light, thin, with_love, rounded, reinforced, heavy, none, other
use_ls_colors: true
rm_always_trash: false
color_config: $default_theme
use_grid_icons: true
footer_mode: "25" # always, never, number_of_rows, auto
quick_completions: true # set this to false to prevent auto-selecting completions when only one remains
partial_completions: true # set this to false to prevent partial filling of the prompt
animate_prompt: false # redraw the prompt every second
float_precision: 2
use_ansi_coloring: true
filesize_format: "auto" # b, kb, kib, mb, mib, gb, gib, tb, tib, pb, pib, eb, eib, zb, zib, auto
edit_mode: emacs # emacs, vi
max_history_size: 10000 # Session has to be reloaded for this to take effect
sync_history_on_enter: true # Enable to share the history between multiple sessions, else you have to close the session to persist history to file
menus: [
# Configuration for default nushell menus
# Note the lack of souce parameter
{
name: completion_menu
only_buffer_difference: false
marker: "| "
type: {
layout: columnar
columns: 4
col_width: 20 # Optional value. If missing all the screen width is used to calculate column width
col_padding: 2
}
style: {
text: green
selected_text: green_reverse
description_text: yellow
}
}
{
name: history_menu
only_buffer_difference: true
marker: "? "
type: {
layout: list
page_size: 10
}
style: {
text: green
selected_text: green_reverse
description_text: yellow
}
}
{
name: help_menu
only_buffer_difference: true
marker: "? "
type: {
layout: description
columns: 4
col_width: 20 # Optional value. If missing all the screen width is used to calculate column width
col_padding: 2
selection_rows: 4
description_rows: 10
}
style: {
text: green
selected_text: green_reverse
description_text: yellow
}
}
# Example of extra menus created using a nushell source
# Use the source field to create a list of records that populates
# the menu
{
name: commands_menu
only_buffer_difference: false
marker: "# "
type: {
layout: columnar
columns: 4
col_width: 20
col_padding: 2
}
style: {
text: green
selected_text: green_reverse
description_text: yellow
}
source: { |buffer, position|
$nu.scope.commands
| where command =~ $buffer
| each { |it| {value: $it.command description: $it.usage} }
}
}
{
name: vars_menu
only_buffer_difference: true
marker: "# "
type: {
layout: list
page_size: 10
}
style: {
text: green
selected_text: green_reverse
description_text: yellow
}
source: { |buffer, position|
$nu.scope.vars
| where name =~ $buffer
| sort-by name
| each { |it| {value: $it.name description: $it.type} }
}
}
{
name: commands_with_description
only_buffer_difference: true
marker: "# "
type: {
layout: description
columns: 4
col_width: 20
col_padding: 2
selection_rows: 4
description_rows: 10
}
style: {
text: green
selected_text: green_reverse
description_text: yellow
}
source: { |buffer, position|
$nu.scope.commands
| where command =~ $buffer
| each { |it| {value: $it.command description: $it.usage} }
}
}
]
keybindings: [
{
name: completion_menu
modifier: none
keycode: tab
mode: emacs # Options: emacs vi_normal vi_insert
event: {
until: [
{ send: menu name: completion_menu }
{ send: menunext }
]
}
}
{
name: completion_previous
modifier: shift
keycode: backtab
mode: [emacs, vi_normal, vi_insert] # Note: You can add the same keybinding to all modes by using a list
event: { send: menuprevious }
}
{
name: history_menu
modifier: control
keycode: char_x
mode: emacs
event: {
until: [
{ send: menu name: history_menu }
{ send: menupagenext }
]
}
}
{
name: history_previous
modifier: control
keycode: char_z
mode: emacs
event: {
until: [
{ send: menupageprevious }
{ edit: undo }
]
}
}
# Keybindings used to trigger the user defined menus
{
name: commands_menu
modifier: control
keycode: char_t
mode: [emacs, vi_normal, vi_insert]
event: { send: menu name: commands_menu }
}
{
name: vars_menu
modifier: control
keycode: char_y
mode: [emacs, vi_normal, vi_insert]
event: { send: menu name: vars_menu }
}
{
name: commands_with_description
modifier: control
keycode: char_u
mode: [emacs, vi_normal, vi_insert]
event: { send: menu name: commands_with_description }
}
]
}

View File

@ -56,3 +56,262 @@ let-env NU_PLUGIN_DIRS = [
# To add entries to PATH (on Windows you might use Path), you can use the following pattern: # To add entries to PATH (on Windows you might use Path), you can use the following pattern:
# let-env PATH = ($env.PATH | prepend '/some/path') # let-env PATH = ($env.PATH | prepend '/some/path')
# for more information on themes see
# https://www.nushell.sh/book/coloring_and_theming.html
let default_theme = {
# color for nushell primitives
separator: white
leading_trailing_space_bg: { attr: n } # no fg, no bg, attr none effectively turns this off
header: green_bold
empty: blue
bool: white
int: white
filesize: white
duration: white
date: white
range: white
float: white
string: white
nothing: white
binary: white
cellpath: white
row_index: green_bold
record: white
list: white
block: white
hints: dark_gray
# shapes are used to change the cli syntax highlighting
shape_garbage: { fg: "#FFFFFF" bg: "#FF0000" attr: b}
shape_binary: purple_bold
shape_bool: light_cyan
shape_int: purple_bold
shape_float: purple_bold
shape_range: yellow_bold
shape_internalcall: cyan_bold
shape_external: cyan
shape_externalarg: green_bold
shape_literal: blue
shape_operator: yellow
shape_signature: green_bold
shape_string: green
shape_string_interpolation: cyan_bold
shape_datetime: cyan_bold
shape_list: cyan_bold
shape_table: blue_bold
shape_record: cyan_bold
shape_block: blue_bold
shape_filepath: cyan
shape_globpattern: cyan_bold
shape_variable: purple
shape_flag: blue_bold
shape_custom: green
shape_nothing: light_cyan
}
# The default config record. This is where much of your global configuration is setup.
let-env config = {
filesize_metric: false
table_mode: rounded # basic, compact, compact_double, light, thin, with_love, rounded, reinforced, heavy, none, other
use_ls_colors: true
rm_always_trash: false
color_config: $default_theme
use_grid_icons: true
footer_mode: "25" # always, never, number_of_rows, auto
quick_completions: true # set this to false to prevent auto-selecting completions when only one remains
partial_completions: true # set this to false to prevent partial filling of the prompt
animate_prompt: false # redraw the prompt every second
float_precision: 2
use_ansi_coloring: true
filesize_format: "auto" # b, kb, kib, mb, mib, gb, gib, tb, tib, pb, pib, eb, eib, zb, zib, auto
edit_mode: emacs # emacs, vi
max_history_size: 10000 # Session has to be reloaded for this to take effect
sync_history_on_enter: true # Enable to share the history between multiple sessions, else you have to close the session to persist history to file
menus: [
# Configuration for default nushell menus
# Note the lack of souce parameter
{
name: completion_menu
only_buffer_difference: false
marker: "| "
type: {
layout: columnar
columns: 4
col_width: 20 # Optional value. If missing all the screen width is used to calculate column width
col_padding: 2
}
style: {
text: green
selected_text: green_reverse
description_text: yellow
}
}
{
name: history_menu
only_buffer_difference: true
marker: "? "
type: {
layout: list
page_size: 10
}
style: {
text: green
selected_text: green_reverse
description_text: yellow
}
}
{
name: help_menu
only_buffer_difference: true
marker: "? "
type: {
layout: description
columns: 4
col_width: 20 # Optional value. If missing all the screen width is used to calculate column width
col_padding: 2
selection_rows: 4
description_rows: 10
}
style: {
text: green
selected_text: green_reverse
description_text: yellow
}
}
# Example of extra menus created using a nushell source
# Use the source field to create a list of records that populates
# the menu
{
name: commands_menu
only_buffer_difference: false
marker: "# "
type: {
layout: columnar
columns: 4
col_width: 20
col_padding: 2
}
style: {
text: green
selected_text: green_reverse
description_text: yellow
}
source: { |buffer, position|
$nu.scope.commands
| where command =~ $buffer
| each { |it| {value: $it.command description: $it.usage} }
}
}
{
name: vars_menu
only_buffer_difference: true
marker: "# "
type: {
layout: list
page_size: 10
}
style: {
text: green
selected_text: green_reverse
description_text: yellow
}
source: { |buffer, position|
$nu.scope.vars
| where name =~ $buffer
| sort-by name
| each { |it| {value: $it.name description: $it.type} }
}
}
{
name: commands_with_description
only_buffer_difference: true
marker: "# "
type: {
layout: description
columns: 4
col_width: 20
col_padding: 2
selection_rows: 4
description_rows: 10
}
style: {
text: green
selected_text: green_reverse
description_text: yellow
}
source: { |buffer, position|
$nu.scope.commands
| where command =~ $buffer
| each { |it| {value: $it.command description: $it.usage} }
}
}
]
keybindings: [
{
name: completion_menu
modifier: none
keycode: tab
mode: emacs # Options: emacs vi_normal vi_insert
event: {
until: [
{ send: menu name: completion_menu }
{ send: menunext }
]
}
}
{
name: completion_previous
modifier: shift
keycode: backtab
mode: [emacs, vi_normal, vi_insert] # Note: You can add the same keybinding to all modes by using a list
event: { send: menuprevious }
}
{
name: history_menu
modifier: control
keycode: char_x
mode: emacs
event: {
until: [
{ send: menu name: history_menu }
{ send: menupagenext }
]
}
}
{
name: history_previous
modifier: control
keycode: char_z
mode: emacs
event: {
until: [
{ send: menupageprevious }
{ edit: undo }
]
}
}
# Keybindings used to trigger the user defined menus
{
name: commands_menu
modifier: control
keycode: char_t
mode: [emacs, vi_normal, vi_insert]
event: { send: menu name: commands_menu }
}
{
name: vars_menu
modifier: control
keycode: char_y
mode: [emacs, vi_normal, vi_insert]
event: { send: menu name: vars_menu }
}
{
name: commands_with_description
modifier: control
keycode: char_u
mode: [emacs, vi_normal, vi_insert]
event: { send: menu name: commands_with_description }
}
]
}

View File

@ -22,7 +22,7 @@ use nu_protocol::{
ast::{Call, Expr, Expression}, ast::{Call, Expr, Expression},
engine::{Command, EngineState, Stack, StateWorkingSet}, engine::{Command, EngineState, Stack, StateWorkingSet},
Category, Example, IntoPipelineData, PipelineData, RawStream, ShellError, Signature, Span, Category, Example, IntoPipelineData, PipelineData, RawStream, ShellError, Signature, Span,
Spanned, SyntaxShape, Value, CONFIG_VARIABLE_ID, Spanned, SyntaxShape, Value,
}; };
use std::cell::RefCell; use std::cell::RefCell;
use std::{ use std::{
@ -196,15 +196,6 @@ fn main() -> Result<()> {
gather_parent_env_vars(&mut engine_state); gather_parent_env_vars(&mut engine_state);
let mut stack = nu_protocol::engine::Stack::new(); let mut stack = nu_protocol::engine::Stack::new();
stack.vars.insert(
CONFIG_VARIABLE_ID,
Value::Record {
cols: vec![],
vals: vec![],
span: Span::new(0, 0),
},
);
if let Some(commands) = &binary_args.commands { if let Some(commands) = &binary_args.commands {
#[cfg(feature = "plugin")] #[cfg(feature = "plugin")]
read_plugin_file( read_plugin_file(
@ -317,14 +308,6 @@ fn parse_commandline_args(
let _ = engine_state.merge_delta(delta, None, init_cwd); let _ = engine_state.merge_delta(delta, None, init_cwd);
let mut stack = Stack::new(); let mut stack = Stack::new();
stack.add_var(
CONFIG_VARIABLE_ID,
Value::Record {
cols: vec![],
vals: vec![],
span: Span::new(0, 0),
},
);
// We should have a successful parse now // We should have a successful parse now
if let Some(pipeline) = block.pipelines.get(0) { if let Some(pipeline) = block.pipelines.get(0) {

View File

@ -13,33 +13,6 @@ fn proper_shadow() -> TestResult {
run_test("let x = 10; let x = $x + 9; $x", "19") run_test("let x = 10; let x = $x + 9; $x", "19")
} }
#[test]
fn config_filesize_format_with_metric_true() -> TestResult {
// Note: this tests both the config variable and that it is properly captured into a block
run_test(
r#"let config = {"filesize_metric": true "filesize_format": "kib" }; do { 40kb | into string } "#,
"39.1 KiB",
)
}
#[test]
fn config_filesize_format_with_metric_false_kib() -> TestResult {
// Note: this tests both the config variable and that it is properly captured into a block
run_test(
r#"let config = {"filesize_metric": false "filesize_format": "kib" }; do { 40kb | into string } "#,
"39.1 KiB",
)
}
#[test]
fn config_filesize_format_with_metric_false_kb() -> TestResult {
// Note: this tests both the config variable and that it is properly captured into a block
run_test(
r#"let config = {"filesize_metric": false "filesize_format": "kb" }; do { 40kb | into string } "#,
"40.0 KB",
)
}
#[test] #[test]
fn in_variable_1() -> TestResult { fn in_variable_1() -> TestResult {
run_test(r#"[3] | if $in.0 > 4 { "yay!" } else { "boo" }"#, "boo") run_test(r#"[3] | if $in.0 > 4 { "yay!" } else { "boo" }"#, "boo")