preproccomment.vim (1933B)
1 " Commenting of #endifs etc 2 " Author: Ben Schmidt, minor modifications by A. S. Budden. 3 4 augroup preproc 5 au BufWrite *.[ch] :call SmartPreProcCommenter() 6 augroup END 7 8 function! SmartPreProcCommenter() 9 mark y 10 let saved_wrapscan=&wrapscan 11 set nowrapscan 12 let elsecomment="" 13 let endcomment="" 14 try 15 " Find the last #if in the buffer 16 $?^\s*#if 17 while 1 18 " Build the comments for later use, based on current line 19 let content=getline('.') 20 let endcomment=BuildEndComment(content,endcomment) 21 " Change # into ## so we know we've already processed this one 22 " and don't find it again 23 s/^\s*\zs#/## 24 " Find the next #else, #elif, #endif which must belong to this #if 25 /^\s*#endif 26 let content=getline('.') 27 call setline('.',ReplaceComment(getline('.'),endcomment)) 28 s/^\s*\zs#/## 29 " Find the previous #if 30 ?^\s*#if 31 endwhile 32 catch /search hit TOP/ 33 " Once we have an error (pattern not found, i.e. no more left) 34 " Change all our ## markers back to # 35 silent! %s/^\s*\zs##/# 36 endtry 37 let &wrapscan=saved_wrapscan 38 normal `y 39 endfunc 40 41 let s:PreProcCommentMatcher = '#\a\+\s\+\zs.\{-}\ze\(\s*\/\*.\{-}\*\/\)\?\s*$' 42 43 function! BuildEndComment(content,previous) 44 let expression=escape(matchstr(a:content,s:PreProcCommentMatcher), '\~&') 45 if match(a:content,'#ifdef') != -1 46 return "/* ".expression." */" 47 elseif match(a:content,'#ifndef') != -1 48 return "/* not ".expression." */" 49 elseif match(a:content,'#if') != -1 50 return "/* ".expression." */" 51 else 52 return "" 53 endif 54 endfunc 55 56 function! ReplaceComment(content,comment) 57 let existing=escape(matchstr(a:content,'#\a\+\s\+\zs.\{-}\s*$'), '\~&') 58 if existing == "" 59 return substitute(a:content,'^\s*#\a\+\zs.*'," ".a:comment,'') 60 elseif existing != a:comment && match(existing,'XXX') == -1 61 return a:content." /* XXX */" 62 else 63 return a:content 64 endif 65 endfunc