Merge pull request #231 from nushell/load_config

Load config
This commit is contained in:
JT 2021-10-13 17:23:39 +13:00 committed by GitHub
commit ff6cc2cbdd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 177 additions and 85 deletions

View File

@ -29,6 +29,7 @@
- [x] Value serialization - [x] Value serialization
- [x] Handling rows with missing columns during a cell path - [x] Handling rows with missing columns during a cell path
- [x] finish operator type-checking - [x] finish operator type-checking
- [x] Config file loading
- [ ] Input/output types - [ ] Input/output types
- [ ] Support for `$in` - [ ] Support for `$in`
- [ ] ctrl-c support - [ ] ctrl-c support

View File

@ -1,13 +1,10 @@
extern crate unicode_segmentation; extern crate unicode_segmentation;
use std::collections::HashMap;
// use indexmap::indexmap;
use unicode_segmentation::UnicodeSegmentation; use unicode_segmentation::UnicodeSegmentation;
use nu_protocol::ast::Call; use nu_protocol::ast::Call;
use nu_protocol::engine::{Command, EvaluationContext}; use nu_protocol::engine::{Command, EvaluationContext};
use nu_protocol::{ShellError, Signature, Span, Spanned, Type, Value}; use nu_protocol::{Example, ShellError, Signature, Span, Type, Value};
pub struct Size; pub struct Size;
@ -33,32 +30,72 @@ impl Command for Size {
size(context, call, input) size(context, call, input)
} }
// fn examples(&self) -> Vec<Example> { fn examples(&self) -> Vec<Example> {
// vec![ vec![
// Example { Example {
// description: "Count the number of words in a string", description: "Count the number of words in a string",
// example: r#"echo "There are seven words in this sentence" | size"#, example: r#""There are seven words in this sentence" | size"#,
// result: Some(vec![Value::row(indexmap! { result: Some(Value::Record {
// "lines".to_string() => UntaggedValue::int(0).into(), cols: vec![
// "words".to_string() => UntaggedValue::int(7).into(), "lines".into(),
// "chars".to_string() => UntaggedValue::int(38).into(), "words".into(),
// "bytes".to_string() => UntaggedValue::int(38).into(), "chars".into(),
// }) "bytes".into(),
// .into()]), ],
// }, vals: vec![
// Example { Value::Int {
// description: "Counts Unicode characters correctly in a string", val: 0,
// example: r#"echo "Amélie Amelie" | size"#, span: Span::unknown(),
// result: Some(vec![UntaggedValue::row(indexmap! { },
// "lines".to_string() => UntaggedValue::int(0).into(), Value::Int {
// "words".to_string() => UntaggedValue::int(2).into(), val: 7,
// "chars".to_string() => UntaggedValue::int(13).into(), span: Span::unknown(),
// "bytes".to_string() => UntaggedValue::int(15).into(), },
// }) Value::Int {
// .into()]), val: 38,
// }, span: Span::unknown(),
// ] },
// } Value::Int {
val: 38,
span: Span::unknown(),
},
],
span: Span::unknown(),
}),
},
Example {
description: "Counts Unicode characters correctly in a string",
example: r#""Amélie Amelie" | size"#,
result: Some(Value::Record {
cols: vec![
"lines".into(),
"words".into(),
"chars".into(),
"bytes".into(),
],
vals: vec![
Value::Int {
val: 0,
span: Span::unknown(),
},
Value::Int {
val: 2,
span: Span::unknown(),
},
Value::Int {
val: 13,
span: Span::unknown(),
},
Value::Int {
val: 15,
span: Span::unknown(),
},
],
span: Span::unknown(),
}),
},
]
}
} }
fn size(_context: &EvaluationContext, call: &Call, input: Value) -> Result<Value, ShellError> { fn size(_context: &EvaluationContext, call: &Call, input: Value) -> Result<Value, ShellError> {
@ -100,24 +137,32 @@ fn count(contents: &str, span: Span) -> Value {
} }
} }
let mut item: HashMap<String, Value> = HashMap::new(); let mut cols = vec![];
item.insert("lines".to_string(), Value::Int { val: lines, span }); let mut vals = vec![];
item.insert("words".to_string(), Value::Int { val: words, span });
item.insert("chars".to_string(), Value::Int { val: chars, span });
item.insert("bytes".to_string(), Value::Int { val: bytes, span });
Value::from(Spanned { item, span }) cols.push("lines".into());
vals.push(Value::Int { val: lines, span });
cols.push("words".into());
vals.push(Value::Int { val: words, span });
cols.push("chars".into());
vals.push(Value::Int { val: chars, span });
cols.push("bytes".into());
vals.push(Value::Int { val: bytes, span });
Value::Record { cols, vals, span }
} }
// #[cfg(test)] #[cfg(test)]
// mod tests { mod test {
// use super::ShellError; use super::*;
// use super::Size;
// #[test] #[test]
// fn examples_work_as_expected() -> Result<(), ShellError> { fn test_examples() {
// use crate::examples::test as test_examples; use crate::test_examples;
// test_examples(Size {}) test_examples(Size {})
// } }
// } }

