mirror of
https://github.com/nushell/nushell
synced 2024-12-27 13:33:16 +00:00
Allow bare words to interpolate (#5327)
* Allow bare words to interpolate * fix highlighting
This commit is contained in:
parent
190f379ff3
commit
3492d4015d
3 changed files with 49 additions and 23 deletions
|
@ -326,23 +326,33 @@ pub fn flatten_expression(
|
|||
output
|
||||
}
|
||||
Expr::StringInterpolation(exprs) => {
|
||||
let mut output = vec![(
|
||||
Span {
|
||||
start: expr.span.start,
|
||||
end: expr.span.start + 2,
|
||||
},
|
||||
FlatShape::StringInterpolation,
|
||||
)];
|
||||
let mut output = vec![];
|
||||
for expr in exprs {
|
||||
output.extend(flatten_expression(working_set, expr));
|
||||
}
|
||||
output.push((
|
||||
Span {
|
||||
start: expr.span.end - 1,
|
||||
end: expr.span.end,
|
||||
},
|
||||
FlatShape::StringInterpolation,
|
||||
));
|
||||
|
||||
if let Some(first) = output.first() {
|
||||
if first.0.start != expr.span.start {
|
||||
// If we aren't a bare word interpolation, also highlight the outer quotes
|
||||
output.insert(
|
||||
0,
|
||||
(
|
||||
Span {
|
||||
start: expr.span.start,
|
||||
end: expr.span.start + 2,
|
||||
},
|
||||
FlatShape::StringInterpolation,
|
||||
),
|
||||
);
|
||||
output.push((
|
||||
Span {
|
||||
start: expr.span.end - 1,
|
||||
end: expr.span.end,
|
||||
},
|
||||
FlatShape::StringInterpolation,
|
||||
));
|
||||
}
|
||||
}
|
||||
output
|
||||
}
|
||||
Expr::Record(list) => {
|
||||
|
|
|
@ -41,7 +41,7 @@ pub fn parse_def_predecl(
|
|||
};
|
||||
|
||||
if (name == b"def" || name == b"def-env") && spans.len() >= 4 {
|
||||
let (name_expr, ..) = parse_string(working_set, spans[1]);
|
||||
let (name_expr, ..) = parse_string(working_set, spans[1], expand_aliases_denylist);
|
||||
let name = name_expr.as_string();
|
||||
|
||||
working_set.enter_scope();
|
||||
|
@ -64,7 +64,7 @@ pub fn parse_def_predecl(
|
|||
}
|
||||
}
|
||||
} else if name == b"extern" && spans.len() == 3 {
|
||||
let (name_expr, ..) = parse_string(working_set, spans[1]);
|
||||
let (name_expr, ..) = parse_string(working_set, spans[1], expand_aliases_denylist);
|
||||
let name = name_expr.as_string();
|
||||
|
||||
working_set.enter_scope();
|
||||
|
@ -892,7 +892,8 @@ pub fn parse_export(
|
|||
call.head = span(&spans[0..=1]);
|
||||
|
||||
if let Some(name_span) = spans.get(2) {
|
||||
let (name_expr, err) = parse_string(working_set, *name_span);
|
||||
let (name_expr, err) =
|
||||
parse_string(working_set, *name_span, expand_aliases_denylist);
|
||||
error = error.or(err);
|
||||
call.add_positional(name_expr);
|
||||
|
||||
|
@ -1132,7 +1133,7 @@ pub fn parse_module(
|
|||
let bytes = working_set.get_span_contents(spans[0]);
|
||||
|
||||
if bytes == b"module" && spans.len() >= 3 {
|
||||
let (module_name_expr, err) = parse_string(working_set, spans[1]);
|
||||
let (module_name_expr, err) = parse_string(working_set, spans[1], expand_aliases_denylist);
|
||||
error = error.or(err);
|
||||
|
||||
let module_name = module_name_expr
|
||||
|
@ -1524,7 +1525,7 @@ pub fn parse_hide(
|
|||
|
||||
if bytes == b"hide" && spans.len() >= 2 {
|
||||
for span in spans[1..].iter() {
|
||||
let (_, err) = parse_string(working_set, *span);
|
||||
let (_, err) = parse_string(working_set, *span, expand_aliases_denylist);
|
||||
error = error.or(err);
|
||||
}
|
||||
|
||||
|
|
|
@ -1726,6 +1726,7 @@ pub fn parse_cell_path(
|
|||
working_set: &mut StateWorkingSet,
|
||||
tokens: impl Iterator<Item = Token>,
|
||||
mut expect_dot: bool,
|
||||
expand_aliases_denylist: &[usize],
|
||||
span: Span,
|
||||
) -> (Vec<PathMember>, Option<ParseError>) {
|
||||
let mut error = None;
|
||||
|
@ -1755,7 +1756,8 @@ pub fn parse_cell_path(
|
|||
span,
|
||||
}),
|
||||
_ => {
|
||||
let (result, err) = parse_string(working_set, path_element.span);
|
||||
let (result, err) =
|
||||
parse_string(working_set, path_element.span, expand_aliases_denylist);
|
||||
error = error.or(err);
|
||||
match result {
|
||||
Expression {
|
||||
|
@ -1885,7 +1887,13 @@ pub fn parse_full_cell_path(
|
|||
);
|
||||
};
|
||||
|
||||
let (tail, err) = parse_cell_path(working_set, tokens, expect_dot, span);
|
||||
let (tail, err) = parse_cell_path(
|
||||
working_set,
|
||||
tokens,
|
||||
expect_dot,
|
||||
expand_aliases_denylist,
|
||||
span,
|
||||
);
|
||||
error = error.or(err);
|
||||
|
||||
if !tail.is_empty() {
|
||||
|
@ -2475,11 +2483,17 @@ pub fn unescape_unquote_string(bytes: &[u8], span: Span) -> (String, Option<Pars
|
|||
pub fn parse_string(
|
||||
working_set: &mut StateWorkingSet,
|
||||
span: Span,
|
||||
expand_aliases_denylist: &[usize],
|
||||
) -> (Expression, Option<ParseError>) {
|
||||
trace!("parsing: string");
|
||||
|
||||
let bytes = working_set.get_span_contents(span);
|
||||
|
||||
// Check for bare word interpolation
|
||||
if bytes[0] != b'\'' && bytes[0] != b'"' && bytes[0] != b'`' && bytes.contains(&b'(') {
|
||||
return parse_string_interpolation(working_set, span, expand_aliases_denylist);
|
||||
}
|
||||
|
||||
let (s, err) = unescape_unquote_string(bytes, span);
|
||||
|
||||
(
|
||||
|
@ -3899,7 +3913,7 @@ pub fn parse_value(
|
|||
SyntaxShape::Filepath => parse_filepath(working_set, span),
|
||||
SyntaxShape::Directory => parse_directory(working_set, span),
|
||||
SyntaxShape::GlobPattern => parse_glob_pattern(working_set, span),
|
||||
SyntaxShape::String => parse_string(working_set, span),
|
||||
SyntaxShape::String => parse_string(working_set, span, expand_aliases_denylist),
|
||||
SyntaxShape::Binary => parse_binary(working_set, span),
|
||||
SyntaxShape::Signature => {
|
||||
if bytes.starts_with(b"[") {
|
||||
|
@ -3940,7 +3954,8 @@ pub fn parse_value(
|
|||
|
||||
let tokens = tokens.into_iter().peekable();
|
||||
|
||||
let (cell_path, err) = parse_cell_path(working_set, tokens, false, span);
|
||||
let (cell_path, err) =
|
||||
parse_cell_path(working_set, tokens, false, expand_aliases_denylist, span);
|
||||
error = error.or(err);
|
||||
|
||||
(
|
||||
|
|
Loading…
Reference in a new issue