SV Matchit — Custom Keyword Jump

Jump/select between keyword pairs, not just brackets — built for HDL languages
like SystemVerilog where a single file nests module → class → `ifdef →
function → begin/end → fork/join_any many levels deep, and VS Code's
built-in "Jump to Bracket" (Ctrl+Shift+\) has no idea begin should jump to its
end.
This extension binds to the same Ctrl+Shift+\ shortcut and acts as a drop-in
replacement for the built-in command, understanding language keywords in addition
to brackets.
Features
- Jump (
Ctrl+Shift+\) — place the cursor on any configured open/close keyword
and jump to its match, correctly skipping over nested pairs of the same kind.
- Select (
svMatchit.select) — same lookup, but selects the exact character
range from the open keyword to the close keyword.
- Select full lines (
svMatchit.selectLines) — same lookup, but expands the
selection to whole lines instead of the exact character range — handy for yanking
or deleting an entire begin…end / `ifdef…`endif block in one motion.
- Built-in SystemVerilog keyword set —
module/endmodule, class/endclass,
function/endfunction, task/endtask, begin/end, case/casex/casez/randcase → endcase, fork → join/join_any/join_none, covergroup → endgroup, common
`uvm_*_utils_begin/end macros, and more — works out of the box, no
settings.json config required.
- Preprocessor-aware —
`ifdef/`ifndef/`elsif/`else/`endif
branches are matched as a mutually-exclusive chain, so an imbalance inside one
`ifdef branch never corrupts matching in a sibling branch or the surrounding
code.
- Fully configurable / extensible — add your own pairs or override the defaults
per
languageId via settings.json, for any language, not just SystemVerilog.
- Diagnostics built in —
SV Matchit: Find Unmatched Keyword scans the whole
file and lists every unmatched open and every stray close, jumping straight to
the first one, so tracking down a missing end/endfunction/`endif doesn't
mean bisecting the file by hand.
Commands
| Command |
Title |
Default behavior |
svMatchit.jump |
SV Matchit: Jump to Matching Keyword |
Move cursor to the matching keyword |
svMatchit.select |
SV Matchit: Select to Matching Keyword |
Select the exact range between the pair |
svMatchit.selectLines |
SV Matchit: Select Full Lines to Matching Keyword |
Select whole lines spanning the pair |
svMatchit.findUnmatched |
SV Matchit: Find Unmatched Keyword (jump to first imbalance) |
Report every unmatched open/stray close in the file |
svMatchit.debugConfig |
SV Matchit: Debug Config (show loaded pairs) |
Show which pairs are loaded for the current language |
None of these ship with a default keybinding except svMatchit.jump
(Ctrl+Shift+\ / Cmd+Shift+\) — wire the rest up to whatever key you like.
Configuration
Two independent, combinable sources of keyword pairs. Both are optional — the
built-in SystemVerilog defaults work with zero configuration.
matchit.brackets — literal pairs, supports many-to-one / one-to-many
"matchit.brackets": {
"systemverilog": [
["begin", "end"],
["fork", "join"],
["fork", "join_any"],
["fork", "join_none"],
["class", "endclass"]
]
}
Anything you list here is merged with the built-in defaults for that
languageId (duplicates are automatically de-duplicated, so re-declaring a
default pair is harmless). Use this to add project-specific macros or a
different language entirely.
Do not add `ifdef/`ifndef/`endif here — those are handled by a
dedicated, branch-aware matcher (see Features above) so that a missing
`endif in one conditional branch doesn't cascade into every branch after
it. Declaring them again in matchit.brackets re-introduces exactly that
failure mode.
matchit.matchingKeywords — regex pairs, strict 1:1
"matchit.matchingKeywords": {
"bsv": [
["\\brule\\b", "\\bendrule\\b"],
["\\baction\\b", "\\bendaction\\b"]
]
}
Use this when a pair needs full regex control and there's exactly one opener
and one closer (no many-to-one / one-to-many cases).
Requirements
VS Code ^1.74.0. No other dependencies.
Known limitations
- Matching is a single flat stack shared across every configured pair in the
file: any open/close keyword pair present anywhere in the document
participates in the same nesting check as every other pair. This is what
makes deep, mixed-keyword nesting (
module → `ifdef → case →
fork/join_any) resolve correctly, but it also means a genuinely missing
closer anywhere in the file can surface as a "no match" error on an
unrelated, correctly-written keyword elsewhere. Run SV Matchit: Find
Unmatched Keyword to locate the actual source.
- Comments (
//, /* */) and string literals ("...") are stripped before
matching, so keywords mentioned inside them are ignored — but only
double-quoted strings are recognized as strings.
Release Notes
See CHANGELOG.md.
License
MIT © quindeptrai