Add commands to scope variable (#3272)

* Add commands to scope variable

* List commands with signature on scope variables

Usage:

```shell
echo $scope.commands | pivot
```

* Run rust formater

* Update variables.rs

Co-authored-by: Jonathan Turner <jonathandturner@users.noreply.github.com>
This commit is contained in:
Steven Barragán 2021-04-11 19:38:47 -07:00 committed by GitHub
parent 52d69bb021
commit b2fe5fabb1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 50 additions and 6 deletions

View File

@ -229,7 +229,11 @@ fn evaluate_reference(name: &str, ctx: &EvaluationContext, tag: Tag) -> Result<V
match name {
"$nu" => crate::evaluate::variables::nu(&ctx.scope, tag, ctx),
"$scope" => crate::evaluate::variables::scope(&ctx.scope.get_aliases(), tag),
"$scope" => crate::evaluate::variables::scope(
&ctx.scope.get_aliases(),
&ctx.scope.get_commands(),
tag,
),
"$true" => Ok(Value {
value: UntaggedValue::boolean(true),

View File

@ -2,7 +2,7 @@ use crate::whole_stream_command::{whole_stream_command, Command};
use indexmap::IndexMap;
use nu_errors::ShellError;
use nu_parser::ParserScope;
use nu_protocol::{hir::Block, Value};
use nu_protocol::{hir::Block, Signature, Value};
use nu_source::Spanned;
use std::sync::Arc;
@ -46,6 +46,18 @@ impl Scope {
output
}
pub fn get_commands(&self) -> IndexMap<String, Signature> {
let mut output = IndexMap::new();
for frame in self.frames.lock().iter().rev() {
for (name, command) in frame.commands.iter() {
output.insert(name.clone(), command.signature());
}
}
output
}
pub fn get_aliases_with_name(&self, name: &str) -> Option<Vec<Vec<Spanned<String>>>> {
let aliases: Vec<_> = self
.frames

View File

@ -2,7 +2,7 @@ use crate::{evaluate::scope::Scope, EvaluationContext};
use indexmap::IndexMap;
use nu_data::config::path::{default_history_path, history_path};
use nu_errors::ShellError;
use nu_protocol::{TaggedDictBuilder, UntaggedValue, Value};
use nu_protocol::{Signature, TaggedDictBuilder, UntaggedValue, Value};
use nu_source::{Spanned, Tag};
pub fn nu(
@ -83,13 +83,14 @@ pub fn nu(
pub fn scope(
aliases: &IndexMap<String, Vec<Spanned<String>>>,
commands: &IndexMap<String, Signature>,
tag: impl Into<Tag>,
) -> Result<Value, ShellError> {
let tag = tag.into();
let mut scope_dict = TaggedDictBuilder::new(&tag);
let mut dict = TaggedDictBuilder::new(&tag);
let mut aliases_dict = TaggedDictBuilder::new(&tag);
for v in aliases.iter() {
let values = v.1.clone();
let mut vec = Vec::new();
@ -99,9 +100,18 @@ pub fn scope(
}
let alias = vec.join(" ");
dict.insert_untagged(v.0, UntaggedValue::string(alias));
aliases_dict.insert_untagged(v.0, UntaggedValue::string(alias));
}
scope_dict.insert_value("aliases", dict.into_value());
let mut commands_dict = TaggedDictBuilder::new(&tag);
for (name, signature) in commands.iter() {
commands_dict.insert_untagged(name, UntaggedValue::string(&signature.allowed().join(" ")))
}
scope_dict.insert_value("aliases", aliases_dict.into_value());
scope_dict.insert_value("commands", commands_dict.into_value());
Ok(scope_dict.into_value())
}

View File

@ -68,3 +68,21 @@ fn scope_variable_with_correct_number_of_aliases_present() {
);
})
}
#[test]
fn scope_variable_with_command_present() {
Playground::setup("scope_commands_test_1", |dirs, nu| {
let file = AbsolutePath::new(dirs.test().join("config.toml"));
nu.with_config(&file);
nu.with_files(vec![FileWithContent(
"config.toml",
"skip_welcome_message = true",
)]);
assert_that!(
nu.pipeline("def meaning-of-life [--number: int] { echo $number }; echo $scope.commands | get meaning-of-life"),
says().to_stdout("-h --help --number")
);
})
}