mirror of
https://github.com/nushell/nushell.git
synced 2025-06-30 22:50:14 +02:00
Add single tick string interpolation (#581)
* Add single tick string interpolation * give string interpolation its own highlighting
This commit is contained in:
@ -19,6 +19,7 @@ pub enum FlatShape {
|
||||
Operator,
|
||||
Signature,
|
||||
String,
|
||||
StringInterpolation,
|
||||
Filepath,
|
||||
GlobPattern,
|
||||
Variable,
|
||||
@ -42,6 +43,7 @@ impl Display for FlatShape {
|
||||
FlatShape::Operator => write!(f, "flatshape_operator"),
|
||||
FlatShape::Signature => write!(f, "flatshape_signature"),
|
||||
FlatShape::String => write!(f, "flatshape_string"),
|
||||
FlatShape::StringInterpolation => write!(f, "flatshape_string_interpolation"),
|
||||
FlatShape::Filepath => write!(f, "flatshape_filepath"),
|
||||
FlatShape::GlobPattern => write!(f, "flatshape_globpattern"),
|
||||
FlatShape::Variable => write!(f, "flatshape_variable"),
|
||||
@ -215,6 +217,26 @@ pub fn flatten_expression(
|
||||
}
|
||||
output
|
||||
}
|
||||
Expr::StringInterpolation(exprs) => {
|
||||
let mut output = vec![(
|
||||
Span {
|
||||
start: expr.span.start,
|
||||
end: expr.span.start + 2,
|
||||
},
|
||||
FlatShape::StringInterpolation,
|
||||
)];
|
||||
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,
|
||||
));
|
||||
output
|
||||
}
|
||||
Expr::Record(list) => {
|
||||
let mut output = vec![];
|
||||
for l in list {
|
||||
|
@ -1014,7 +1014,7 @@ pub(crate) fn parse_dollar_expr(
|
||||
) -> (Expression, Option<ParseError>) {
|
||||
let contents = working_set.get_span_contents(span);
|
||||
|
||||
if contents.starts_with(b"$\"") {
|
||||
if contents.starts_with(b"$\"") || contents.starts_with(b"$'") {
|
||||
parse_string_interpolation(working_set, span)
|
||||
} else if let (expr, None) = parse_range(working_set, span) {
|
||||
(expr, None)
|
||||
@ -1036,16 +1036,22 @@ pub fn parse_string_interpolation(
|
||||
|
||||
let contents = working_set.get_span_contents(span);
|
||||
|
||||
let start = if contents.starts_with(b"$\"") {
|
||||
span.start + 2
|
||||
let (start, end) = if contents.starts_with(b"$\"") {
|
||||
let end = if contents.ends_with(b"\"") && contents.len() > 2 {
|
||||
span.end - 1
|
||||
} else {
|
||||
span.end
|
||||
};
|
||||
(span.start + 2, end)
|
||||
} else if contents.starts_with(b"$'") {
|
||||
let end = if contents.ends_with(b"'") && contents.len() > 2 {
|
||||
span.end - 1
|
||||
} else {
|
||||
span.end
|
||||
};
|
||||
(span.start + 2, end)
|
||||
} else {
|
||||
span.start
|
||||
};
|
||||
|
||||
let end = if contents.ends_with(b"\"") && contents.len() > 2 {
|
||||
span.end - 1
|
||||
} else {
|
||||
span.end
|
||||
(span.start, span.end)
|
||||
};
|
||||
|
||||
let inner_span = Span { start, end };
|
||||
@ -1134,30 +1140,15 @@ pub fn parse_string_interpolation(
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(decl_id) = working_set.find_decl(b"build-string") {
|
||||
(
|
||||
Expression {
|
||||
expr: Expr::Call(Box::new(Call {
|
||||
head: Span {
|
||||
start: span.start,
|
||||
end: span.start + 2,
|
||||
},
|
||||
named: vec![],
|
||||
positional: output,
|
||||
decl_id,
|
||||
})),
|
||||
span,
|
||||
ty: Type::String,
|
||||
custom_completion: None,
|
||||
},
|
||||
error,
|
||||
)
|
||||
} else {
|
||||
(
|
||||
Expression::garbage(span),
|
||||
Some(ParseError::UnknownCommand(span)),
|
||||
)
|
||||
}
|
||||
(
|
||||
Expression {
|
||||
expr: Expr::StringInterpolation(output),
|
||||
span,
|
||||
ty: Type::String,
|
||||
custom_completion: None,
|
||||
},
|
||||
error,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn parse_variable_expr(
|
||||
@ -3529,6 +3520,12 @@ pub fn find_captures_in_expr(
|
||||
}
|
||||
Expr::Signature(_) => {}
|
||||
Expr::String(_) => {}
|
||||
Expr::StringInterpolation(exprs) => {
|
||||
for expr in exprs {
|
||||
let result = find_captures_in_expr(working_set, expr, seen);
|
||||
output.extend(&result);
|
||||
}
|
||||
}
|
||||
Expr::RowCondition(block_id) | Expr::Subexpression(block_id) => {
|
||||
let block = working_set.get_block(*block_id);
|
||||
let result = find_captures_in_block(working_set, block, seen);
|
||||
|
Reference in New Issue
Block a user