diff --git a/crates/nu-cli/src/util.rs b/crates/nu-cli/src/util.rs index e4912e012f..2fc7a8dd11 100644 --- a/crates/nu-cli/src/util.rs +++ b/crates/nu-cli/src/util.rs @@ -304,13 +304,15 @@ mod test { #[test] fn test_gather_env_vars() { let mut engine_state = EngineState::new(); - let symbols = r##" !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~"##; + let symbols = r##" !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~"##.to_string(); + let foo_key = "FOO".to_string(); + let symbols_key = "SYMBOLS".to_string(); gather_env_vars( [ - ("FOO".into(), "foo".into()), - ("SYMBOLS".into(), symbols.into()), - (symbols.into(), "symbols".into()), + (foo_key.clone(), "foo".into()), + (symbols_key.clone(), symbols.into()), + (symbols.clone()(), "symbols".into()), ] .into_iter(), &mut engine_state, @@ -319,16 +321,12 @@ mod test { let env = engine_state.render_env_vars(); + assert!(matches!(env.get(&foo_key), Some(&Value::String { val, .. }) if val == "foo")); assert!( - matches!(env.get(&"FOO".to_string()), Some(&Value::String { val, .. }) if val == "foo") + matches!(env.get(&symbols_key), Some(&Value::String { val, .. }) if val == symbols) ); - assert!( - matches!(env.get(&"SYMBOLS".to_string()), Some(&Value::String { val, .. }) if val == symbols) - ); - assert!( - matches!(env.get(&symbols.to_string()), Some(&Value::String { val, .. }) if val == "symbols") - ); - assert!(env.get(&"PWD".to_string()).is_some()); + assert!(matches!(env.get(&symbols), Some(&Value::String { val, .. }) if val == "symbols")); + assert!(env.get(&"PWD").is_some()); assert_eq!(env.len(), 4); } } diff --git a/crates/nu-parser/src/parse_keywords.rs b/crates/nu-parser/src/parse_keywords.rs index 2849b4e39c..9ecc6a9675 100644 --- a/crates/nu-parser/src/parse_keywords.rs +++ b/crates/nu-parser/src/parse_keywords.rs @@ -1192,7 +1192,7 @@ pub fn parse_export_in_block( "export alias" => parse_alias(working_set, lite_command, None), "export def" => parse_def(working_set, lite_command, None).0, "export const" => parse_const(working_set, &lite_command.parts[1..]), - "export use" => parse_use(working_set, lite_command).0, + "export use" => parse_use(working_set, lite_command, None).0, "export module" => parse_module(working_set, lite_command, None).0, "export extern" => parse_extern(working_set, lite_command, None), _ => { @@ -1759,7 +1759,7 @@ pub fn parse_module_block( )) } b"use" => { - let (pipeline, _) = parse_use(working_set, command); + let (pipeline, _) = parse_use(working_set, command, Some(&mut module)); block.pipelines.push(pipeline) } @@ -2228,6 +2228,7 @@ pub fn parse_module( pub fn parse_use( working_set: &mut StateWorkingSet, lite_command: &LiteCommand, + user_module: Option<&mut Module>, ) -> (Pipeline, Vec) { let spans = &lite_command.parts; @@ -2420,6 +2421,16 @@ pub fn parse_use( import_pattern.constants = constants.iter().map(|(_, id)| *id).collect(); + if let Some(m) = user_module { + m.add_usage_modules( + definitions + .modules + .iter() + .map(|(_, id)| *id) + .collect::>() + .as_slice(), + ) + } // Extend the current scope with the module's exportables working_set.use_decls(definitions.decls); working_set.use_modules(definitions.modules); diff --git a/crates/nu-parser/src/parser.rs b/crates/nu-parser/src/parser.rs index 149bce8958..034ae567cb 100644 --- a/crates/nu-parser/src/parser.rs +++ b/crates/nu-parser/src/parser.rs @@ -5219,7 +5219,7 @@ pub fn parse_builtin_commands( } b"alias" => parse_alias(working_set, lite_command, None), b"module" => parse_module(working_set, lite_command, None).0, - b"use" => parse_use(working_set, lite_command).0, + b"use" => parse_use(working_set, lite_command, None).0, b"overlay" => { if let Some(redirection) = lite_command.redirection.as_ref() { working_set.error(redirecting_builtin_error("overlay", redirection)); diff --git a/crates/nu-protocol/src/module.rs b/crates/nu-protocol/src/module.rs index ebb6f5621e..2a5ef737ea 100644 --- a/crates/nu-protocol/src/module.rs +++ b/crates/nu-protocol/src/module.rs @@ -2,6 +2,7 @@ use crate::{ ast::ImportPatternMember, engine::StateWorkingSet, BlockId, DeclId, ModuleId, ParseError, Span, Value, VarId, }; +use std::path::PathBuf; use indexmap::IndexMap; @@ -35,6 +36,8 @@ pub struct Module { pub env_block: Option, // `export-env { ... }` block pub main: Option, // `export def main` pub span: Option, + pub use_modules: Vec, + pub file: Option, } impl Module { @@ -47,6 +50,8 @@ impl Module { env_block: None, main: None, span: None, + use_modules: vec![], + file: None, } } @@ -59,6 +64,8 @@ impl Module { env_block: None, main: None, span: Some(span), + use_modules: vec![], + file: None, } } @@ -82,6 +89,12 @@ impl Module { self.env_block = Some(block_id); } + pub fn add_usage_modules(&mut self, module_id: &[ModuleId]) { + for m in module_id { + self.use_modules.push(*m) + } + } + pub fn has_decl(&self, name: &[u8]) -> bool { if name == self.name && self.main.is_some() { return true;