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#ifor#else]#— jump to the next unmatched#elseor#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
.cor.hfiles - Reference:
:help [#