Walk backward from `start` (exclusive) to find the unmatched `(` that encloses the cursor. Skips balanced `(…)` pairs and string literals. Returns `None` if no enclosing `(` is found (cursor is not inside call parens).
(chars: &[char], start: usize)
| 160 | /// Skips balanced `(…)` pairs and string literals. Returns `None` if no |
| 161 | /// enclosing `(` is found (cursor is not inside call parens). |
| 162 | pub fn find_enclosing_open_paren(chars: &[char], start: usize) -> Option<usize> { |
| 163 | let mut i = start; |
| 164 | let mut depth: i32 = 0; |
| 165 | |
| 166 | while i > 0 { |
| 167 | i -= 1; |
| 168 | match chars[i] { |
| 169 | ')' => depth += 1, |
| 170 | '(' => { |
| 171 | if depth > 0 { |
| 172 | depth -= 1; |
| 173 | } else { |
| 174 | // Found unmatched `(` — this is the call's open paren. |
| 175 | return Some(i); |
| 176 | } |
| 177 | } |
| 178 | // Skip single-quoted strings backwards |
| 179 | '\'' => { |
| 180 | i = skip_string_backward(chars, i, '\''); |
| 181 | } |
| 182 | // Skip double-quoted strings backwards |
| 183 | '"' => { |
| 184 | i = skip_string_backward(chars, i, '"'); |
| 185 | } |
| 186 | // If we hit `{` or `[` without a matching `}` or `]`, we've |
| 187 | // left the expression context — stop searching. |
| 188 | '{' | '[' => return None, |
| 189 | // If we hit `;` we've gone past a statement boundary. |
| 190 | ';' => return None, |
| 191 | _ => {} |
| 192 | } |
| 193 | } |
| 194 | |
| 195 | None |
| 196 | } |
| 197 | |
| 198 | /// Skip backward past a string literal ending at position `end` (which |
| 199 | /// points to the closing quote character `q`). |
no test coverage detected