(Adjust previous/next navigation) |
(Change <tt> to <code>, perhaps also minor tweak.) |
||
Line 3: | Line 3: | ||
|previous=1536 |
|previous=1536 |
||
|next=1539 |
|next=1539 |
||
− | |created= |
+ | |created=2007 |
|complexity=intermediate |
|complexity=intermediate |
||
|author=A. S. Budden |
|author=A. S. Budden |
||
Line 11: | Line 11: | ||
|category2=C |
|category2=C |
||
}} |
}} |
||
− | When the preprocessor directives < |
+ | When the preprocessor directives <code>#if</code>, <code>#ifdef</code>, <code>#elif</code>, <code>#else</code> and <code>#endif</code> are used extensively in source code, it can be extremely valuable to have comments on the <code>#else</code> and <code>#endif</code> lines to make the code clearer. |
For example: |
For example: |
||
Line 21: | Line 21: | ||
</pre> |
</pre> |
||
− | With multiple levels of < |
+ | With multiple levels of <code>#if</code>s, this can simplify the code considerably (particularly with the addition of comments on the <code>#else</code> lines. The function below can be used to automate this process. It will also highlight (with a comment containing 'XXX') any inaccurate comments (for example a <code>/* def DEBUG */</code> linked to a <code>#ifndef DEBUG</code>). |
A more advanced version of this code, with a (slightly buggy) Brace Commenter as well, is available as a plugin from http://sites.google.com/site/abudden/Vim-Scripts/smart-brace--preprocessor-commenting |
A more advanced version of this code, with a (slightly buggy) Brace Commenter as well, is available as a plugin from http://sites.google.com/site/abudden/Vim-Scripts/smart-brace--preprocessor-commenting |
Latest revision as of 06:31, 13 July 2012
created 2007 · complexity intermediate · author A. S. Budden · version 7.0
When the preprocessor directives #if
, #ifdef
, #elif
, #else
and #endif
are used extensively in source code, it can be extremely valuable to have comments on the #else
and #endif
lines to make the code clearer.
For example:
#ifdef DEBUG /* Only execute this if debugging */ printf("Example debug output\n"); #endif /* def DEBUG */
With multiple levels of #if
s, this can simplify the code considerably (particularly with the addition of comments on the #else
lines. The function below can be used to automate this process. It will also highlight (with a comment containing 'XXX') any inaccurate comments (for example a /* def DEBUG */
linked to a #ifndef DEBUG
).
A more advanced version of this code, with a (slightly buggy) Brace Commenter as well, is available as a plugin from http://sites.google.com/site/abudden/Vim-Scripts/smart-brace--preprocessor-commenting
" Commenting of #endifs etc " Author: Ben Schmidt, minor modifications by A. S. Budden. command SmartPreProcCommenter call SmartPreProcCommenter() function! SmartPreProcCommenter() mark y let saved_wrapscan=&wrapscan set nowrapscan let elsecomment="" let endcomment="" try " Find the last #if in the buffer $?^\s*#if while 1 " Build the comments for later use, based on current line let content=getline('.') let elsecomment=BuildElseComment(content,elsecomment) let endcomment=BuildEndComment(content,endcomment) " Change # into ## so we know we've already processed this one " and don't find it again s/^\s*\zs#/## " Find the next #else, #elif, #endif which must belong to this #if /^\s*#\(elif\|else\|endif\) let content=getline('.') if match(content,'^\s*#elif') != -1 " For #elif, treat the same as #if, i.e. build new comments continue elseif match(content,'^\s*#else') != -1 " For #else, add/replace the comment call setline('.',ReplaceComment(content,elsecomment)) s/^\s*\zs#/## " Find the #endif /^\s*#endif endif " We should be at the #endif now; add/replace the comment call setline('.',ReplaceComment(getline('.'),endcomment)) s/^\s*\zs#/## " Find the previous #if ?^\s*#if endwhile catch /search hit TOP/ " Once we have an error (pattern not found, i.e. no more left) " Change all our ## markers back to # silent! %s/^\s*\zs##/# endtry let &wrapscan=saved_wrapscan normal `y endfunc let s:PreProcCommentMatcher = '#\a\+\s\+\zs.\{-}\ze\(\s*\/\*.\{-}\*\/\)\?\s*$' function! BuildElseComment(content,previous) let expression=escape(matchstr(a:content,s:PreProcCommentMatcher), '\~&') if match(a:content,'#ifdef') != -1 return "/* NOT def ".expression." */" elseif match(a:content,'#ifndef') != -1 return "/* def ".expression." */" elseif match(a:content,'#if') != -1 return "/* NOT ".expression." */" elseif match(a:content,'#elif') != -1 return substitute(a:previous,' \*/',', '.expression.' */','') else return "" endif endfunc function! BuildEndComment(content,previous) let expression=escape(matchstr(a:content,s:PreProcCommentMatcher), '\~&') if match(a:content,'#ifdef') != -1 return "/* def ".expression." */" elseif match(a:content,'#ifndef') != -1 return "/* NOT def ".expression." */" elseif match(a:content,'#if') != -1 return "/* ".expression." */" elseif match(a:content,'#elif') != -1 return substitute(a:previous,' \*/',', '.expression.' */','') else return "" endif endfunc function! ReplaceComment(content,comment) let existing=escape(matchstr(a:content,'#\a\+\s\+\zs.\{-}\s*$'), '\~&') if existing == "" return substitute(a:content,'^\s*#\a\+\zs.*'," ".a:comment,'') elseif existing != a:comment && match(existing,'XXX') == -1 return a:content." /* XXX */" else return a:content endif endfunc