mirror of
https://github.com/nushell/nushell.git
synced 2025-04-13 07:48:19 +02:00
Add the ability to remove and list aliases (#3879)
* Add the ability to remove and list aliases * Fix failing unit tests * Add a test to check unalias shadowing blocks
This commit is contained in:
parent
2b7390c2a1
commit
9bd408449e
@ -2,7 +2,7 @@ use crate::prelude::*;
|
|||||||
use nu_engine::WholeStreamCommand;
|
use nu_engine::WholeStreamCommand;
|
||||||
|
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::{Signature, SyntaxShape};
|
use nu_protocol::{Signature, SyntaxShape, UntaggedValue};
|
||||||
|
|
||||||
pub struct Alias;
|
pub struct Alias;
|
||||||
|
|
||||||
@ -35,6 +35,18 @@ impl WholeStreamCommand for Alias {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alias(_: CommandArgs) -> Result<OutputStream, ShellError> {
|
pub fn alias(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
|
// TODO: is there a better way of checking whether no arguments were passed?
|
||||||
|
if args.nth(0).is_none() {
|
||||||
|
let aliases = UntaggedValue::string(
|
||||||
|
&args
|
||||||
|
.scope()
|
||||||
|
.get_aliases()
|
||||||
|
.iter()
|
||||||
|
.map(|val| format!("{} = '{}'", val.0, val.1.iter().map(|x| &x.item).join(" ")))
|
||||||
|
.join("\n"),
|
||||||
|
);
|
||||||
|
return Ok(OutputStream::one(aliases));
|
||||||
|
}
|
||||||
Ok(OutputStream::empty())
|
Ok(OutputStream::empty())
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ mod nu_plugin;
|
|||||||
mod nu_signature;
|
mod nu_signature;
|
||||||
mod source;
|
mod source;
|
||||||
mod tags;
|
mod tags;
|
||||||
|
mod unalias;
|
||||||
mod version;
|
mod version;
|
||||||
|
|
||||||
pub use self::nu_plugin::SubCommand as NuPlugin;
|
pub use self::nu_plugin::SubCommand as NuPlugin;
|
||||||
@ -32,4 +33,5 @@ pub use ignore::Ignore;
|
|||||||
pub use let_::Let;
|
pub use let_::Let;
|
||||||
pub use source::Source;
|
pub use source::Source;
|
||||||
pub use tags::Tags;
|
pub use tags::Tags;
|
||||||
|
pub use unalias::Unalias;
|
||||||
pub use version::{version, Version};
|
pub use version::{version, Version};
|
||||||
|
37
crates/nu-command/src/commands/core_commands/unalias.rs
Normal file
37
crates/nu-command/src/commands/core_commands/unalias.rs
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
use crate::prelude::*;
|
||||||
|
use nu_engine::WholeStreamCommand;
|
||||||
|
|
||||||
|
use nu_errors::ShellError;
|
||||||
|
use nu_protocol::{Signature, SyntaxShape};
|
||||||
|
|
||||||
|
pub struct Unalias;
|
||||||
|
|
||||||
|
impl WholeStreamCommand for Unalias {
|
||||||
|
fn name(&self) -> &str {
|
||||||
|
"unalias"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn signature(&self) -> Signature {
|
||||||
|
Signature::build("unalias").required("name", SyntaxShape::String, "the name of the alias")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn usage(&self) -> &str {
|
||||||
|
"Removes an alias"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
|
unalias(args)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn examples(&self) -> Vec<Example> {
|
||||||
|
vec![Example {
|
||||||
|
description: "Remove the 'v' alias",
|
||||||
|
example: "unalias v",
|
||||||
|
result: None,
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn unalias(_: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
|
Ok(OutputStream::empty())
|
||||||
|
}
|
@ -18,6 +18,7 @@ pub fn create_default_context(interactive: bool) -> Result<EvaluationContext, Bo
|
|||||||
whole_stream_command(Def),
|
whole_stream_command(Def),
|
||||||
whole_stream_command(Source),
|
whole_stream_command(Source),
|
||||||
whole_stream_command(Alias),
|
whole_stream_command(Alias),
|
||||||
|
whole_stream_command(Unalias),
|
||||||
whole_stream_command(Ignore),
|
whole_stream_command(Ignore),
|
||||||
// System/file operations
|
// System/file operations
|
||||||
whole_stream_command(Exec),
|
whole_stream_command(Exec),
|
||||||
|
@ -317,6 +317,10 @@ mod tests {
|
|||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn remove_alias(&self, _name: &str) {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
fn add_definition(&self, _block: Arc<Block>) {}
|
fn add_definition(&self, _block: Arc<Block>) {}
|
||||||
|
|
||||||
fn get_definitions(&self) -> Vec<Arc<Block>> {
|
fn get_definitions(&self) -> Vec<Arc<Block>> {
|
||||||
|
@ -407,6 +407,12 @@ impl ParserScope for Scope {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn remove_alias(&self, name: &str) {
|
||||||
|
for frame in self.frames.lock().iter_mut().rev() {
|
||||||
|
frame.aliases.remove(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn enter_scope(&self) {
|
fn enter_scope(&self) {
|
||||||
self.frames.lock().push(ScopeFrame::new());
|
self.frames.lock().push(ScopeFrame::new());
|
||||||
}
|
}
|
||||||
|
@ -1902,7 +1902,7 @@ fn parse_call(
|
|||||||
)),
|
)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else if lite_cmd.parts[0].item == "alias" {
|
} else if lite_cmd.parts[0].item == "alias" || lite_cmd.parts[0].item == "unalias" {
|
||||||
let error = parse_alias(&lite_cmd, scope);
|
let error = parse_alias(&lite_cmd, scope);
|
||||||
if error.is_none() {
|
if error.is_none() {
|
||||||
return (Some(ClassifiedCommand::Internal(internal_command)), None);
|
return (Some(ClassifiedCommand::Internal(internal_command)), None);
|
||||||
@ -2048,26 +2048,41 @@ fn expand_shorthand_forms(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn parse_alias(call: &LiteCommand, scope: &dyn ParserScope) -> Option<ParseError> {
|
fn parse_alias(call: &LiteCommand, scope: &dyn ParserScope) -> Option<ParseError> {
|
||||||
if call.parts.len() == 2 && (call.parts[1].item == "--help" || (call.parts[1].item == "-h")) {
|
if call.parts[0].item == "alias" {
|
||||||
return None;
|
if (call.parts.len() == 1)
|
||||||
}
|
|| (call.parts.len() == 2
|
||||||
|
&& (call.parts[1].item == "--help" || (call.parts[1].item == "-h")))
|
||||||
|
{
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
if call.parts.len() < 4 {
|
||||||
|
return Some(ParseError::mismatch("alias", call.parts[0].clone()));
|
||||||
|
}
|
||||||
|
|
||||||
if call.parts.len() < 4 {
|
if call.parts[0].item != "alias" {
|
||||||
return Some(ParseError::mismatch("alias", call.parts[0].clone()));
|
return Some(ParseError::mismatch("alias", call.parts[0].clone()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if call.parts[0].item != "alias" {
|
if call.parts[2].item != "=" {
|
||||||
return Some(ParseError::mismatch("alias", call.parts[0].clone()));
|
return Some(ParseError::mismatch("=", call.parts[2].clone()));
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
if call.parts[2].item != "=" {
|
// unalias
|
||||||
return Some(ParseError::mismatch("=", call.parts[2].clone()));
|
if call.parts.len() != 2 {
|
||||||
|
return Some(ParseError::mismatch("unalias", call.parts[0].clone()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let name = call.parts[1].item.clone();
|
let name = call.parts[1].item.clone();
|
||||||
let args: Vec<_> = call.parts.iter().skip(3).cloned().collect();
|
let args: Vec<_> = call.parts.iter().skip(3).cloned().collect();
|
||||||
|
|
||||||
scope.add_alias(&name, args);
|
match call.parts[0].item.as_str() {
|
||||||
|
"alias" => scope.add_alias(&name, args),
|
||||||
|
"unalias" => {
|
||||||
|
scope.remove_alias(&name);
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,8 @@ pub trait ParserScope: Debug {
|
|||||||
|
|
||||||
fn get_alias(&self, name: &str) -> Option<Vec<Spanned<String>>>;
|
fn get_alias(&self, name: &str) -> Option<Vec<Spanned<String>>>;
|
||||||
|
|
||||||
|
fn remove_alias(&self, name: &str);
|
||||||
|
|
||||||
fn add_alias(&self, name: &str, replacement: Vec<Spanned<String>>);
|
fn add_alias(&self, name: &str, replacement: Vec<Spanned<String>>);
|
||||||
|
|
||||||
fn enter_scope(&self);
|
fn enter_scope(&self);
|
||||||
|
@ -1145,6 +1145,21 @@ fn nothing_string_2() {
|
|||||||
assert_eq!(actual.out, "true");
|
assert_eq!(actual.out, "true");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn unalias_shadowing() {
|
||||||
|
let actual = nu!(
|
||||||
|
cwd: ".", pipeline(
|
||||||
|
r#"
|
||||||
|
alias ll = ls -l
|
||||||
|
let xyz = { ll -a }
|
||||||
|
unalias ll
|
||||||
|
do $xyz
|
||||||
|
"#)
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(actual.out, "");
|
||||||
|
}
|
||||||
|
|
||||||
mod parse {
|
mod parse {
|
||||||
use nu_test_support::nu;
|
use nu_test_support::nu;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user