make embedded dollar quote interpolation work properly

This commit is contained in:
Devyn Cairns 2024-06-19 20:52:33 -07:00
parent 7f4f9114f4
commit da83dcd670
No known key found for this signature in database
2 changed files with 35 additions and 1 deletions

View File

@ -183,6 +183,20 @@ fn external_arg_with_non_option_like_embedded_quotes() {
)
}
#[test]
fn external_arg_with_string_interpolation() {
Playground::setup("external arg with string interpolation", |dirs, _| {
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
^nu --testbin cococo foo=(2 + 2) $"foo=(2 + 2)" foo=$"(2 + 2)"
"#
));
assert_eq!(actual.out, "foo=4 foo=4 foo=4");
})
}
#[test]
fn external_arg_with_variable_name() {
Playground::setup("external failed command with semicolon", |dirs, _| {

View File

@ -261,7 +261,9 @@ fn parse_external_string(working_set: &mut StateWorkingSet, span: Span) -> Expre
};
let mut spans = vec![];
let mut state = State::Bare { from: 0 };
for (index, &ch) in contents.iter().enumerate() {
let mut index = 0;
while index < contents.len() {
let ch = contents[index];
match &mut state {
State::Bare { from } => match ch {
b'"' | b'\'' => {
@ -277,6 +279,23 @@ fn parse_external_string(working_set: &mut StateWorkingSet, span: Span) -> Expre
depth: 1,
};
}
b'$' => {
if let Some(&quote_char @ (b'"' | b'\'')) = contents.get(index + 1) {
// Start a dollar quote (interpolated string)
if index != *from {
spans.push(make_span(*from, index));
}
state = State::Quote {
from: index,
quote_char,
escaped: false,
depth: 1,
};
// Skip over two chars (the dollar sign and the quote)
index += 2;
continue;
}
}
// Continue to consume
_ => (),
},
@ -316,6 +335,7 @@ fn parse_external_string(working_set: &mut StateWorkingSet, span: Span) -> Expre
}
},
}
index += 1;
}
// Add the final span