View File

@ -0,0 +1,9 @@
use std::path::PathBuf;
pub fn home_dir() -> Option<PathBuf> {
dirs_next::home_dir()
}
pub fn config_dir() -> Option<PathBuf> {
dirs_next::config_dir()
}

View File

@ -1,8 +1,10 @@
mod dots; mod dots;
mod expansions; mod expansions;
mod helpers;
mod tilde; mod tilde;
mod util; mod util;
pub use expansions::{canonicalize, canonicalize_with, expand_path, expand_path_with}; pub use expansions::{canonicalize, canonicalize_with, expand_path, expand_path_with};
pub use helpers::{config_dir, home_dir};
pub use tilde::expand_tilde; pub use tilde::expand_tilde;
pub use util::trim_trailing_slash; pub use util::trim_trailing_slash;

View File

@ -91,6 +91,23 @@ fn main() -> Result<()> {
let mut nu_prompt = NushellPrompt::new(); let mut nu_prompt = NushellPrompt::new();
let stack = nu_protocol::engine::Stack::new(); let stack = nu_protocol::engine::Stack::new();
// Load config startup file
if let Some(mut config_path) = nu_path::config_dir() {
config_path.push("nushell");
config_path.push("config.nu");
// FIXME: remove this message when we're ready
println!("Loading config from: {:?}", config_path);
if config_path.exists() {
let config_filename = config_path.to_string_lossy().to_owned();
if let Ok(contents) = std::fs::read_to_string(&config_path) {
eval_source(engine_state.clone(), &stack, &contents, &config_filename);
}
}
}
loop { loop {
let prompt = update_prompt( let prompt = update_prompt(
PROMPT_COMMAND, PROMPT_COMMAND,
@ -124,45 +141,12 @@ fn main() -> Result<()> {
continue; continue;
} }
let (block, delta) = { eval_source(
let engine_state = engine_state.borrow(); engine_state.clone(),
let mut working_set = StateWorkingSet::new(&*engine_state); &stack,
let (output, err) = parse( &s,
&mut working_set, &format!("entry #{}", entry_num),
Some(&format!("entry #{}", entry_num)), );
s.as_bytes(),
false,
);
if let Some(err) = err {
report_error(&working_set, &err);
continue;
}
(output, working_set.render())
};
EngineState::merge_delta(&mut *engine_state.borrow_mut(), delta);
let state = nu_protocol::engine::EvaluationContext {
engine_state: engine_state.clone(),
stack: stack.clone(),
};
match eval_block(&state, &block, Value::nothing()) {
Ok(value) => {
if let Err(err) = print_value(value, &state) {
let engine_state = engine_state.borrow();
let working_set = StateWorkingSet::new(&*engine_state);
report_error(&working_set, &err);
}
}
Err(err) => {
let engine_state = engine_state.borrow();
let working_set = StateWorkingSet::new(&*engine_state);
report_error(&working_set, &err);
}
}
} }
Ok(Signal::CtrlC) => { Ok(Signal::CtrlC) => {
println!("Ctrl-c"); println!("Ctrl-c");
@ -267,3 +251,54 @@ fn update_prompt<'prompt>(
nu_prompt as &dyn Prompt nu_prompt as &dyn Prompt
} }
fn eval_source(
engine_state: Rc<RefCell<EngineState>>,
stack: &Stack,
source: &str,
fname: &str,
) -> bool {
let (block, delta) = {
let engine_state = engine_state.borrow();
let mut working_set = StateWorkingSet::new(&*engine_state);
let (output, err) = parse(
&mut working_set,
Some(fname), // format!("entry #{}", entry_num)
source.as_bytes(),
false,
);
if let Some(err) = err {
report_error(&working_set, &err);
return false;
}
(output, working_set.render())
};
EngineState::merge_delta(&mut *engine_state.borrow_mut(), delta);
let state = nu_protocol::engine::EvaluationContext {
engine_state: engine_state.clone(),
stack: stack.clone(),
};
match eval_block(&state, &block, Value::nothing()) {
Ok(value) => {
if let Err(err) = print_value(value, &state) {
let engine_state = engine_state.borrow();
let working_set = StateWorkingSet::new(&*engine_state);
report_error(&working_set, &err);
return false;
}
}
Err(err) => {
let engine_state = engine_state.borrow();
let working_set = StateWorkingSet::new(&*engine_state);
report_error(&working_set, &err);
return false;
}
}
true
}