nu_cmd_lang/core_commands/scope/
variables.rs1use nu_engine::{command_prelude::*, scope::ScopeData};
2
3#[derive(Clone)]
4pub struct ScopeVariables;
5
6impl Command for ScopeVariables {
7 fn name(&self) -> &str {
8 "scope variables"
9 }
10
11 fn signature(&self) -> Signature {
12 Signature::build("scope variables")
13 .input_output_types(vec![(Type::Nothing, Type::Any)])
14 .allow_variants_without_examples(true)
15 .category(Category::Core)
16 }
17
18 fn description(&self) -> &str {
19 "Output info on the variables in the current scope."
20 }
21
22 fn extra_description(&self) -> &str {
23 "Lists variables that are available at runtime in the current stack and active overlays \
24(locals and globals). Nested scopes such as `do`, `if`/`for` bodies, and custom commands include \
25their locals while that scope is active; outer locals remain visible when the outer frame is still \
26on the stack.
27
28Closures only capture free variables that are referenced in the closure body. An outer local that \
29is never mentioned is not captured, so after the defining scope ends it will not appear in \
30`scope variables` when that closure runs. Mentioning the variable (for example `$a`) causes it to \
31be captured and listed.
32
33For example, this shows `$a` inside the `do` block, but not when the returned closure runs later:
34
35 do {
36 let a = 123
37 scope variables | where name == '$a' | print
38 {|| scope variables | where name == '$a' }
39 } | let factory
40 do $factory
41
42Adding a reference to `$a` in the closure body captures it so it appears:
43
44 {|| $a; scope variables | where name == '$a' }"
45 }
46
47 fn run(
48 &self,
49 engine_state: &EngineState,
50 stack: &mut Stack,
51 call: &Call,
52 _input: PipelineData,
53 ) -> Result<PipelineData, ShellError> {
54 let head = call.head;
55 let mut scope_data = ScopeData::new(engine_state, stack);
56 scope_data.populate_vars();
57 Ok(Value::list(scope_data.collect_vars(head), head).into_pipeline_data())
58 }
59
60 fn examples(&self) -> Vec<Example<'_>> {
61 vec![Example {
62 description: "Show the variables in the current scope.",
63 example: "scope variables",
64 result: None,
65 }]
66 }
67}
68
69#[cfg(test)]
70mod test {
71 use super::*;
72
73 #[test]
74 fn test_examples() -> nu_test_support::Result {
75 nu_test_support::test().examples(ScopeVariables)
76 }
77}