How do I make % jump between HTML tags and block-level keywords like if/end?
Answer
:packadd matchit
Explanation
The matchit plugin ships with Vim and Neovim but is not enabled by default. Once loaded, it supercharges % to jump between matching HTML/XML tags (<div> ↔ </div>), language block delimiters (if/elsif/else/end in Ruby, def/end in Vimscript, <!-- to --> in HTML), and more.
How it works
:packadd matchit— loads the plugin for the current session (Vim 8+ / Neovim)- For older Vim:
:runtime macros/matchit.vim - To load automatically, add to your
vimrcorinit.vim:
if has('packages')
packadd matchit
endif
Once active, % works everywhere the default built-in handles (), [], {}, and additionally on language-aware constructs defined per filetype.
Example
With matchit active in an HTML file:
<div class="container">
<p>Hello</p>
</div>
With the cursor on <div, pressing % jumps to </div>. Press % again to jump back.
In a Ruby file:
if condition
do_something
else
do_other
end
Pressing % on if jumps to else, then end, cycling through all branches.
Tips
matchitrespects filetype — it uses per-language match definitions stored inb:match_words- You can extend matching for custom filetypes:
:let b:match_words = 'begin:end' ]%and[%jump to the next/previous unmatched opening bracket, also enhanced bymatchit- In Neovim,
matchitis already bundled; just addpackadd matchitto your config