Warning, /sdk/kde-dev-scripts/kde-devel-vim.vim is written in an unsupported language. File is not indexed.
0001 " To use this file, add this line to your ~/.vimrc:, w/o the dquote 0002 " source /path/to/kde/sources/kdesdk/scripts/kde-devel-vim.vim 0003 " 0004 " For CreateChangeLogEntry() : If you don't want to re-enter your 0005 " Name/Email in each vim session then make sure to have the viminfo 0006 " option enabled in your ~/.vimrc, with the '!' flag, enabling persistent 0007 " storage of global variables. Something along the line of 0008 " set viminfo=%,!,'50,\"100,:100,n~/.viminfo 0009 " should do the trick. 0010 " 0011 " To make use of the ,ll and ,lg shortcuts you need to have the files 0012 " GPLHEADER and LGPLHEADER in your home directory. Their content will be 0013 " copied as license header then. 0014 0015 " Don't include these in filename completions 0016 set suffixes+=.lo,.o,.moc,.la,.closure,.loT 0017 0018 " Search for headers here 0019 set path=.,/usr/include,/usr/local/include, 0020 if $QTDIR != '' 0021 let &path = &path . $QTDIR . '/include/,' 0022 let &path = &path . $QTDIR . '/include/Qt/,' 0023 let &path = &path . $QTDIR . '/include/QtCore/,' 0024 let &path = &path . $QTDIR . '/include/Qt3Support/,' 0025 let &path = &path . $QTDIR . '/include/QtAssistant/,' 0026 let &path = &path . $QTDIR . '/include/QtDBus/,' 0027 let &path = &path . $QTDIR . '/include/QtDesigner/,' 0028 let &path = &path . $QTDIR . '/include/QtGui/,' 0029 let &path = &path . $QTDIR . '/include/QtNetwork/,' 0030 let &path = &path . $QTDIR . '/include/QtOpenGL/,' 0031 let &path = &path . $QTDIR . '/include/QtSql/,' 0032 let &path = &path . $QTDIR . '/include/QtSvg/,' 0033 let &path = &path . $QTDIR . '/include/QtTest/,' 0034 let &path = &path . $QTDIR . '/include/QtUiTools/,' 0035 let &path = &path . $QTDIR . '/include/QtXml/,' 0036 endif 0037 if $KDEDIR != '' 0038 let &path = &path . $KDEDIR . '/include/,' 0039 endif 0040 if $KDEDIRS != '' 0041 let &path = &path . substitute( $KDEDIRS, '\(:\|$\)', '/include,', 'g' ) 0042 endif 0043 set path+=, 0044 0045 " Use makeobj to build 0046 set mp=makeobj 0047 0048 " If TagList is Loaded then get a funny statusline 0049 " Only works if kde-devel-vim.vim is loaded after taglist. 0050 " Droping this script in ~/.vim/plugin works fine 0051 if exists('loaded_taglist') 0052 let Tlist_Process_File_Always=1 0053 set statusline=%<%f:[\ %{Tlist_Get_Tag_Prototype_By_Line()}\ ]\ %h%m%r%=%-14.(%l,%c%V%)\ %P 0054 endif 0055 0056 " Insert tab character in whitespace-only lines, complete otherwise 0057 inoremap <Tab> <C-R>=SmartTab()<CR> 0058 0059 if !exists("DisableSmartParens") 0060 " Insert a space after ( or [ and before ] or ) unless preceded by a matching 0061 " paren/bracket or space or inside a string or comment. Comments are only 0062 " recognized as such if they start on the current line :-( 0063 inoremap ( <C-R>=SmartParens( '(' )<CR> 0064 inoremap [ <C-R>=SmartParens( '[' )<CR> 0065 inoremap ] <C-R>=SmartParens( ']', '[' )<CR> 0066 inoremap ) <C-R>=SmartParens( ')', '(' )<CR> 0067 endif 0068 0069 " Insert an #include statement for the current/last symbol 0070 inoremap <F5> <C-O>:call AddHeader()<CR> 0071 0072 " Insert a forward declaration for the current/last symbol 0073 inoremap <S-F5> <C-O>:call AddForward()<CR> 0074 0075 " Switch between header and implementation files on ,h 0076 nmap <silent> ,h :call SwitchHeaderImpl()<CR> 0077 nmap <silent> ,p :call SwitchPrivateHeaderImpl()<CR> 0078 0079 " Comment selected lines on ,c in visual mode 0080 vmap ,c :s,^,//X ,<CR>:noh<CR> 0081 " Uncomment selected lines on ,u in visual mode 0082 vmap ,u :s,^//X ,,<CR> 0083 0084 " Insert an include guard based on the file name on ,i 0085 nmap ,i :call IncludeGuard()<CR> 0086 0087 " Insert license headers at the top of the file 0088 nmap ,lg :call LicenseHeader( "GPL" )<CR> 0089 nmap ,ll :call LicenseHeader( "LGPL" )<CR> 0090 nmap ,lm :call LicenseHeader( "MIT" )<CR> 0091 0092 " Expand #i to #include <.h> or #include ".h". The latter is chosen 0093 " if the character typed after #i is a dquote 0094 " If the character is > #include <> is inserted (standard C++ headers w/o .h) 0095 iab #i <C-R>=SmartInclude()<CR> 0096 0097 " Insert a stripped down CVS diff 0098 iab DIFF <Esc>:call RunDiff()<CR> 0099 0100 " mark 'misplaced' tab characters 0101 set listchars=tab:·\ ,trail:· 0102 set list 0103 0104 set incsearch 0105 0106 function! SetCodingStyle() 0107 if &syntax == 'cmake' 0108 call SmartParensOff() 0109 set sw=3 0110 set ts=3 0111 set et 0112 set tw=0 0113 return 0114 endif 0115 if ( &syntax !~ '^\(c\|cpp\|java\)$' ) 0116 return 0117 endif 0118 "the path for the file 0119 let pathfn = expand( '%:p:h' ) 0120 if pathfn =~ 'nmm' 0121 call SmartParensOff() 0122 inoremap ( <C-R>=SpaceBetweenKeywordAndParens()<CR> 0123 let g:need_brace_on_next_line = '\<\(class\|namespace\|struct\)\>' 0124 let g:need_brace_on_same_line = '\<\(if\|else\|while\|switch\|do\|enum\|for\|try\|catch\)\>' 0125 set sw=4 0126 set ts=4 0127 set noet 0128 set tw=100 0129 elseif pathfn =~ 'xine-lib' 0130 call SmartParensOff() 0131 let g:need_brace_on_next_line = '\<\(class\|namespace\|struct\)\>' 0132 let g:need_brace_on_same_line = '\<\(if\|else\|while\|switch\|do\|foreach\|forever\|enum\|for\|try\|catch\)\>' 0133 set sw=2 0134 set sts=2 0135 set ts=8 0136 set noet 0137 "set tw=100 0138 elseif pathfn =~ 'kdemultimedia\/juk' 0139 call SmartParensOff() 0140 let g:need_brace_on_next_line = '\<\(class\|namespace\|struct\|if\|else\|while\|switch\|do\|foreach\|forever\|enum\|for\|try\|catch\)\>' 0141 let g:need_brace_on_same_line = '' 0142 set sw=4 0143 set sts=4 0144 set et 0145 "set tw=100 0146 elseif pathfn =~ 'kdenetwork\/kopete' 0147 call SmartParensOff() 0148 let g:need_brace_on_next_line = '\<\(class\|namespace\|struct\|if\|else\|while\|switch\|do\|foreach\|forever\|enum\|for\|try\|catch\)\>' 0149 let g:need_brace_on_same_line = '' 0150 set sw=4 0151 set sts=4 0152 set noet 0153 "set tw=100 0154 else " kdelibs/kf5/qt coding style 0155 call SmartParensOff() 0156 inoremap ( <C-R>=SpaceBetweenKeywordAndParens()<CR> 0157 let g:need_brace_on_next_line = '\<\(class\|namespace\|struct\)\>' 0158 let g:need_brace_on_same_line = '\<\(if\|else\|while\|switch\|do\|foreach\|forever\|enum\|for\|try\|catch\)\>' 0159 set sw=4 0160 set sts=4 0161 set et 0162 "set tw=100 0163 endif 0164 if ( !exists("g:noautobrace") ) 0165 call EnableSmartLineBreak() 0166 endif 0167 endfunction 0168 0169 function! DisableSmartLineBreak() 0170 iunmap <CR> 0171 iuna else 0172 endfunction 0173 function! EnableSmartLineBreak() 0174 if exists("*pumvisible") 0175 inoremap <CR> <C-R>=pumvisible() ? "\<lt>CR>" : "\<lt>ESC>:call SmartLineBreak()\<lt>CR>a\<lt>CR>"<CR> 0176 else 0177 inoremap <CR> <ESC>:call SmartLineBreak()<CR>a<CR> 0178 endif 0179 iab else <C-R>=SmartElse()<CR> 0180 endfunction 0181 0182 function! SmartElse() 0183 "let next = nr2char( getchar( 0 ) ) 0184 let prefix = '' 0185 if strlen(g:need_brace_on_same_line) > 0 && 'else' =~ g:need_brace_on_same_line 0186 if getline('.') =~ '^\s*$' 0187 if getline(line('.') - 1) =~ '}$' 0188 let prefix = prefix . "\<ESC>kmMjdd`MA " 0189 elseif getline(line('.') - 1) =~ '}\s*$' 0190 let prefix = prefix . "\<ESC>kmMjdd`MA" 0191 endif 0192 endif 0193 endif 0194 return prefix . "else\<Right>" 0195 endfunction 0196 0197 " automatic indenting is required for SmartLineBreak to work correctly 0198 filetype indent on 0199 0200 function! CreateMatchLine() 0201 let linenum = line( '.' ) 0202 let current_line = getline( linenum ) 0203 " don't do magic if the cursor isn't at the end of the line or if it's 0204 " inside a // comment 0205 if col( '.' ) != strlen( current_line ) || match( current_line, '//' ) >= 0 0206 return '' 0207 endif 0208 " remove whitespace at the end 0209 if match( current_line, '\s\+$' ) >= 0 0210 :execute ':s/\s*$//' 0211 " the following is needed if return '' is called 0212 :execute "normal $" 0213 endif 0214 let current_line = getline( linenum ) 0215 " remove all /* */ comments 0216 let current_line = substitute( current_line, '/\*.\{-}\*/', '', 'g' ) 0217 " remove all strings 0218 let current_line = substitute( current_line, "'[^']*'", '', 'g' ) 0219 let current_line = substitute( current_line, '"\(\\"\|[^"]\)*"', '', 'g' ) 0220 " remove all ( ) 0221 while current_line =~ '(.*)' 0222 let current_line = substitute( current_line, '([^()]*)', '', 'g' ) 0223 endwhile 0224 " prepend earlier lines until we find a ; or { 0225 while linenum > 1 && current_line !~ ';' && current_line !~ '{.\+$' 0226 let linenum = linenum - 1 0227 let prev_line = getline(linenum) 0228 if synIDattr(synID(linenum, 1, 1), "name") == 'cComment' "inside a /* */ comment at the beginning of the line 0229 if stridx(prev_line, '*/') == -1 0230 " next line please 0231 let prev_line = '' 0232 else 0233 " remove everything before */ 0234 let prev_line = substitute(prev_line, '^.*\*/', '*/', '') 0235 endif 0236 endif 0237 " remove // comment 0238 let prev_line = substitute(prev_line, '//.*$', '', '' ) 0239 " concatenate the lines with a space in between 0240 let current_line = prev_line.' '.current_line 0241 " remove all /* */ comments 0242 let current_line = substitute( current_line, '/\*.\{-}\*/', '', 'g' ) 0243 " remove all strings 0244 let current_line = substitute( current_line, "'[^']*'", '', 'g' ) 0245 let current_line = substitute( current_line, '"\(\\"\|[^"]\)*"', '', 'g' ) 0246 " remove all ( ) 0247 while current_line =~ '(.*)' 0248 let current_line = substitute( current_line, '([^()]*)', '', 'g' ) 0249 endwhile 0250 endwhile 0251 " remove everything until the last ; 0252 let current_line = substitute( current_line, '^.*;', '', '' ) 0253 " remove everything until the last { which is not at the end of the line 0254 let current_line = substitute( current_line, '^.*{\(.\+\)$', '\1', '' ) 0255 " remove all [ ] 0256 while current_line =~ '\[.*\]' 0257 let current_line = substitute( current_line, '\[[^\[\]]*\]', '', 'g' ) 0258 endwhile 0259 " if <CR> was pressed inside ( ), [ ] or /* */ don't add braces 0260 if current_line =~ '[(\[]' || current_line =~ '/\*' 0261 return '' 0262 endif 0263 return current_line 0264 endfunction 0265 0266 function! AddClosingBrace(current_line) 0267 if a:current_line =~ '\<enum\|class\|struct\>' 0268 :execute "normal o};\<ESC>k" 0269 elseif a:current_line =~ '\<namespace\>' 0270 let namespace = substitute( a:current_line, '^.*namespace\s\+', '', '' ) 0271 let namespace = substitute( namespace, '\s.*$', '', '' ) 0272 :execute "normal o} // namespace " . namespace . "\<ESC>k" 0273 else 0274 :execute "normal o}\<ESC>k" 0275 endif 0276 endfunction 0277 0278 function! SmartLineBreak() 0279 if synIDattr(synID(line("."), col("."), 1), "name") == 'cComment' "inside a /* */ comment at the point where the line break occurs 0280 return 0281 endif 0282 let match_line = CreateMatchLine() 0283 if match_line == '' 0284 return 0285 endif 0286 0287 let match_position1 = -1 0288 let match_position2 = -1 0289 if strlen(g:need_brace_on_same_line) > 0 0290 let match_position1 = match(match_line, g:need_brace_on_same_line) 0291 if match_position1 > 0 0292 while strpart(match_line, match_position1 - 1, 1) == '#' 0293 let old_position = match_position1 0294 let match_position1 = match(match_line, g:need_brace_on_same_line, match_position1 + 1) 0295 if match_position1 == -1 0296 if strpart(match_line, old_position, 2) == 'if' 0297 :execute "normal o#endif\<ESC>k$" 0298 endif 0299 return 0300 endif 0301 endwhile 0302 endif 0303 endif 0304 if strlen(g:need_brace_on_next_line) > 0 && match_position1 == -1 0305 let match_position2 = match(match_line, g:need_brace_on_next_line) 0306 if match_position2 > 0 0307 while strpart(match_line, match_position2 - 1, 1) == '#' 0308 let old_position = match_position2 0309 let match_position2 = match(match_line, g:need_brace_on_same_line, match_position2 + 1) 0310 if match_position2 == -1 0311 if strpart(match_line, old_position, 2) == 'if' 0312 :execute "normal o#endif\<ESC>k$" 0313 endif 0314 return 0315 endif 0316 endwhile 0317 endif 0318 endif 0319 0320 if match_position1 > -1 0321 if match_line =~ '}\s*else\>' 0322 " make sure else is on the same line as the closing brace 0323 if getline('.') =~ '^\s*else' 0324 if getline(line('.') - 1) =~ '}$' 0325 :execute "normal kA \<ESC>J" 0326 elseif getline(line('.') - 1) =~ '}\s*$' 0327 :execute "normal kJ" 0328 endif 0329 endif 0330 endif 0331 while getline('.') =~ '^\s*{$' 0332 " opening brace is on its own line: move it up 0333 :execute "normal kJ" 0334 endwhile 0335 if match_line =~ '{$' 0336 if getline('.') =~ '[^ ]{$' 0337 :execute ':s/{$/ {/' 0338 endif 0339 else 0340 :execute ':s/$/ {/' 0341 endif 0342 call AddClosingBrace(match_line) 0343 elseif getline('.') =~ '^\s*{$' 0344 call AddClosingBrace('') 0345 elseif match_position2 > -1 0346 if match_line =~ '{$' 0347 :execute ':s/\s*{$//' 0348 endif 0349 :execute "normal o{" 0350 call AddClosingBrace(match_line) 0351 endif 0352 :execute "normal $" 0353 endfunction 0354 0355 function! SmartParensOn() 0356 inoremap ( <C-R>=SmartParens( '(' )<CR> 0357 inoremap [ <C-R>=SmartParens( '[' )<CR> 0358 inoremap ] <C-R>=SmartParens( ']', '[' )<CR> 0359 inoremap ) <C-R>=SmartParens( ')', '(' )<CR> 0360 endfunction 0361 0362 function! SmartParensOff() 0363 if strlen(mapcheck('[','i')) > 0 0364 iunmap ( 0365 iunmap [ 0366 iunmap ] 0367 iunmap ) 0368 endif 0369 endfunction 0370 0371 function! SmartTab() 0372 let col = col('.') - 1 0373 if !col || getline('.')[col-1] !~ '\k' 0374 return "\<Tab>" 0375 else 0376 return "\<C-P>" 0377 endif 0378 endfunction 0379 0380 function! SmartParens( char, ... ) 0381 if ! ( &syntax =~ '^\(c\|cpp\|java\)$' ) 0382 return a:char 0383 endif 0384 let s = strpart( getline( '.' ), 0, col( '.' ) - 1 ) 0385 if s =~ '//' 0386 return a:char 0387 endif 0388 let s = substitute( s, '/\*\([^*]\|\*\@!/\)*\*/', '', 'g' ) 0389 let s = substitute( s, "'[^']*'", '', 'g' ) 0390 let s = substitute( s, '"\(\\"\|[^"]\)*"', '', 'g' ) 0391 if s =~ "\\([\"']\\|/\\*\\)" 0392 return a:char 0393 endif 0394 if a:0 > 0 0395 if strpart( getline( '.' ), col( '.' ) - 3, 2 ) == a:1 . ' ' 0396 return "\<BS>" . a:char 0397 endif 0398 if strpart( getline( '.' ), col( '.' ) - 2, 1 ) == ' ' 0399 return a:char 0400 endif 0401 return ' ' . a:char 0402 endif 0403 if !exists("g:DisableSpaceBeforeParen") 0404 if a:char == '(' 0405 if strpart( getline( '.' ), col( '.' ) - 3, 2 ) == 'if' || 0406 \strpart( getline( '.' ), col( '.' ) - 4, 3 ) == 'for' || 0407 \strpart( getline( '.' ), col( '.' ) - 6, 5 ) == 'while' || 0408 \strpart( getline( '.' ), col( '.' ) - 7, 6 ) == 'switch' 0409 return ' ( ' 0410 endif 0411 endif 0412 endif 0413 return a:char . ' ' 0414 endfunction 0415 0416 function! SpaceBetweenKeywordAndParens() 0417 if ! ( &syntax =~ '^\(c\|cpp\|java\)$' ) 0418 return '(' 0419 endif 0420 let s = strpart( getline( '.' ), 0, col( '.' ) - 1 ) 0421 if s =~ '//' 0422 " text inside a comment 0423 return '(' 0424 endif 0425 let s = substitute( s, '/\*\([^*]\|\*\@!/\)*\*/', '', 'g' ) 0426 let s = substitute( s, "'[^']*'", '', 'g' ) 0427 let s = substitute( s, '"\(\\"\|[^"]\)*"', '', 'g' ) 0428 if s =~ "\\([\"']\\|/\\*\\)" 0429 " text inside a string 0430 return '(' 0431 endif 0432 if a:0 > 0 0433 if strpart( getline( '.' ), col( '.' ) - 3, 2 ) == a:1 . ' ' 0434 return "\<BS>" . a:char 0435 endif 0436 if strpart( getline( '.' ), col( '.' ) - 2, 1 ) == ' ' 0437 return a:char 0438 endif 0439 return ' ' . a:char 0440 endif 0441 if strpart( getline( '.' ), col( '.' ) - 3, 2 ) == 'if' || 0442 \strpart( getline( '.' ), col( '.' ) - 4, 3 ) == 'for' || 0443 \strpart( getline( '.' ), col( '.' ) - 6, 5 ) == 'while' || 0444 \strpart( getline( '.' ), col( '.' ) - 7, 6 ) == 'switch' || 0445 \strpart( getline( '.' ), col( '.' ) - 8, 7 ) == 'foreach' || 0446 \strpart( getline( '.' ), col( '.' ) - 8, 7 ) == 'forever' 0447 return ' (' 0448 endif 0449 return '(' 0450 endfunction 0451 0452 function! SwitchHeaderImpl() 0453 let privateheaders = '_p\.\([hH]\|hpp\|hxx\)$' 0454 let headers = '\.\([hH]\|hpp\|hxx\)$' 0455 let impl = '\.\([cC]\|cpp\|cc\|cxx\)$' 0456 let fn = expand( '%' ) 0457 if fn =~ privateheaders 0458 let list = glob( substitute( fn, privateheaders, '.*', '' ) ) 0459 elseif fn =~ headers 0460 let list = glob( substitute( fn, headers, '.*', '' ) ) 0461 elseif fn =~ impl 0462 let list = glob( substitute( fn, impl, '.*', '' ) ) 0463 endif 0464 while strlen( list ) > 0 0465 let file = substitute( list, "\n.*", '', '' ) 0466 let list = substitute( list, "[^\n]*", '', '' ) 0467 let list = substitute( list, "^\n", '', '' ) 0468 if ( ( fn =~ headers || fn =~ privateheaders ) && file =~ impl ) || ( fn =~ impl && file =~ headers ) 0469 call AskToSave() 0470 execute( "edit " . file ) 0471 return 0472 endif 0473 endwhile 0474 if ( fn =~ headers ) 0475 call AskToSave() 0476 if exists( "$implextension" ) 0477 let file = substitute( fn, headers, '.' . $implextension, '' ) 0478 else 0479 let file = substitute( fn, headers, '.cpp', '' ) 0480 endif 0481 " check for modified state of current buffer and if modified ask: 0482 " save, discard, cancel 0483 execute( 'edit '.file ) 0484 call append( 0, "#include \"".fn."\"" ) 0485 call append( 2, "// vim: sw=4 sts=4 et tw=100" ) 0486 execute( "set sw=4" ) 0487 execute( "set sts=4" ) 0488 execute( "set et" ) 0489 "execute( "set tw=100" ) 0490 elseif fn =~ impl 0491 call AskToSave() 0492 let file = substitute( fn, impl, '.h', '' ) 0493 execute( "edit ".file ) 0494 endif 0495 endfunction 0496 0497 function! SwitchPrivateHeaderImpl() 0498 let privateheaders = '_p\.\([hH]\|hpp\|hxx\)$' 0499 let headers = '\.\([hH]\|hpp\|hxx\)$' 0500 let impl = '\.\([cC]\|cpp\|cc\|cxx\)$' 0501 let fn = expand( '%' ) 0502 if fn =~ privateheaders 0503 let list = glob( substitute( fn, privateheaders, '.*', '' ) ) 0504 elseif fn =~ headers 0505 let list = glob( substitute( fn, headers, '_p.*', '' ) ) 0506 elseif fn =~ impl 0507 let list = glob( substitute( fn, impl, '_p.*', '' ) ) 0508 endif 0509 while strlen( list ) > 0 0510 let file = substitute( list, "\n.*", '', '' ) 0511 let list = substitute( list, "[^\n]*", '', '' ) 0512 let list = substitute( list, "^\n", '', '' ) 0513 if ( fn =~ privateheaders && file =~ impl ) || ( fn =~ impl && file =~ privateheaders ) || ( fn =~ headers && file =~ privateheaders ) 0514 call AskToSave() 0515 execute( "edit " . file ) 0516 return 0517 endif 0518 endwhile 0519 if ( fn =~ privateheaders ) 0520 call AskToSave() 0521 if exists( "$implextension" ) 0522 let file = substitute( fn, privateheaders, '.' . $implextension, '' ) 0523 else 0524 let file = substitute( fn, privateheaders, '.cpp', '' ) 0525 endif 0526 " check for modified state of current buffer and if modified ask: 0527 " save, discard, cancel 0528 execute( 'edit '.file ) 0529 call append( 0, "#include \"".fn."\"" ) 0530 call append( 2, "// vim: sw=4 ts=4 noet" ) 0531 execute( "set sw=4" ) 0532 execute( "set ts=4" ) 0533 elseif fn =~ impl 0534 let file = substitute( fn, impl, '_p.h', '' ) 0535 call CreatePrivateHeader( file ) 0536 elseif fn =~ headers 0537 let file = substitute( fn, headers, '_p.h', '' ) 0538 call CreatePrivateHeader( file ) 0539 endif 0540 endfunction 0541 0542 function! AskToSave() 0543 if &modified 0544 let yesorno = input("Save changes before switching file? [Y/n]") 0545 if yesorno == 'y' || yesorno == '' || yesorno == 'Y' 0546 :execute 'w' 0547 return 1 0548 else 0549 return 0 0550 endif 0551 endif 0552 return 1 0553 endfunction 0554 0555 function! CreatePrivateHeader( privateHeader ) 0556 let privateheaders = '_p\.\([hH]\|hpp\|hxx\)$' 0557 let headers = '\.\([hH]\|hpp\|hxx\)$' 0558 let impl = '\.\([cC]\|cpp\|cc\|cxx\)$' 0559 let fn = expand( '%' ) 0560 if fn =~ headers 0561 let className = ClassNameFromHeader() 0562 elseif fn =~ impl 0563 let className = ClassNameFromImpl() 0564 endif 0565 0566 if AskToSave() && fn =~ headers 0567 :normal gg 0568 " check whether a Q_DECLARE_PRIVATE is needed 0569 let dp = search( '\(^\|\s\+\)Q_DECLARE_PRIVATE\s*(\s*'.className.'\s*)' ) 0570 if dp == 0 "nothing found 0571 call search( '^\s*class\s\+\([A-Za-z0-9]\+_EXPORT\s\+\)\?[A-Za-z_]\+\s*\(:\s*[,\t A-Za-z_]\+\)\?\s*\n\?\s*{' ) 0572 call search( '{' ) 0573 let @c = className 0574 if getline(line('.')+1) =~ 'Q_OBJECT' 0575 :normal joQ_DECLARE_PRIVATE(c) 0576 else 0577 :normal oQ_DECLARE_PRIVATE(c) 0578 endif 0579 :execute 'w' 0580 endif 0581 endif 0582 execute( "edit ".a:privateHeader ) 0583 let privateClassName = className . 'Private' 0584 let header = substitute( a:privateHeader, privateheaders, '.h', '' ) 0585 0586 call IncludeGuard() 0587 " FIXME: find out what license to use 0588 call LicenseHeader( "LGPL" ) 0589 let @h = header 0590 let @p = privateClassName 0591 let @c = className 0592 :normal Gkko #include "h" class p Q_DECLARE_PUBLIC(c) protected: c *q_ptr; 0593 endfunction 0594 0595 function! ClassNameFromHeader() 0596 :normal gg 0597 call search( '^\s*class\s\+\([A-Za-z0-9]\+_EXPORT\s\+\)\?[A-Za-z_]\+\s*\(:\s*[,\t A-Za-z_]\+\)\?\s*\n\?\s*{' ) 0598 "\zs and \ze mark start and end of the matching 0599 return matchstr( getline('.'), '\s\+\zs\w\+\ze\s*\(:\|{\|$\)' ) 0600 endfunction 0601 0602 function! ClassNameFromImpl() 0603 :normal gg 0604 call search( '\s*\([A-Za-z_]\+\)::\1\s*(' ) 0605 :normal "cye 0606 return @c 0607 endfunction 0608 0609 function! IncludeGuard() 0610 let guard = toupper( substitute( expand( '%' ), '[\./]', '_', 'g' ) ) 0611 call append( '^', '#define ' . guard ) 0612 + 0613 call append( '^', '#ifndef ' . guard ) 0614 call append( '$', '#endif // ' . guard ) 0615 + 0616 endfunction 0617 0618 function! LicenseHeader( license ) 0619 let filename = $HOME . "/" . a:license . "HEADER" 0620 execute ":0r " . filename 0621 " call append( 0, system( "cat " . filename ) ) 0622 endfunction 0623 0624 function! SmartInclude() 0625 let next = nr2char( getchar( 0 ) ) 0626 if next == '"' 0627 return "#include \".h\"\<Left>\<Left>\<Left>" 0628 endif 0629 if next == '>' 0630 return "#include <>\<Left>" 0631 endif 0632 return "#include <.h>\<Left>\<Left>\<Left>" 0633 endfunction 0634 0635 function! MapIdentHeader( ident ) 0636 let header = tolower(substitute(a:ident, '::', '/', 'g')).'.h' 0637 if a:ident =~ 'Private$' 0638 let header = substitute(header, 'private', '_p', '') 0639 endif 0640 " always prefer the headers in the same directory 0641 let check = header 0642 let slash = 1 0643 while slash != -1 0644 if filereadable( check ) 0645 return '"' . check . '"' 0646 endif 0647 let slash = match( check, '/' ) 0648 let check = strpart( check, slash + 1 ) 0649 endwhile 0650 let check = tolower(substitute(a:ident, '::', '/', 'g')).'_p.h' 0651 let slash = 1 0652 while slash != -1 0653 if filereadable(check) 0654 return '"' . check . '"' 0655 endif 0656 let slash = match(check, '/') 0657 let check = strpart(check, slash + 1) 0658 endwhile 0659 0660 " Qt stuff 0661 if a:ident =~ '^Q[A-Z]' 0662 " let's try to find the module 0663 let module = '' 0664 if $QTDIR != '' 0665 if filereadable($QTDIR.'/include/QtCore/'.a:ident) 0666 let module = 'QtCore/' 0667 elseif filereadable($QTDIR.'/include/QtGui/'.a:ident) 0668 let module = 'QtGui/' 0669 elseif filereadable($QTDIR.'/include/Qt3Support/'.a:ident) 0670 let module = 'Qt3Support/' 0671 elseif filereadable($QTDIR.'/include/QtAssistant/'.a:ident) 0672 let module = 'QtAssistant/' 0673 elseif filereadable($QTDIR.'/include/QtDBus/'.a:ident) 0674 let module = 'QtDBus/' 0675 elseif filereadable($QTDIR.'/include/QtDesigner/'.a:ident) 0676 let module = 'QtDesigner/' 0677 elseif filereadable($QTDIR.'/include/QtNetwork/'.a:ident) 0678 let module = 'QtNetwork/' 0679 elseif filereadable($QTDIR.'/include/QtOpenGL/'.a:ident) 0680 let module = 'QtOpenGL/' 0681 elseif filereadable($QTDIR.'/include/QtSql/'.a:ident) 0682 let module = 'QtSql/' 0683 elseif filereadable($QTDIR.'/include/QtSvg/'.a:ident) 0684 let module = 'QtSvg/' 0685 elseif filereadable($QTDIR.'/include/QtTest/'.a:ident) 0686 let module = 'QtTest/' 0687 elseif filereadable($QTDIR.'/include/QtUiTools/'.a:ident) 0688 let module = 'QtUiTools/' 0689 elseif filereadable($QTDIR.'/include/QtXml/'.a:ident) 0690 let module = 'QtXml/' 0691 endif 0692 endif 0693 return '<'.module.a:ident.'>' 0694 elseif a:ident == 'qDebug' || 0695 \a:ident == 'qWarning' || 0696 \a:ident == 'qCritical' || 0697 \a:ident == 'qFatal' 0698 return '<QtCore/QtDebug>' 0699 elseif a:ident == 'Q_EXPORT_PLUGIN2' 0700 return '<QtCore/QtPlugin>' 0701 elseif a:ident =~ 'Q_DECLARE_INTERFACE' 0702 return '<QtCore/QObject>' 0703 elseif a:ident =~ '^QT_VERSION' || 0704 \a:ident =~ '^Q_\(W\|O\)S_' || 0705 \a:ident =~ '^Q_CC_' || 0706 \a:ident =~ '^Q_.*STRUCTOR_FUNCTION$' || 0707 \a:ident =~ '^qu\?int' || 0708 \a:ident =~ '^Q_.*_RESOURCE$' || 0709 \a:ident == 'qreal' || 0710 \a:ident == 'qAbs' || 0711 \a:ident == 'qRound' || 0712 \a:ident == 'qRound64' || 0713 \a:ident == 'qMin' || 0714 \a:ident == 'qMax' || 0715 \a:ident == 'qBound' || 0716 \a:ident == 'qVersion' || 0717 \a:ident == 'qSharedBuild' || 0718 \a:ident == 'Q_UNUSED' || 0719 \a:ident == 'Q_ASSERT' || 0720 \a:ident == 'qInstallMsgHandler' || 0721 \a:ident == 'Q_GLOBAL_STATIC' || 0722 \a:ident == 'Q_GLOBAL_STATIC_WITH_ARGS' || 0723 \a:ident == 'qFuzzyCompare' || 0724 \a:ident == 'qIsNull' || 0725 \a:ident == 'qSwap' || 0726 \a:ident =~ 'Q_DECLARE_\(FLAGS\|OPERATORS_FOR_FLAGS\|PRIVATE\|PUBLIC\)' || 0727 \a:ident == 'Q_D' || 0728 \a:ident == 'Q_Q' || 0729 \a:ident == 'Q_DISABLE_COPY' || 0730 \a:ident == 'qsrand' || 0731 \a:ident == 'qrand' 0732 return '<QtCore/QtGlobal>' 0733 0734 " Phonon stuff 0735 elseif a:ident =~ '^Phonon::[A-Z]' 0736 if a:ident =~ '^Phonon::\(NoDisc\|Cd\|Dvd\|Vcd\|.\+MetaData\|.*State\|.*Category\|.\+Error\)' 0737 return '<Phonon/Global>' 0738 endif 0739 return '<'.substitute(a:ident, '::', '/', 'g').'>' 0740 endif 0741 0742 " KDE stuff 0743 let kdeincdir = substitute(system('kde4-config --prefix'), '[\n\r]*', '', 'g').'/include/KDE/' 0744 let classname = substitute(a:ident, '^.*:', '', '') 0745 let pathfn = expand('%:p:h') 0746 if filereadable(kdeincdir.classname) && !pathfn =~ 'kdelibs' 0747 return '<'.classname.'>' 0748 elseif filereadable(kdeincdir.'Phonon/'.classname) 0749 return '<Phonon/'.classname.'>' 0750 elseif filereadable(kdeincdir.'Solid/'.classname) 0751 return '<Solid/'.classname.'>' 0752 elseif filereadable(kdeincdir.'KIO/'.classname) 0753 return '<KIO/'.classname.'>' 0754 elseif filereadable(kdeincdir.'KParts/'.classname) 0755 return '<KParts/'.classname.'>' 0756 elseif a:ident == 'K_GLOBAL_STATIC' 0757 return '<KGlobal>' 0758 elseif a:ident == 'K_EXPORT_PLUGIN' 0759 return '<KPluginLoader>' 0760 elseif a:ident =~ 'K_PLUGIN_FACTORY' 0761 return '<KPluginFactory>' 0762 elseif a:ident == 'K\(Double\|Int\)\(NumInput\|SpinBox\)' 0763 return '<knuminput.h>' 0764 elseif a:ident == 'KSharedConfig' 0765 return '<kconfig.h>' 0766 elseif a:ident == 'KConfigGroup' 0767 return '<kconfiggroup.h>' 0768 elseif a:ident == 'KListViewItem' 0769 return '<klistview.h>' 0770 elseif a:ident =~ 'kd\(Debug\|Warning\|Error\|Fatal\|Backtrace\)' 0771 return '<kdebug.h>' 0772 elseif a:ident == 'kapp' 0773 return '<kapplication.h>' 0774 elseif a:ident == 'i18n' || 0775 \a:ident == 'I18N_NOOP' 0776 return '<klocale.h>' 0777 elseif a:ident == 'locate' || 0778 \a:ident == 'locateLocal' 0779 return '<kstandarddirs.h>' 0780 elseif a:ident =~ '\(Small\|Desktop\|Bar\|MainBar\|User\)Icon\(Set\)\?' || 0781 \a:ident == 'IconSize' 0782 return '<kiconloader.h>' 0783 0784 " Standard Library stuff 0785 elseif a:ident =~ '\(std::\)\?\(cout\|cerr\|endl\)' 0786 return '<iostream>' 0787 elseif a:ident =~ '\(std::\)\?is\(alnum\|alpha\|ascii\|blank\|graph\|lower\|print\|punct\|space\|upper\|xdigit\)' 0788 return '<cctype>' 0789 elseif a:ident == 'printf' 0790 return '<cstdio>' 0791 endif 0792 0793 let check = header 0794 while 1 0795 if filereadable( check ) 0796 return '"' . check . '"' 0797 endif 0798 let slash = match( check, '/' ) 0799 if slash == -1 0800 return '<' . header . '>' 0801 endif 0802 let check = strpart( check, slash + 1 ) 0803 endwhile 0804 endfunction 0805 0806 " This is a rather dirty hack, but seems to work somehow :-) (malte) 0807 function! AddHeader() 0808 let s = getline( '.' ) 0809 let i = col( '.' ) - 1 0810 while i > 0 && strpart( s, i, 1 ) !~ '[A-Za-z0-9_:]' 0811 let i = i - 1 0812 endwhile 0813 while i > 0 && strpart( s, i, 1 ) =~ '[A-Za-z0-9_:]' 0814 let i = i - 1 0815 endwhile 0816 let start = match( s, '[A-Za-z0-9_]\+\(::[A-Z][A-Za-z0-9_]*\)*', i ) 0817 let end = matchend( s, '[A-Za-z0-9_]\+\(::[A-Z][A-Za-z0-9_]*\)*', i ) 0818 " if end > col( '.' ) 0819 " let end = matchend( s, '[A-Za-z0-9_]\+', i ) 0820 " endif 0821 let ident = strpart( s, start, end - start ) 0822 let header = MapIdentHeader(ident) 0823 let include = '#include '.header 0824 0825 let line = 1 0826 let incomment = 0 0827 let appendpos = 0 0828 let codestart = 0 0829 let similarpos = 0 0830 let similarity = 0 0831 while line <= line( '$' ) 0832 let s = getline( line ) 0833 if incomment == 1 0834 let end = matchend( s, '\*/' ) 0835 if end == -1 0836 let line = line + 1 0837 continue 0838 else 0839 let s = strpart( s, end ) 0840 let incomment = 0 0841 endif 0842 endif 0843 let s = substitute( s, '//.*', '', '' ) 0844 let s = substitute( s, '/\*\([^*]\|\*\@!/\)*\*/', '', 'g' ) 0845 if s =~ '/\*' 0846 let incomment = 1 0847 elseif s =~ '^' . include 0848 break 0849 elseif s =~ '^#include' && s !~ '\.moc"' 0850 let appendpos = line 0851 if s =~ '^#include '.header[0:similarity+1] 0852 let similarpos = line 0853 let similarity = similarity + 1 0854 while s =~ '^#include '.header[0:similarity+1] 0855 let similarity = similarity + 1 0856 endwhile 0857 if s[9:strlen(s)-2] > header[0:strlen(header)-2] 0858 let similarpos = similarpos - 1 0859 let similarity = 100 "this include belongs one line higher (assuming the order of includes already is alphabetically) 0860 endif 0861 endif 0862 elseif codestart == 0 && s !~ '^$' 0863 let codestart = line 0864 endif 0865 let line = line + 1 0866 endwhile 0867 if similarpos > 0 0868 let appendpos = similarpos 0869 endif 0870 if line == line( '$' ) + 1 0871 if appendpos == 0 0872 call append( codestart - 1, include ) 0873 call append( codestart, '' ) 0874 else 0875 call append( appendpos, include ) 0876 endif 0877 endif 0878 endfunction 0879 0880 function! AddForward() 0881 let s = getline( '.' ) 0882 let i = col( '.' ) - 1 0883 while i > 0 && strpart( s, i, 1 ) !~ '[A-Za-z0-9_:]' 0884 let i = i - 1 0885 endwhile 0886 while i > 0 && strpart( s, i, 1 ) =~ '[A-Za-z0-9_:]' 0887 let i = i - 1 0888 endwhile 0889 let start = match( s, '[A-Za-z0-9_]\+\(::[A-Za-z0-9_]\+\)*', i ) 0890 let end = matchend( s, '[A-Za-z0-9_]\+\(::[A-Za-z0-9_]\+\)*', i ) 0891 if end > col( '.' ) 0892 let end = matchend( s, '[A-Za-z0-9_]\+', i ) 0893 endif 0894 let ident = strpart( s, start, end - start ) 0895 let forward = 'class ' . ident . ';' 0896 0897 let line = 1 0898 let incomment = 0 0899 let appendpos = 0 0900 let codestart = 0 0901 while line <= line( '$' ) 0902 let s = getline( line ) 0903 if incomment == 1 0904 let end = matchend( s, '\*/' ) 0905 if end == -1 0906 let line = line + 1 0907 continue 0908 else 0909 let s = strpart( s, end ) 0910 let incomment = 0 0911 endif 0912 endif 0913 let s = substitute( s, '//.*', '', '' ) 0914 let s = substitute( s, '/\*\([^*]\|\*\@!/\)*\*/', '', 'g' ) 0915 if s =~ '/\*' 0916 let incomment = 1 0917 elseif s =~ '^' . forward 0918 break 0919 elseif s =~ '^\s*class [A-za-z0-9_]\+;' || (s =~ '^#include' && s !~ '\.moc"') 0920 let appendpos = line 0921 elseif codestart == 0 && s !~ '^$' 0922 let codestart = line 0923 endif 0924 let line = line + 1 0925 endwhile 0926 if line == line( '$' ) + 1 0927 if appendpos == 0 0928 call append( codestart - 1, forward ) 0929 call append( codestart, '' ) 0930 else 0931 call append( appendpos, forward ) 0932 endif 0933 endif 0934 endfunction 0935 0936 function! RunDiff() 0937 echo 'Diffing....' 0938 read! cvs diff -bB -I \\\#include | egrep -v '(^Index:|^=+$|^RCS file:|^retrieving revision|^diff -u|^[+-]{3})' 0939 endfunction 0940 0941 function! CreateChangeLogEntry() 0942 let currentBuffer = expand( "%" ) 0943 0944 if exists( "g:EMAIL" ) 0945 let mail = g:EMAIL 0946 elseif exists( "$EMAIL" ) 0947 let mail = $EMAIL 0948 else 0949 let mail = inputdialog( "Enter Name/Email for Changelog entry: " ) 0950 if mail == "" 0951 echo "Aborted ChangeLog edit..." 0952 return 0953 endif 0954 let g:EMAIL = mail 0955 endif 0956 0957 if bufname( "ChangeLog" ) != "" && bufwinnr( bufname( "ChangeLog" ) ) != -1 0958 execute bufwinnr( bufname( "ChangeLog" ) ) . " wincmd w" 0959 else 0960 execute "split ChangeLog" 0961 endif 0962 0963 let lastEntry = getline( nextnonblank( 1 ) ) 0964 let newEntry = strftime("%Y-%m-%d") . " " . mail 0965 0966 if lastEntry != newEntry 0967 call append( 0, "" ) 0968 call append( 0, "" ) 0969 call append( 0, newEntry ) 0970 endif 0971 0972 " like emacs, prepend the current buffer name to the entry. but unlike 0973 " emacs I have no idea how to figure out the current function name :( 0974 " (Simon) 0975 if currentBuffer != "" 0976 let newLine = "\t* " . currentBuffer . ": " 0977 else 0978 let newLine = "\t* " 0979 endif 0980 0981 call append( 2, newLine ) 0982 0983 execute "normal 3G$" 0984 endfunction 0985 0986 function! AddQtSyntax() 0987 if expand( "<amatch>" ) == "cpp" 0988 syn keyword qtKeywords signals slots emit Q_SLOTS Q_SIGNALS 0989 syn keyword qtMacros Q_OBJECT Q_WIDGET Q_PROPERTY Q_ENUMS Q_OVERRIDE Q_CLASSINFO Q_SETS SIGNAL SLOT Q_DECLARE_PUBLIC Q_DECLARE_PRIVATE Q_D Q_Q Q_DISABLE_COPY Q_DECLARE_METATYPE Q_PRIVATE_SLOT Q_FLAGS Q_INTERFACES Q_DECLARE_INTERFACE Q_EXPORT_PLUGIN2 Q_GADGET Q_SCRIPTABLE Q_INVOKABLE METHOD Q_ARG Q_RETURN_ARG Q_GLOBAL_STATIC Q_GLOBAL_STATIC_WITH_ARGS 0990 syn keyword qtCast qt_cast qobject_cast qvariant_cast qstyleoption_cast qgraphicsitem_cast 0991 syn keyword qtTypedef uchar uint ushort ulong Q_INT8 Q_UINT8 Q_INT16 Q_UINT16 Q_INT32 Q_UINT32 Q_LONG Q_ULONG Q_INT64 Q_UINT64 Q_LLONG Q_ULLONG pchar puchar pcchar qint8 quint8 qint16 quint16 qint32 quint32 qint64 quint64 qlonglong qulonglong qreal 0992 syn keyword kdeMacros ASYNC PHONON_ABSTRACTBASE PHONON_OBJECT PHONON_HEIR PHONON_ABSTRACTBASE_IMPL PHONON_OBJECT_IMPL PHONON_HEIR_IMPL PHONON_PRIVATECLASS PHONON_PRIVATEABSTRACTCLASS K_DECLARE_PRIVATE K_D K_EXPORT_PLUGIN K_PLUGIN_FACTORY K_PLUGIN_FACTORY_DEFINITION K_PLUGIN_FACTORY_DECLARATION K_GLOBAL_STATIC K_GLOBAL_STATIC_WITH_ARGS 0993 syn keyword cRepeat foreach 0994 syn keyword cRepeat forever 0995 0996 hi def link qtKeywords Statement 0997 hi def link qtMacros Type 0998 hi def link qtCast Statement 0999 hi def link qtTypedef Type 1000 hi def link kdeMacros Type 1001 endif 1002 endfunction 1003 1004 function! UpdateMocFiles() 1005 if &syntax == "cpp" 1006 let i = 1 1007 while i < 80 1008 let s = getline( i ) 1009 if s =~ '^#include ".*\.moc"' 1010 let s = substitute( s, '.*"\(.*\)\.moc"', '\1.h', '' ) 1011 if stridx( &complete, s ) == -1 1012 let &complete = &complete . ',k' . s 1013 endif 1014 break 1015 endif 1016 let i = i + 1 1017 endwhile 1018 endif 1019 endfunction 1020 1021 autocmd Syntax * call AddQtSyntax() 1022 autocmd CursorHold * call UpdateMocFiles() 1023 autocmd BufNewFile,BufRead * call SetCodingStyle() 1024 1025 " vim: sw=4 sts=4 et