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

How do I jump between matching if/else/endif or other language constructs?

Answer

% with matchit plugin

Explanation

The % command jumps between matching brackets by default, but with the built-in matchit plugin, it extends to match language-specific keywords like if/else/endif, do/end, <div>/</div>, and more.

Enabling matchit

Matchit is included with Vim but not loaded by default:

" In your vimrc
runtime macros/matchit.vim

" Or in Neovim (built-in since 0.5)
packadd matchit

What it matches

Without matchit, % only matches: (), [], {}

With matchit enabled, % also matches:

  • Ruby: def/end, do/end, if/elsif/else/end
  • HTML: <div>/</div>, <ul>/</ul>
  • Shell: if/then/elif/else/fi, case/esac
  • Vim: if/elseif/else/endif, while/endwhile
  • LaTeX: \begin{}/\end{}

Example

def process(items)
  items.each do |item|        cursor here, press %
    if item.valid?
      transform(item)
    else
      skip(item)
    end
  end                          jumps here
end

Press % again to cycle through doenddo.

Tips

  • [% jumps to the previous unmatched group start
  • ]% jumps to the next unmatched group end
  • Works in visual mode and with operators: d% deletes to the matching keyword
  • Matchit sets the b:match_words variable — you can customize matches per filetype
  • The Neovim-native vim-matchup plugin provides even more features (highlighting, text objects)

Next

How do I always access my last yanked text regardless of deletes?