mirror of
https://github.com/nushell/nushell.git
synced 2025-01-11 00:38:23 +01:00
begin aliases
This commit is contained in:
parent
38fef28c84
commit
bf19918e3c
@ -359,6 +359,8 @@ fn eval_call(state: &State, stack: Stack, call: &Call) -> Result<Value, ShellErr
|
||||
Ok(Value::Nothing { span: call.head })
|
||||
} else if decl.signature.name == "def" {
|
||||
Ok(Value::Nothing { span: call.head })
|
||||
} else if decl.signature.name == "alias" {
|
||||
Ok(Value::Nothing { span: call.head })
|
||||
} else {
|
||||
Err(ShellError::Unsupported(call.head))
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ fn main() -> std::io::Result<()> {
|
||||
working_set.add_decl(sig.into());
|
||||
|
||||
let sig = Signature::build("alias")
|
||||
.required("var_name", SyntaxShape::Variable, "variable name")
|
||||
.required("name", SyntaxShape::String, "name of the alias")
|
||||
.required(
|
||||
"initial_value",
|
||||
SyntaxShape::Keyword(b"=".to_vec(), Box::new(SyntaxShape::Expression)),
|
||||
|
@ -782,13 +782,17 @@ impl<'a> ParserWorkingSet<'a> {
|
||||
(Box::new(call), span(spans), error)
|
||||
}
|
||||
|
||||
pub fn parse_call(&mut self, spans: &[Span]) -> (Expression, Option<ParseError>) {
|
||||
pub fn parse_call(
|
||||
&mut self,
|
||||
spans: &[Span],
|
||||
expand_aliases: bool,
|
||||
) -> (Expression, Option<ParseError>) {
|
||||
// assume spans.len() > 0?
|
||||
let mut pos = 0;
|
||||
let mut shorthand = vec![];
|
||||
|
||||
while pos < spans.len() {
|
||||
// First, check if there is any environment shorthand
|
||||
// Check if there is any environment shorthand
|
||||
let name = self.get_span_contents(spans[pos]);
|
||||
let split: Vec<_> = name.splitn(2, |x| *x == b'=').collect();
|
||||
if split.len() == 2 {
|
||||
@ -807,6 +811,21 @@ impl<'a> ParserWorkingSet<'a> {
|
||||
}
|
||||
|
||||
let name = self.get_span_contents(spans[pos]);
|
||||
|
||||
if expand_aliases {
|
||||
if let Some(expansion) = self.find_alias(name) {
|
||||
//let mut spans = spans.to_vec();
|
||||
let mut new_spans: Vec<Span> = vec![];
|
||||
new_spans.extend(&spans[0..pos]);
|
||||
new_spans.extend(expansion);
|
||||
if spans.len() > pos {
|
||||
new_spans.extend(&spans[(pos + 1)..]);
|
||||
}
|
||||
|
||||
return self.parse_call(&new_spans, false);
|
||||
}
|
||||
}
|
||||
|
||||
pos += 1;
|
||||
|
||||
if let Some(mut decl_id) = self.find_decl(name) {
|
||||
@ -2115,7 +2134,7 @@ impl<'a> ParserWorkingSet<'a> {
|
||||
match bytes[0] {
|
||||
b'0' | b'1' | b'2' | b'3' | b'4' | b'5' | b'6' | b'7' | b'8' | b'9' | b'(' | b'{'
|
||||
| b'[' | b'$' | b'"' | b'\'' => self.parse_math_expression(spans),
|
||||
_ => self.parse_call(spans),
|
||||
_ => self.parse_call(spans, true),
|
||||
}
|
||||
}
|
||||
|
||||
@ -2234,6 +2253,30 @@ impl<'a> ParserWorkingSet<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse_alias(&mut self, spans: &[Span]) -> (Statement, Option<ParseError>) {
|
||||
let name = self.get_span_contents(spans[0]);
|
||||
|
||||
if name == b"alias" && spans.len() >= 4 {
|
||||
let alias_name = self.get_span_contents(spans[1]).to_vec();
|
||||
let _equals = self.get_span_contents(spans[2]);
|
||||
|
||||
let replacement = spans[3..].to_vec();
|
||||
|
||||
self.add_alias(alias_name, replacement);
|
||||
}
|
||||
(
|
||||
Statement::Expression(Expression {
|
||||
expr: Expr::Garbage,
|
||||
span: span(spans),
|
||||
ty: Type::Unknown,
|
||||
}),
|
||||
Some(ParseError::UnknownState(
|
||||
"internal error: let statement unparseable".into(),
|
||||
span(spans),
|
||||
)),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn parse_let(&mut self, spans: &[Span]) -> (Statement, Option<ParseError>) {
|
||||
let name = self.get_span_contents(spans[0]);
|
||||
|
||||
@ -2271,6 +2314,8 @@ impl<'a> ParserWorkingSet<'a> {
|
||||
(decl, None)
|
||||
} else if let (stmt, None) = self.parse_let(spans) {
|
||||
(stmt, None)
|
||||
} else if let (stmt, None) = self.parse_alias(spans) {
|
||||
(stmt, None)
|
||||
} else {
|
||||
let (expr, err) = self.parse_expression(spans);
|
||||
(Statement::Expression(expr), err)
|
||||
|
@ -36,6 +36,7 @@ pub type BlockId = usize;
|
||||
struct ScopeFrame {
|
||||
vars: HashMap<Vec<u8>, VarId>,
|
||||
decls: HashMap<Vec<u8>, DeclId>,
|
||||
aliases: HashMap<Vec<u8>, Vec<Span>>,
|
||||
}
|
||||
|
||||
impl ScopeFrame {
|
||||
@ -43,6 +44,7 @@ impl ScopeFrame {
|
||||
Self {
|
||||
vars: HashMap::new(),
|
||||
decls: HashMap::new(),
|
||||
aliases: HashMap::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -352,6 +354,22 @@ impl<'a> ParserWorkingSet<'a> {
|
||||
None
|
||||
}
|
||||
|
||||
pub fn find_alias(&self, name: &[u8]) -> Option<&[Span]> {
|
||||
for scope in self.delta.scope.iter().rev() {
|
||||
if let Some(spans) = scope.aliases.get(name) {
|
||||
return Some(spans);
|
||||
}
|
||||
}
|
||||
|
||||
for scope in self.permanent_state.scope.iter().rev() {
|
||||
if let Some(spans) = scope.aliases.get(name) {
|
||||
return Some(spans);
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
pub fn add_variable(&mut self, mut name: Vec<u8>, ty: Type) -> VarId {
|
||||
let next_id = self.next_var_id();
|
||||
|
||||
@ -373,6 +391,16 @@ impl<'a> ParserWorkingSet<'a> {
|
||||
next_id
|
||||
}
|
||||
|
||||
pub fn add_alias(&mut self, name: Vec<u8>, replacement: Vec<Span>) {
|
||||
let last = self
|
||||
.delta
|
||||
.scope
|
||||
.last_mut()
|
||||
.expect("internal error: missing stack frame");
|
||||
|
||||
last.aliases.insert(name, replacement);
|
||||
}
|
||||
|
||||
pub fn set_variable_type(&mut self, var_id: VarId, ty: Type) {
|
||||
let num_permanent_vars = self.permanent_state.num_vars();
|
||||
if var_id < num_permanent_vars {
|
||||
|
Loading…
Reference in New Issue
Block a user