How do I jump between matching #if, #else, and #endif preprocessor directives in C code?
Answer
[#
Explanation
Vim includes built-in motions for navigating C preprocessor conditional blocks: [# jumps backward to the previous unmatched #if or #else, and ]# jumps forward to the next unmatched #else or #endif. These make it easy to orient yourself inside deeply nested conditional compilation blocks without manually searching.
How it works
[#— jump to the previous unmatched#if,#ifdef,#ifndef, or#else]#— jump to the next unmatched#else,#elif, or#endif- "Unmatched" means there is no closing counterpart at the same nesting level between the cursor and the target
Vim respects nesting depth: if you are inside a nested #ifdef, [# takes you to the enclosing boundary, not a deeper one.
Example
#ifdef PLATFORM_LINUX ← [# lands here
#ifdef HAVE_EPOLL ← [# from inner block
use_epoll(); ← cursor here
#endif
#endif
From the cursor inside the inner block, one [# reaches #ifdef HAVE_EPOLL; pressing [# again reaches #ifdef PLATFORM_LINUX.
Tips
%on a#if/#else/#endifline jumps to its partner — but[#/]#work from inside the block, not on the directive line itself- These motions accept an operator prefix:
d[#deletes from the cursor back to the unmatched#if, making it easy to cut out an entire conditional branch - Works with all preprocessor conditionals:
#if,#ifdef,#ifndef,#elif,#else,#endif - See
:help [#for the full list of related preprocessor jump commands