Highlight matching brackets in the REPL input - #35
Merged
Merged
Conversation
Adds DevTools-style bracket-pair highlighting to the REPL's live input: the bracket adjacent to the caret and its match get a subtle background plus underline, updated as the caret moves (not just as text changes). findMatchingBrackets() (bracket-matcher.ts) resolves which bracket is "active" for the caret the same way Chrome/CodeMirror do - checking the character immediately behind the caret before the one in front - so back-to-back brackets with no whitespace (`}]`) resolve unambiguously, while whitespace-separated brackets match from either side since only one side is ever touching a bracket character. Matching itself walks the existing tokenizer's punctuation stream with a stack, so brackets inside strings/comments are never candidates and mismatched closers are left unpaired rather than mispairing. highlightCode() takes an optional matched-pair offset tuple and wraps just those two punctuation tokens; the REPL wires it up by reading live caret/selection state (not values captured at event time) inside the existing debounced highlight update, and adds click/keyup/select listeners so pure caret movement (not just typing) also refreshes it. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This branch was previously deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
}]with no space) follows Chrome/CodeMirror's convention: the character immediately behind the caret wins over the one in front. With whitespace around brackets, this never matters since only one side ever touches a bracket character.findMatchingBrackets()(src/runtime/bracket-matcher.ts) reuses the existing tokenizer's punctuation stream with a stack, so brackets inside strings/comments are never candidates, and mismatched closers are left unpaired instead of being force-matched.highlightCode()now takes an optional matched-pair offset tuple and wraps just those two punctuation tokens in a.vc-bracket-matchspan.click/keyup/selectlisteners so pure caret movement - not just typing - refreshes the highlight.Test plan
pnpm test- all 116 tests pass, including 10 newbracket-matcher.test.tscases (simple pairs from all four caret sides, the tight-nesting tie-break, whitespace-separated matching from either side, unmatched/mismatched brackets, brackets inside strings, empty input)pnpm typecheck- cleanpnpm lint- clean (one pre-existing, unrelated warning intokenizer.test.ts)examples/local/react-vite-plugin): typed[{ONE:{a:1},TWO:[1,2]}]into the REPL and inspected the rendered backdrop HTML at several caret positions to confirm the correct pair highlights, confirmed the whitespace case matches from either side, and confirmed no highlight while text is selected🤖 Generated with Claude Code