Skip to content

Matching tag / block highlighting

When the caret is on — or inside — an enclosing tag or block, the editor boxes the start and the end of that pair, so you can see at a glance where a <div>…</div>, an if…fi, or a #if…#endif begins and ends.

This is separate from the single-character brace match (the () [] {} glyph): that one still works exactly as before, on its own. Both can show at the same time, so you can be inside a { } block and an enclosing if…fi and see both.

Using it

Put the caret on a tag name (or anywhere inside <…>), or on a block keyword — the open, the close, and any "middle" keywords light up together. Placing the caret inside a block (not on a keyword) highlights the nearest enclosing pair. Plain content between tags highlights nothing.

It updates as the caret moves and needs no shortcut.

Turning it on and off

View ▸ Highlight Matching Tag/Block — on by default, and the choice is remembered between sessions.

The two kinds of pair

Tags (markup)

In HTML and XML, the caret on a start or end tag boxes the element name in both tags. Nesting of same-named tags is resolved by depth, self-closing tags (<br/>) have no partner, and a > inside a quoted attribute value never ends the tag early. < used as text or a comparison operator never triggers it — matching keys off the lexer's tag styling, not raw angle brackets.

Block keywords (languages)

Whole-word keyword pairs, counted with proper nesting and skipping anything inside comments and strings. Shipped out of the box:

Language Pairs
Shell (bash) if … fi (with elif/else), do … done, case … esac
C / C++ preprocessor #if / #ifdef / #ifndef#endif (with #elif/#else)
SQL begin … end, case … end (case-insensitive)

C/C++ uses this only for the preprocessor

Ordinary C/C++ { } blocks are handled by the single-character brace match, not this feature — so a .cpp with no #if…#endif conditionals shows nothing here, by design.

Adding pairs for another language

Pairs are data, not code: they live in the language's colorizer JSON, so you can add them for any language without rebuilding. In the colorizer file add "tagMatch": true for markup, or a "blockPairs" list for keyword pairs, e.g.:

"blockPairs": [
    { "open": "if", "middle": ["elif", "else"], "close": "fi" },
    { "open": "do", "close": "done" }
],
"pairsCaseSensitive": false

A user colorizer file shadows the shipped one, so you can override or extend the built-ins. See Syntax colouring for where colorizer files live.

Notes and limits

  • Matching scans a window around the caret, so a pair whose ends are very far apart (roughly a thousand lines or more — e.g. a whole-file include guard) may not be matched.
  • Matching uses strict nesting: a single unclosed inner tag/block prevents the tags/blocks around it from matching until it is closed.