mirror of
https://github.com/nushell/nushell
synced 2024-12-27 21:43:09 +00:00
Improve alias expansion, again (#4474)
This commit is contained in:
parent
fbaafaa459
commit
a743db8e8f
3 changed files with 133 additions and 21 deletions
|
@ -842,35 +842,21 @@ pub fn parse_call(
|
||||||
|
|
||||||
let expansion = working_set.get_alias(alias_id);
|
let expansion = working_set.get_alias(alias_id);
|
||||||
|
|
||||||
let orig_span = spans[pos];
|
let expansion_span = span(expansion);
|
||||||
|
|
||||||
|
let orig_span = span(&[spans[cmd_start], spans[pos]]);
|
||||||
let mut new_spans: Vec<Span> = vec![];
|
let mut new_spans: Vec<Span> = vec![];
|
||||||
new_spans.extend(&spans[0..pos]);
|
new_spans.extend(&spans[0..cmd_start]);
|
||||||
new_spans.extend(expansion);
|
new_spans.extend(expansion);
|
||||||
if spans.len() > pos {
|
if spans.len() > pos {
|
||||||
new_spans.extend(&spans[(pos + 1)..]);
|
new_spans.extend(&spans[(pos + 1)..]);
|
||||||
}
|
}
|
||||||
|
|
||||||
let (result, err) = parse_expression(working_set, &new_spans, false);
|
let (mut result, err) = parse_expression(working_set, &new_spans, false);
|
||||||
|
|
||||||
let expression = match result {
|
result.replace_span(working_set, expansion_span, orig_span);
|
||||||
Expression {
|
|
||||||
expr: Expr::Call(mut call),
|
|
||||||
span,
|
|
||||||
ty,
|
|
||||||
custom_completion,
|
|
||||||
} => {
|
|
||||||
call.head = orig_span;
|
|
||||||
Expression {
|
|
||||||
expr: Expr::Call(call),
|
|
||||||
span,
|
|
||||||
ty,
|
|
||||||
custom_completion,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
x => x,
|
|
||||||
};
|
|
||||||
|
|
||||||
return (expression, err);
|
return (result, err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -402,4 +402,126 @@ impl Expression {
|
||||||
Expr::VarDecl(_) => {}
|
Expr::VarDecl(_) => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn replace_span(
|
||||||
|
&mut self,
|
||||||
|
working_set: &mut StateWorkingSet,
|
||||||
|
replaced: Span,
|
||||||
|
new_span: Span,
|
||||||
|
) {
|
||||||
|
if replaced.contains_span(self.span) {
|
||||||
|
self.span = new_span;
|
||||||
|
}
|
||||||
|
match &mut self.expr {
|
||||||
|
Expr::BinaryOp(left, _, right) => {
|
||||||
|
left.replace_span(working_set, replaced, new_span);
|
||||||
|
right.replace_span(working_set, replaced, new_span);
|
||||||
|
}
|
||||||
|
Expr::Block(block_id) => {
|
||||||
|
let mut block = working_set.get_block(*block_id).clone();
|
||||||
|
|
||||||
|
for stmt in block.stmts.iter_mut() {
|
||||||
|
if let Statement::Pipeline(pipeline) = stmt {
|
||||||
|
for expr in pipeline.expressions.iter_mut() {
|
||||||
|
expr.replace_span(working_set, replaced, new_span)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*block_id = working_set.add_block(block);
|
||||||
|
}
|
||||||
|
Expr::Bool(_) => {}
|
||||||
|
Expr::Call(call) => {
|
||||||
|
if replaced.contains_span(call.head) {
|
||||||
|
call.head = new_span;
|
||||||
|
}
|
||||||
|
for positional in &mut call.positional {
|
||||||
|
positional.replace_span(working_set, replaced, new_span);
|
||||||
|
}
|
||||||
|
for named in &mut call.named {
|
||||||
|
if let Some(expr) = &mut named.1 {
|
||||||
|
expr.replace_span(working_set, replaced, new_span)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Expr::CellPath(_) => {}
|
||||||
|
Expr::ExternalCall(head, args) => {
|
||||||
|
head.replace_span(working_set, replaced, new_span);
|
||||||
|
for arg in args {
|
||||||
|
arg.replace_span(working_set, replaced, new_span)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Expr::Filepath(_) => {}
|
||||||
|
Expr::Float(_) => {}
|
||||||
|
Expr::FullCellPath(full_cell_path) => {
|
||||||
|
full_cell_path
|
||||||
|
.head
|
||||||
|
.replace_span(working_set, replaced, new_span);
|
||||||
|
}
|
||||||
|
Expr::ImportPattern(_) => {}
|
||||||
|
Expr::Garbage => {}
|
||||||
|
Expr::Nothing => {}
|
||||||
|
Expr::GlobPattern(_) => {}
|
||||||
|
Expr::Int(_) => {}
|
||||||
|
Expr::Keyword(_, _, expr) => expr.replace_span(working_set, replaced, new_span),
|
||||||
|
Expr::List(list) => {
|
||||||
|
for l in list {
|
||||||
|
l.replace_span(working_set, replaced, new_span)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Expr::Operator(_) => {}
|
||||||
|
Expr::Range(left, middle, right, ..) => {
|
||||||
|
if let Some(left) = left {
|
||||||
|
left.replace_span(working_set, replaced, new_span)
|
||||||
|
}
|
||||||
|
if let Some(middle) = middle {
|
||||||
|
middle.replace_span(working_set, replaced, new_span)
|
||||||
|
}
|
||||||
|
if let Some(right) = right {
|
||||||
|
right.replace_span(working_set, replaced, new_span)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Expr::Record(fields) => {
|
||||||
|
for (field_name, field_value) in fields {
|
||||||
|
field_name.replace_span(working_set, replaced, new_span);
|
||||||
|
field_value.replace_span(working_set, replaced, new_span);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Expr::Signature(_) => {}
|
||||||
|
Expr::String(_) => {}
|
||||||
|
Expr::StringInterpolation(items) => {
|
||||||
|
for i in items {
|
||||||
|
i.replace_span(working_set, replaced, new_span)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Expr::RowCondition(block_id) | Expr::Subexpression(block_id) => {
|
||||||
|
let mut block = working_set.get_block(*block_id).clone();
|
||||||
|
|
||||||
|
for stmt in block.stmts.iter_mut() {
|
||||||
|
if let Statement::Pipeline(pipeline) = stmt {
|
||||||
|
for expr in pipeline.expressions.iter_mut() {
|
||||||
|
expr.replace_span(working_set, replaced, new_span)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*block_id = working_set.add_block(block);
|
||||||
|
}
|
||||||
|
Expr::Table(headers, cells) => {
|
||||||
|
for header in headers {
|
||||||
|
header.replace_span(working_set, replaced, new_span)
|
||||||
|
}
|
||||||
|
|
||||||
|
for row in cells {
|
||||||
|
for cell in row.iter_mut() {
|
||||||
|
cell.replace_span(working_set, replaced, new_span)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Expr::ValueWithUnit(expr, _) => expr.replace_span(working_set, replaced, new_span),
|
||||||
|
Expr::Var(_) => {}
|
||||||
|
Expr::VarDecl(_) => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,10 @@ impl Span {
|
||||||
pos >= self.start && pos < self.end
|
pos >= self.start && pos < self.end
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn contains_span(&self, span: Span) -> bool {
|
||||||
|
span.start >= self.start && span.end <= self.end
|
||||||
|
}
|
||||||
|
|
||||||
/// Point to the space just past this span, useful for missing
|
/// Point to the space just past this span, useful for missing
|
||||||
/// values
|
/// values
|
||||||
pub fn past(&self) -> Span {
|
pub fn past(&self) -> Span {
|
||||||
|
|
Loading…
Reference in a new issue