diff --git a/flamegraph.svg b/flamegraph.svg
deleted file mode 100644
index 9c3b2f0..0000000
--- a/flamegraph.svg
+++ /dev/null
@@ -1,491 +0,0 @@
-
\ No newline at end of file
diff --git a/perf.data b/perf.data
deleted file mode 100644
index d28c0cc..0000000
Binary files a/perf.data and /dev/null differ
diff --git a/perf.data.old b/perf.data.old
deleted file mode 100644
index aa3b80a..0000000
Binary files a/perf.data.old and /dev/null differ
diff --git a/src/expand.rs b/src/expand.rs
index 161550b..3471f6e 100644
--- a/src/expand.rs
+++ b/src/expand.rs
@@ -500,6 +500,7 @@ pub fn expand_var(chars: &mut Peekable>) -> ShResult {
let mut idx_brace_depth: i32 = 0;
let mut idx_raw = String::new();
let mut idx = None;
+ let mut in_operator = false;
while let Some(&ch) = chars.peek() {
match ch {
markers::SUBSH if var_name.is_empty() => {
@@ -555,7 +556,7 @@ pub fn expand_var(chars: &mut Peekable>) -> ShResult {
};
return Ok(val);
}
- '[' if brace_depth > 0 && bracket_depth == 0 && inner_brace_depth == 0 => {
+ '[' if brace_depth > 0 && bracket_depth == 0 && inner_brace_depth == 0 && !in_operator => {
chars.next(); // consume the bracket
bracket_depth += 1;
}
@@ -590,6 +591,9 @@ pub fn expand_var(chars: &mut Peekable>) -> ShResult {
if ch == '}' {
inner_brace_depth -= 1;
}
+ if !in_operator && matches!(ch, '#' | '%' | ':' | '/' | '-' | '+' | '=' | '?' | '!') {
+ in_operator = true;
+ }
var_name.push(ch);
}
ch if var_name.is_empty() && PARAMETERS.contains(&ch) => {
diff --git a/src/parse/lex.rs b/src/parse/lex.rs
index f6e9d92..35e9718 100644
--- a/src/parse/lex.rs
+++ b/src/parse/lex.rs
@@ -1087,11 +1087,26 @@ pub fn case_pat_lookahead(mut chars: Peekable) -> Option {
while let Some(ch) = chars.next() {
pos += ch.len_utf8();
match ch {
- _ if is_hard_sep(ch) => return None,
+ _ if qt_state.outside() && is_hard_sep(ch) => return None,
'\\' => {
if let Some(esc) = chars.next() {
pos += esc.len_utf8();
}
+ }
+ '$' if qt_state.outside() && chars.peek() == Some(&'\'') => {
+ // $'...' ANSI-C quoting — skip through to closing quote
+ chars.next(); // consume opening '
+ pos += 1;
+ while let Some(c) = chars.next() {
+ pos += c.len_utf8();
+ if c == '\\' {
+ if let Some(esc) = chars.next() {
+ pos += esc.len_utf8();
+ }
+ } else if c == '\'' {
+ break;
+ }
+ }
}
'\'' => {
qt_state.toggle_single();