vimtricks.wiki Concise Vim tricks, one at a time.

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 vimrc or init.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

  • matchit respects filetype — it uses per-language match definitions stored in b: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 by matchit
  • In Neovim, matchit is already bundled; just add packadd matchit to your config

Next

How do I programmatically set a register's content in Vimscript to pre-load a macro?