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

How do I jump between unmatched #if, #else, and #endif preprocessor directives in Vim?

Answer

]# and [#

Explanation

Vim provides the ]# and [# motions specifically for navigating C preprocessor conditionals. When working with deeply nested or complex #if/#ifdef/#endif blocks, these commands jump to the nearest unmatched directive rather than simply moving to the next occurrence, making it easy to find the enclosing conditional or its corresponding close.

How it works

  • [# — jump to the previous unmatched #if or #else
  • ]# — jump to the next unmatched #else or #endif
  • Both commands treat preprocessor directives as a balanced structure, like matching braces
  • Prefix with a count (2[#) to skip over N matched pairs first
  • Requires no plugins or ctags — this is built into Vim

Example

Given this C code with the cursor on the inner #if VERBOSE line:

#if DEBUG
  void debug_log() {
    #if VERBOSE
      print_all();
    #endif
  }
#endif

Pressing [# jumps to #if DEBUG, correctly skipping over the already-matched inner #if/#endif pair. Pressing ]# from #if DEBUG jumps to the outer #endif.

Tips

  • Use % to jump between any matched pair on the same line
  • [{ and ]} similarly jump to unmatched curly braces — pair these motions for full C code navigation
  • Works in any file that uses C preprocessor syntax, not just .c or .h files
  • Reference: :help [#

Next

How do I check if a specific Vim feature or capability is available before using it in my vimrc?