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

How do I make % jump between matching HTML tags and language keywords like if/end?

Answer

packadd matchit

Explanation

Vim ships with matchit.vim, an optional plugin that extends the built-in % motion to match HTML/XML tags, language keywords (if/else/end, def/end, do/end), and other language-specific paired constructs. By default only single characters like (, ), {, } are matched — matchit makes % far more powerful for real-world code.

How it works

  • packadd matchit loads the matchit plugin from Vim's built-in package directory (requires Vim 8+ or Neovim)
  • For older Vim, use runtime macros/matchit.vim instead
  • Once active, % navigates between opening and closing HTML tags, and between language keywords defined by the filetype
  • Add the command to your vimrc so it loads on every startup
" In your vimrc:
packadd matchit
" Or for older Vim:
runtime macros/matchit.vim

Example

With matchit active in an HTML file:

<div class="container">
  <p>Hello world</p>
</div>

With cursor on <div, pressing % jumps to </div>. Without matchit, % would do nothing (no single-character bracket to match).

In Ruby:

def greet
  if condition
    puts "hi"
  end
end

With cursor on def, % jumps to the matching end.

Tips

  • g% moves to the previous match (backward cycling)
  • In visual mode, % extends the selection to the matching tag or keyword
  • matchit respects the b:match_words variable, which filetypes set to define their own pairs
  • The plugin is pre-installed but not activated — it just needs packadd or runtime to load it

Next

How do I use capture groups in Vim substitutions to rearrange or swap matched text?