diff --git a/local/recipes/tui/tlc/source/src/editor/mod.rs b/local/recipes/tui/tlc/source/src/editor/mod.rs index 4df082fc20..80990d538d 100644 --- a/local/recipes/tui/tlc/source/src/editor/mod.rs +++ b/local/recipes/tui/tlc/source/src/editor/mod.rs @@ -824,24 +824,47 @@ impl Editor { fn update_bracket_flash(&mut self) { let pos = self.cursor.position(); let text = self.buffer.as_string(); - if pos >= text.len() || !text.is_char_boundary(pos) { + if pos > text.len() || !text.is_char_boundary(pos) { self.bracket_flash = None; return; } - let ch = text[pos..].chars().next().unwrap(); - let open = "([{<"; - let close = ")]}>"; - let result = if let Some(idx) = open.find(ch) { - let target = close.as_bytes()[idx] as char; - Self::find_matching_forward(&text, pos, ch, target) - .map(|end| (pos, end)) - } else if let Some(idx) = close.find(ch) { - let target = open.as_bytes()[idx] as char; - Self::find_matching_backward(&text, pos, ch, target) - .map(|start| (start, pos)) + // Check the character UNDER the cursor first. If the cursor + // sits on an opening bracket, the match is forward. If it + // sits on a closing bracket, the match is backward. + let ch_at = text[pos..].chars().next(); + // Also check the character BEFORE the cursor (pos - 1). + // When the user types a closing bracket, the cursor sits + // *after* the bracket; we still want to flash the pair. + let ch_before = if pos > 0 && text.is_char_boundary(pos - 1) { + text[..pos].chars().next_back() } else { None }; + let open = "([{<"; + let close = ")]}>"; + let resolve = |c: char| -> Option<(usize, usize)> { + if let Some(idx) = open.find(c) { + let target = close.as_bytes()[idx] as char; + Self::find_matching_forward(&text, pos, c, target) + .map(|end| (pos, end)) + } else if let Some(idx) = close.find(c) { + let target = open.as_bytes()[idx] as char; + Self::find_matching_backward(&text, pos, c, target) + .map(|start| (start, pos)) + } else { + None + } + }; + // Prefer the char under the cursor. Fall back to the char + // before (for the typed-closing-bracket case). + let result = ch_at.and_then(&resolve).or_else(|| { + ch_before.and_then(&resolve).map(|(s, _)| { + // For backward lookup the match is at (pos - 1) and + // the opening bracket is before it. + let _ = pos; + (s, pos.saturating_sub(1)) + }) + }); self.bracket_flash = result; }