mirror of
https://github.com/nushell/nushell.git
synced 2025-04-02 12:19:48 +02:00
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:
parent
52d69bb021
commit
b2fe5fabb1
@ -229,7 +229,11 @@ fn evaluate_reference(name: &str, ctx: &EvaluationContext, tag: Tag) -> Result<V
|
|||||||
match name {
|
match name {
|
||||||
"$nu" => crate::evaluate::variables::nu(&ctx.scope, tag, ctx),
|
"$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 {
|
"$true" => Ok(Value {
|
||||||
value: UntaggedValue::boolean(true),
|
value: UntaggedValue::boolean(true),
|
||||||
|
@ -2,7 +2,7 @@ use crate::whole_stream_command::{whole_stream_command, Command};
|
|||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_parser::ParserScope;
|
use nu_parser::ParserScope;
|
||||||
use nu_protocol::{hir::Block, Value};
|
use nu_protocol::{hir::Block, Signature, Value};
|
||||||
use nu_source::Spanned;
|
use nu_source::Spanned;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
@ -46,6 +46,18 @@ impl Scope {
|
|||||||
output
|
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>>>> {
|
pub fn get_aliases_with_name(&self, name: &str) -> Option<Vec<Vec<Spanned<String>>>> {
|
||||||
let aliases: Vec<_> = self
|
let aliases: Vec<_> = self
|
||||||
.frames
|
.frames
|
||||||
|
@ -2,7 +2,7 @@ use crate::{evaluate::scope::Scope, EvaluationContext};
|
|||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
use nu_data::config::path::{default_history_path, history_path};
|
use nu_data::config::path::{default_history_path, history_path};
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::{TaggedDictBuilder, UntaggedValue, Value};
|
use nu_protocol::{Signature, TaggedDictBuilder, UntaggedValue, Value};
|
||||||
use nu_source::{Spanned, Tag};
|
use nu_source::{Spanned, Tag};
|
||||||
|
|
||||||
pub fn nu(
|
pub fn nu(
|
||||||
@ -83,13 +83,14 @@ pub fn nu(
|
|||||||
|
|
||||||
pub fn scope(
|
pub fn scope(
|
||||||
aliases: &IndexMap<String, Vec<Spanned<String>>>,
|
aliases: &IndexMap<String, Vec<Spanned<String>>>,
|
||||||
|
commands: &IndexMap<String, Signature>,
|
||||||
tag: impl Into<Tag>,
|
tag: impl Into<Tag>,
|
||||||
) -> Result<Value, ShellError> {
|
) -> Result<Value, ShellError> {
|
||||||
let tag = tag.into();
|
let tag = tag.into();
|
||||||
|
|
||||||
let mut scope_dict = TaggedDictBuilder::new(&tag);
|
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() {
|
for v in aliases.iter() {
|
||||||
let values = v.1.clone();
|
let values = v.1.clone();
|
||||||
let mut vec = Vec::new();
|
let mut vec = Vec::new();
|
||||||
@ -99,9 +100,18 @@ pub fn scope(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let alias = vec.join(" ");
|
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())
|
Ok(scope_dict.into_value())
|
||||||
}
|
}
|
||||||
|
@ -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")
|
||||||
|
);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user