diff options
Diffstat (limited to 'dot_vim/kde-devel-vim.vim')
-rw-r--r-- | dot_vim/kde-devel-vim.vim | 1029 |
1 files changed, 1029 insertions, 0 deletions
diff --git a/dot_vim/kde-devel-vim.vim b/dot_vim/kde-devel-vim.vim new file mode 100644 index 0000000..7ce39a9 --- /dev/null +++ b/dot_vim/kde-devel-vim.vim @@ -0,0 +1,1029 @@ +" To use this file, add this line to your ~/.vimrc:, w/o the dquote +" source /path/to/kde/sources/kdesdk/scripts/kde-devel-vim.vim +" +" For CreateChangeLogEntry() : If you don't want to re-enter your +" Name/Email in each vim session then make sure to have the viminfo +" option enabled in your ~/.vimrc, with the '!' flag, enabling persistent +" storage of global variables. Something along the line of +" set viminfo=%,!,'50,\"100,:100,n~/.viminfo +" should do the trick. +" +" To make use of the ,ll and ,lg shortcuts you need to have the files +" GPLHEADER and LGPLHEADER in your home directory. Their content will be +" copied as license header then. + +" Don't include these in filename completions +set suffixes+=.lo,.o,.moc,.la,.closure,.loT + +" Search for headers here +set path=.,/usr/include,/usr/local/include, +if $QTDIR != '' + let &path = &path . $QTDIR . '/include/,' + let &path = &path . $QTDIR . '/include/Qt/,' + let &path = &path . $QTDIR . '/include/QtCore/,' + let &path = &path . $QTDIR . '/include/Qt3Support/,' + let &path = &path . $QTDIR . '/include/QtAssistant/,' + let &path = &path . $QTDIR . '/include/QtDBus/,' + let &path = &path . $QTDIR . '/include/QtDesigner/,' + let &path = &path . $QTDIR . '/include/QtGui/,' + let &path = &path . $QTDIR . '/include/QtNetwork/,' + let &path = &path . $QTDIR . '/include/QtOpenGL/,' + let &path = &path . $QTDIR . '/include/QtSql/,' + let &path = &path . $QTDIR . '/include/QtSvg/,' + let &path = &path . $QTDIR . '/include/QtTest/,' + let &path = &path . $QTDIR . '/include/QtUiTools/,' + let &path = &path . $QTDIR . '/include/QtXml/,' +endif +if $KDEDIR != '' + let &path = &path . $KDEDIR . '/include/,' +endif +if $KDEDIRS != '' + let &path = &path . substitute( $KDEDIRS, '\(:\|$\)', '/include,', 'g' ) +endif +set path+=, + +" Use makeobj to build +set mp=makeobj + +" If TagList is Loaded then get a funny statusline +" Only works if kde-devel-vim.vim is loaded after taglist. +" Droping this script in ~/.vim/plugin works fine +if exists('loaded_taglist') + let Tlist_Process_File_Always=1 + set statusline=%<%f:[\ %{Tlist_Get_Tag_Prototype_By_Line()}\ ]\ %h%m%r%=%-14.(%l,%c%V%)\ %P +endif + +" Insert tab character in whitespace-only lines, complete otherwise +inoremap <Tab> <C-R>=SmartTab()<CR> + +if !exists("DisableSmartParens") +" Insert a space after ( or [ and before ] or ) unless preceded by a matching +" paren/bracket or space or inside a string or comment. Comments are only +" recognized as such if they start on the current line :-( +inoremap ( <C-R>=SmartParens( '(' )<CR> +inoremap [ <C-R>=SmartParens( '[' )<CR> +inoremap ] <C-R>=SmartParens( ']', '[' )<CR> +inoremap ) <C-R>=SmartParens( ')', '(' )<CR> +endif + +" Insert an #include statement for the current/last symbol +inoremap <F5> <C-O>:call AddHeader()<CR> + +" Insert a forward declaration for the current/last symbol +inoremap <S-F5> <C-O>:call AddForward()<CR> + +" Switch between header and implementation files on ,h +nmap <silent> ,h :call SwitchHeaderImpl()<CR> +nmap <silent> ,p :call SwitchPrivateHeaderImpl()<CR> + +" Comment selected lines on ,c in visual mode +vmap ,c :s,^,//X ,<CR>:noh<CR> +" Uncomment selected lines on ,u in visual mode +vmap ,u :s,^//X ,,<CR> + +" Insert an include guard based on the file name on ,i +nmap ,i :call IncludeGuard()<CR> + +" Insert license headers at the top of the file +nmap ,lg :call LicenseHeader( "GPL" )<CR> +nmap ,ll :call LicenseHeader( "LGPL" )<CR> +nmap ,lm :call LicenseHeader( "MIT" )<CR> + +" Insert simple debug statements into each method +nmap ,d :call InsertMethodTracer()<CR> + +" Expand #i to #include <.h> or #include ".h". The latter is chosen +" if the character typed after #i is a dquote +" If the character is > #include <> is inserted (standard C++ headers w/o .h) +iab #i <C-R>=SmartInclude()<CR> + +" Insert a stripped down CVS diff +iab DIFF <Esc>:call RunDiff()<CR> + +" mark 'misplaced' tab characters +set listchars=tab:·\ ,trail:· +set list + +set incsearch + +function! SetCodingStyle() + if &syntax == 'cmake' + call SmartParensOff() + set sw=3 + set ts=3 + set et + set tw=0 + return + endif + if ( &syntax !~ '^\(c\|cpp\|java\)$' ) + return + endif + "the path for the file + let pathfn = expand( '%:p:h' ) + if pathfn =~ 'nmm' + call SmartParensOff() + inoremap ( <C-R>=SpaceBetweenKeywordAndParens()<CR> + let g:need_brace_on_next_line = '\<\(class\|namespace\|struct\)\>' + let g:need_brace_on_same_line = '\<\(if\|else\|while\|switch\|do\|enum\|for\|try\|catch\)\>' + set sw=4 + set ts=4 + set noet + set tw=100 + elseif pathfn =~ 'kdepim' + if strlen(mapcheck('(','i')) > 0 + iunmap ( + endif + call SmartParensOn() + let g:need_brace_on_next_line = '\<\(class\|namespace\|struct\)\>' + let g:need_brace_on_same_line = '\<\(if\|else\|while\|switch\|do\|foreach\|forever\|enum\|for\|try\|catch\)\>' + set sw=2 + set sts=2 + set et + set tw=100 + elseif pathfn =~ 'kdemultimedia\/juk' + call SmartParensOff() + let g:need_brace_on_next_line = '\<\(class\|namespace\|struct\|if\|else\|while\|switch\|do\|foreach\|forever\|enum\|for\|try\|catch\)\>' + let g:need_brace_on_same_line = '' + set sw=4 + set sts=4 + set et + set tw=100 + else "if pathfn =~ '\(kdelibs\|qt-copy\)' + call SmartParensOff() + inoremap ( <C-R>=SpaceBetweenKeywordAndParens()<CR> + let g:need_brace_on_next_line = '\<\(class\|namespace\|struct\)\>' + let g:need_brace_on_same_line = '\<\(if\|else\|while\|switch\|do\|foreach\|forever\|enum\|for\|try\|catch\)\>' + set sw=4 + set sts=4 + set et + set tw=100 + endif + if ( !exists("g:noautobrace") ) + call EnableSmartLineBreak() + endif +endfunction + +function! DisableSmartLineBreak() + iunmap <CR> + iuna else +endfunction +function! EnableSmartLineBreak() + if exists("*pumvisible") + inoremap <CR> <C-R>=pumvisible() ? "\<lt>CR>" : "\<lt>ESC>:call SmartLineBreak()\<lt>CR>a\<lt>CR>"<CR> + else + inoremap <CR> <ESC>:call SmartLineBreak()<CR>a<CR> + endif + iab else <C-R>=SmartElse()<CR> +endfunction + +function! SmartElse() + "let next = nr2char( getchar( 0 ) ) + let prefix = '' + if strlen(g:need_brace_on_same_line) > 0 && 'else' =~ g:need_brace_on_same_line + if getline('.') =~ '^\s*$' + if getline(line('.') - 1) =~ '}$' + let prefix = prefix . "\<ESC>kmMjdd`MA " + elseif getline(line('.') - 1) =~ '}\s*$' + let prefix = prefix . "\<ESC>kmMjdd`MA" + endif + endif + endif + return prefix . "else\<Right>" +endfunction + +" automatic indenting is required for SmartLineBreak to work correctly +filetype indent on + +function! CreateMatchLine() + let linenum = line( '.' ) + let current_line = getline( linenum ) + " don't do magic if the cursor isn't at the end of the line or if it's + " inside a // comment + if col( '.' ) != strlen( current_line ) || match( current_line, '//' ) >= 0 + return '' + endif + " remove whitespace at the end + if match( current_line, '\s\+$' ) >= 0 + :execute ':s/\s*$//' + " the following is needed if return '' is called + :execute "normal $" + endif + let current_line = getline( linenum ) + " remove all /* */ comments + let current_line = substitute( current_line, '/\*.\{-}\*/', '', 'g' ) + " remove all strings + let current_line = substitute( current_line, "'[^']*'", '', 'g' ) + let current_line = substitute( current_line, '"\(\\"\|[^"]\)*"', '', 'g' ) + " remove all ( ) + while current_line =~ '(.*)' + let current_line = substitute( current_line, '([^()]*)', '', 'g' ) + endwhile + " prepend earlier lines until we find a ; or { + while linenum > 1 && current_line !~ ';' && current_line !~ '{.\+$' + let linenum = linenum - 1 + let prev_line = getline(linenum) + if synIDattr(synID(linenum, 1, 1), "name") == 'cComment' "inside a /* */ comment at the beginning of the line + if stridx(prev_line, '*/') == -1 + " next line please + let prev_line = '' + else + " remove everything before */ + let prev_line = substitute(prev_line, '^.*\*/', '*/', '') + endif + endif + " remove // comment + let prev_line = substitute(prev_line, '//.*$', '', '' ) + " concatenate the lines with a space in between + let current_line = prev_line.' '.current_line + " remove all /* */ comments + let current_line = substitute( current_line, '/\*.\{-}\*/', '', 'g' ) + " remove all strings + let current_line = substitute( current_line, "'[^']*'", '', 'g' ) + let current_line = substitute( current_line, '"\(\\"\|[^"]\)*"', '', 'g' ) + " remove all ( ) + while current_line =~ '(.*)' + let current_line = substitute( current_line, '([^()]*)', '', 'g' ) + endwhile + endwhile + " remove everything until the last ; + let current_line = substitute( current_line, '^.*;', '', '' ) + " remove everything until the last { which is not at the end of the line + let current_line = substitute( current_line, '^.*{\(.\+\)$', '\1', '' ) + " remove all [ ] + while current_line =~ '\[.*\]' + let current_line = substitute( current_line, '\[[^\[\]]*\]', '', 'g' ) + endwhile + " if <CR> was pressed inside ( ), [ ] or /* */ don't add braces + if current_line =~ '[(\[]' || current_line =~ '/\*' + return '' + endif + return current_line +endfunction + +function! AddClosingBrace(current_line) + if a:current_line =~ '\<enum\|class\|struct\>' + :execute "normal o};\<ESC>k" + elseif a:current_line =~ '\<namespace\>' + let namespace = substitute( a:current_line, '^.*namespace\s\+', '', '' ) + let namespace = substitute( namespace, '\s.*$', '', '' ) + :execute "normal o} // namespace " . namespace . "\<ESC>k" + else + :execute "normal o}\<ESC>k" + endif +endfunction + +function! SmartLineBreak() + if synIDattr(synID(line("."), col("."), 1), "name") == 'cComment' "inside a /* */ comment at the point where the line break occurs + return + endif + let match_line = CreateMatchLine() + if match_line == '' + return + endif + + let match_position1 = -1 + let match_position2 = -1 + if strlen(g:need_brace_on_same_line) > 0 + let match_position1 = match(match_line, g:need_brace_on_same_line) + if match_position1 > 0 + while strpart(match_line, match_position1 - 1, 1) == '#' + let old_position = match_position1 + let match_position1 = match(match_line, g:need_brace_on_same_line, match_position1 + 1) + if match_position1 == -1 + if strpart(match_line, old_position, 2) == 'if' + :execute "normal o#endif\<ESC>k$" + endif + return + endif + endwhile + endif + endif + if strlen(g:need_brace_on_next_line) > 0 && match_position1 == -1 + let match_position2 = match(match_line, g:need_brace_on_next_line) + if match_position2 > 0 + while strpart(match_line, match_position2 - 1, 1) == '#' + let old_position = match_position2 + let match_position2 = match(match_line, g:need_brace_on_same_line, match_position2 + 1) + if match_position2 == -1 + if strpart(match_line, old_position, 2) == 'if' + :execute "normal o#endif\<ESC>k$" + endif + return + endif + endwhile + endif + endif + + if match_position1 > -1 + if match_line =~ '}\s*else\>' + " make sure else is on the same line as the closing brace + if getline('.') =~ '^\s*else' + if getline(line('.') - 1) =~ '}$' + :execute "normal kA \<ESC>J" + elseif getline(line('.') - 1) =~ '}\s*$' + :execute "normal kJ" + endif + endif + endif + while getline('.') =~ '^\s*{$' + " opening brace is on its own line: move it up + :execute "normal kJ" + endwhile + if match_line =~ '{$' + if getline('.') =~ '[^ ]{$' + :execute ':s/{$/ {/' + endif + else + :execute ':s/$/ {/' + endif + call AddClosingBrace(match_line) + elseif getline('.') =~ '^\s*{$' + call AddClosingBrace('') + elseif match_position2 > -1 + if match_line =~ '{$' + :execute ':s/\s*{$//' + endif + :execute "normal o{" + call AddClosingBrace(match_line) + endif + :execute "normal $" +endfunction + +function! SmartParensOn() + inoremap ( <C-R>=SmartParens( '(' )<CR> + inoremap [ <C-R>=SmartParens( '[' )<CR> + inoremap ] <C-R>=SmartParens( ']', '[' )<CR> + inoremap ) <C-R>=SmartParens( ')', '(' )<CR> +endfunction + +function! SmartParensOff() + if strlen(mapcheck('[','i')) > 0 + iunmap ( + iunmap [ + iunmap ] + iunmap ) + endif +endfunction + +function! SmartTab() + let col = col('.') - 1 + if !col || getline('.')[col-1] !~ '\k' + return "\<Tab>" + else + return "\<C-P>" + endif +endfunction + +function! SmartParens( char, ... ) + if ! ( &syntax =~ '^\(c\|cpp\|java\)$' ) + return a:char + endif + let s = strpart( getline( '.' ), 0, col( '.' ) - 1 ) + if s =~ '//' + return a:char + endif + let s = substitute( s, '/\*\([^*]\|\*\@!/\)*\*/', '', 'g' ) + let s = substitute( s, "'[^']*'", '', 'g' ) + let s = substitute( s, '"\(\\"\|[^"]\)*"', '', 'g' ) + if s =~ "\\([\"']\\|/\\*\\)" + return a:char + endif + if a:0 > 0 + if strpart( getline( '.' ), col( '.' ) - 3, 2 ) == a:1 . ' ' + return "\<BS>" . a:char + endif + if strpart( getline( '.' ), col( '.' ) - 2, 1 ) == ' ' + return a:char + endif + return ' ' . a:char + endif + if !exists("g:DisableSpaceBeforeParen") + if a:char == '(' + if strpart( getline( '.' ), col( '.' ) - 3, 2 ) == 'if' || + \strpart( getline( '.' ), col( '.' ) - 4, 3 ) == 'for' || + \strpart( getline( '.' ), col( '.' ) - 6, 5 ) == 'while' || + \strpart( getline( '.' ), col( '.' ) - 7, 6 ) == 'switch' + return ' ( ' + endif + endif + endif + return a:char . ' ' +endfunction + +function! SpaceBetweenKeywordAndParens() + if ! ( &syntax =~ '^\(c\|cpp\|java\)$' ) + return '(' + endif + let s = strpart( getline( '.' ), 0, col( '.' ) - 1 ) + if s =~ '//' + " text inside a comment + return '(' + endif + let s = substitute( s, '/\*\([^*]\|\*\@!/\)*\*/', '', 'g' ) + let s = substitute( s, "'[^']*'", '', 'g' ) + let s = substitute( s, '"\(\\"\|[^"]\)*"', '', 'g' ) + if s =~ "\\([\"']\\|/\\*\\)" + " text inside a string + return '(' + endif + if a:0 > 0 + if strpart( getline( '.' ), col( '.' ) - 3, 2 ) == a:1 . ' ' + return "\<BS>" . a:char + endif + if strpart( getline( '.' ), col( '.' ) - 2, 1 ) == ' ' + return a:char + endif + return ' ' . a:char + endif + if strpart( getline( '.' ), col( '.' ) - 3, 2 ) == 'if' || + \strpart( getline( '.' ), col( '.' ) - 4, 3 ) == 'for' || + \strpart( getline( '.' ), col( '.' ) - 6, 5 ) == 'while' || + \strpart( getline( '.' ), col( '.' ) - 7, 6 ) == 'switch' || + \strpart( getline( '.' ), col( '.' ) - 8, 7 ) == 'foreach' || + \strpart( getline( '.' ), col( '.' ) - 8, 7 ) == 'forever' + return ' (' + endif + return '(' +endfunction + +function! SwitchHeaderImpl() + let privateheaders = '_p\.\([hH]\|hpp\|hxx\)$' + let headers = '\.\([hH]\|hpp\|hxx\)$' + let impl = '\.\([cC]\|cpp\|cc\|cxx\)$' + let fn = expand( '%' ) + if fn =~ privateheaders + let list = glob( substitute( fn, privateheaders, '.*', '' ) ) + elseif fn =~ headers + let list = glob( substitute( fn, headers, '.*', '' ) ) + elseif fn =~ impl + let list = glob( substitute( fn, impl, '.*', '' ) ) + endif + while strlen( list ) > 0 + let file = substitute( list, "\n.*", '', '' ) + let list = substitute( list, "[^\n]*", '', '' ) + let list = substitute( list, "^\n", '', '' ) + if ( ( fn =~ headers || fn =~ privateheaders ) && file =~ impl ) || ( fn =~ impl && file =~ headers ) + call AskToSave() + execute( "edit " . file ) + return + endif + endwhile + if ( fn =~ headers ) + call AskToSave() + if exists( "$implextension" ) + let file = substitute( fn, headers, '.' . $implextension, '' ) + else + let file = substitute( fn, headers, '.cpp', '' ) + endif + " check for modified state of current buffer and if modified ask: + " save, discard, cancel + execute( 'edit '.file ) + call append( 0, "#include \"".fn."\"" ) + call append( 2, "// vim: sw=4 sts=4 et tw=100" ) + execute( "set sw=4" ) + execute( "set sts=4" ) + execute( "set et" ) + execute( "set tw=100" ) + elseif fn =~ impl + call AskToSave() + let file = substitute( fn, impl, '.h', '' ) + execute( "edit ".file ) + endif +endfunction + +function! SwitchPrivateHeaderImpl() + let privateheaders = '_p\.\([hH]\|hpp\|hxx\)$' + let headers = '\.\([hH]\|hpp\|hxx\)$' + let impl = '\.\([cC]\|cpp\|cc\|cxx\)$' + let fn = expand( '%' ) + if fn =~ privateheaders + let list = glob( substitute( fn, privateheaders, '.*', '' ) ) + elseif fn =~ headers + let list = glob( substitute( fn, headers, '_p.*', '' ) ) + elseif fn =~ impl + let list = glob( substitute( fn, impl, '_p.*', '' ) ) + endif + while strlen( list ) > 0 + let file = substitute( list, "\n.*", '', '' ) + let list = substitute( list, "[^\n]*", '', '' ) + let list = substitute( list, "^\n", '', '' ) + if ( fn =~ privateheaders && file =~ impl ) || ( fn =~ impl && file =~ privateheaders ) || ( fn =~ headers && file =~ privateheaders ) + call AskToSave() + execute( "edit " . file ) + return + endif + endwhile + if ( fn =~ privateheaders ) + call AskToSave() + if exists( "$implextension" ) + let file = substitute( fn, privateheaders, '.' . $implextension, '' ) + else + let file = substitute( fn, privateheaders, '.cpp', '' ) + endif + " check for modified state of current buffer and if modified ask: + " save, discard, cancel + execute( 'edit '.file ) + call append( 0, "#include \"".fn."\"" ) + call append( 2, "// vim: sw=4 ts=4 noet" ) + execute( "set sw=4" ) + execute( "set ts=4" ) + elseif fn =~ impl + let file = substitute( fn, impl, '_p.h', '' ) + call CreatePrivateHeader( file ) + elseif fn =~ headers + let file = substitute( fn, headers, '_p.h', '' ) + call CreatePrivateHeader( file ) + endif +endfunction + +function! AskToSave() + if &modified + let yesorno = input("Save changes before switching file? [Y/n]") + if yesorno == 'y' || yesorno == '' || yesorno == 'Y' + :execute 'w' + return 1 + else + return 0 + endif + endif + return 1 +endfunction + +function! CreatePrivateHeader( privateHeader ) + let privateheaders = '_p\.\([hH]\|hpp\|hxx\)$' + let headers = '\.\([hH]\|hpp\|hxx\)$' + let impl = '\.\([cC]\|cpp\|cc\|cxx\)$' + let fn = expand( '%' ) + if fn =~ headers + let className = ClassNameFromHeader() + elseif fn =~ impl + let className = ClassNameFromImpl() + endif + + if AskToSave() && fn =~ headers + :normal gg + " check whether a Q_DECLARE_PRIVATE is needed + let dp = search( '\(^\|\s\+\)Q_DECLARE_PRIVATE\s*(\s*'.className.'\s*)' ) + if dp == 0 "nothing found + call search( '^\s*class\s\+\([A-Za-z0-9]\+_EXPORT\s\+\)[A-Za-z_]\+\s*\(:\s*[,\t A-Za-z_]\+\)\?\s*\n\?\s*{' ) + call search( '{' ) + let @c = className + if match(getline(line('.')+1), 'Q_OBJECT') + :normal joQ_DECLARE_PRIVATE(c) + else + :normal oQ_DECLARE_PRIVATE(c) + endif + :execute 'w' + endif + endif + execute( "edit ".a:privateHeader ) + let privateClassName = className . 'Private' + let header = substitute( a:privateHeader, privateheaders, '.h', '' ) + + call IncludeGuard() + " FIXME: find out what license to use + call LicenseHeader( "LGPL" ) + :set sw=4 + :set sts=4 + :set et + :set tw=100 + :normal Go// vim: sw=4 sts=4 et tw=100 + let @h = header + let @p = privateClassName + let @c = className + :normal kkko
#include "h"
class p
{
Q_DECLARE_PUBLIC(c)
protected:
c* q_ptr;
}; +endfunction + +function! ClassNameFromHeader() + :normal gg + call search( '^\s*class\s\+\([A-Za-z0-9]\+_EXPORT\s\+\)\?[A-Za-z_]\+\s*\(:\s*[,\t A-Za-z_]\+\)\?\s*\n\?\s*{' ) + "\zs and \ze mark start and end of the matching + return matchstr( getline('.'), '\s\+\zs\w\+\ze\s*\(:\|{\|$\)' ) +endfunction + +function! ClassNameFromImpl() + :normal gg + call search( '\s*\([A-Za-z_]\+\)::\1\s*(' ) + :normal "cye + return @c +endfunction + +function! IncludeGuard() + let guard = toupper( substitute( substitute( expand( '%' ), '\([^.]*\)\.h', '\1_h', '' ), '/', '_', '' ) ) + call append( '^', '#define ' . guard ) + + + call append( '^', '#ifndef ' . guard ) + call append( '$', '#endif // ' . guard ) + + +endfunction + +function! LicenseHeader( license ) + let filename = $HOME . "/" . a:license . "HEADER" + execute ":0r " . filename +" call append( 0, system( "cat " . filename ) ) +endfunction + +function! SmartInclude() + let next = nr2char( getchar( 0 ) ) + if next == '"' + return "#include \".h\"\<Left>\<Left>\<Left>" + endif + if next == '>' + return "#include <>\<Left>" + endif + return "#include <.h>\<Left>\<Left>\<Left>" +endfunction + +function! MapIdentHeader( ident ) + let header = tolower(substitute(a:ident, '::', '/', 'g')).'.h' + if a:ident =~ 'Private$' + let header = substitute(header, 'private', '_p', '') + endif + " always prefer the headers in the same directory + let check = header + let slash = 1 + while slash != -1 + if filereadable( check ) + return '"' . check . '"' + endif + let slash = match( check, '/' ) + let check = strpart( check, slash + 1 ) + endwhile + let check = tolower(substitute(a:ident, '::', '/', 'g')).'_p.h' + let slash = 1 + while slash != -1 + if filereadable(check) + return '"' . check . '"' + endif + let slash = match(check, '/') + let check = strpart(check, slash + 1) + endwhile + + " Qt stuff + if a:ident =~ '^Q[A-Z]' + " let's try to find the module + let module = '' + if $QTDIR != '' + if filereadable($QTDIR.'/include/QtCore/'.a:ident) + let module = 'QtCore/' + elseif filereadable($QTDIR.'/include/QtGui/'.a:ident) + let module = 'QtGui/' + elseif filereadable($QTDIR.'/include/Qt3Support/'.a:ident) + let module = 'Qt3Support/' + elseif filereadable($QTDIR.'/include/QtAssistant/'.a:ident) + let module = 'QtAssistant/' + elseif filereadable($QTDIR.'/include/QtDBus/'.a:ident) + let module = 'QtDBus/' + elseif filereadable($QTDIR.'/include/QtDesigner/'.a:ident) + let module = 'QtDesigner/' + elseif filereadable($QTDIR.'/include/QtNetwork/'.a:ident) + let module = 'QtNetwork/' + elseif filereadable($QTDIR.'/include/QtOpenGL/'.a:ident) + let module = 'QtOpenGL/' + elseif filereadable($QTDIR.'/include/QtSql/'.a:ident) + let module = 'QtSql/' + elseif filereadable($QTDIR.'/include/QtSvg/'.a:ident) + let module = 'QtSvg/' + elseif filereadable($QTDIR.'/include/QtTest/'.a:ident) + let module = 'QtTest/' + elseif filereadable($QTDIR.'/include/QtUiTools/'.a:ident) + let module = 'QtUiTools/' + elseif filereadable($QTDIR.'/include/QtXml/'.a:ident) + let module = 'QtXml/' + endif + endif + return '<'.module.a:ident.'>' + elseif a:ident == 'qDebug' || + \a:ident == 'qWarning' || + \a:ident == 'qCritical' || + \a:ident == 'qFatal' + return '<QtCore/QtDebug>' + elseif a:ident =~ 'Q_DECLARE_INTERFACE' + return '<QtCore/QObject>' + elseif a:ident =~ '^QT_VERSION' || + \a:ident =~ '^Q_\(W\|O\)S_' || + \a:ident =~ '^Q_CC_' || + \a:ident =~ '^Q_.*STRUCTOR_FUNCTION$' || + \a:ident =~ '^qu\?int' || + \a:ident =~ '^Q_.*_RESOURCE$' || + \a:ident == 'qreal' || + \a:ident == 'qAbs' || + \a:ident == 'qRound' || + \a:ident == 'qRound64' || + \a:ident == 'qMin' || + \a:ident == 'qMax' || + \a:ident == 'qBound' || + \a:ident == 'qVersion' || + \a:ident == 'qSharedBuild' || + \a:ident == 'Q_UNUSED' || + \a:ident == 'Q_ASSERT' || + \a:ident == 'qInstallMsgHandler' || + \a:ident == 'Q_GLOBAL_STATIC' || + \a:ident == 'Q_GLOBAL_STATIC_WITH_ARGS' || + \a:ident == 'qFuzzyCompare' || + \a:ident == 'qIsNull' || + \a:ident == 'qSwap' || + \a:ident =~ 'Q_DECLARE_\(FLAGS\|OPERATORS_FOR_FLAGS\|PRIVATE\|PUBLIC\)' || + \a:ident == 'Q_D' || + \a:ident == 'Q_Q' || + \a:ident == 'Q_DISABLE_COPY' || + \a:ident == 'qsrand' || + \a:ident == 'qrand' + return '<QtCore/QtGlobal>' + + " Phonon stuff + elseif a:ident =~ '^Phonon::[A-Z]' + if a:ident =~ '^Phonon::\(NoDisc\|Cd\|Dvd\|Vcd\|.\+MetaData\|.*State\|.*Category\|.\+Error\)' + return '<Phonon/Global>' + endif + return '<'.substitute(a:ident, '::', '/', 'g').'>' + endif + + " KDE stuff + let kdeincdir = substitute(system('kde4-config --prefix'), '[\n\r]*', '', 'g').'/include/KDE/' + let classname = substitute(a:ident, '^.*:', '', '') + let pathfn = expand('%:p:h') + if filereadable(kdeincdir.classname) && !pathfn =~ 'kdelibs' + return '<'.classname.'>' + elseif filereadable(kdeincdir.'Phonon/'.classname) + return '<Phonon/'.classname.'>' + elseif filereadable(kdeincdir.'Solid/'.classname) + return '<Solid/'.classname.'>' + elseif filereadable(kdeincdir.'KIO/'.classname) + return '<KIO/'.classname.'>' + elseif filereadable(kdeincdir.'KParts/'.classname) + return '<KParts/'.classname.'>' + elseif a:ident == 'K\(Double\|Int\)\(NumInput\|SpinBox\)' + return '<knuminput.h>' + elseif a:ident == 'KSharedConfig' + return '<kconfig.h>' + elseif a:ident == 'KConfigGroup' + return '<kconfiggroup.h>' + elseif a:ident == 'KListViewItem' + return '<klistview.h>' + elseif a:ident =~ 'kd\(Debug\|Warning\|Error\|Fatal\|Backtrace\)' + return '<kdebug.h>' + elseif a:ident == 'kapp' + return '<kapplication.h>' + elseif a:ident == 'i18n' || + \a:ident == 'I18N_NOOP' + return '<klocale.h>' + elseif a:ident == 'locate' || + \a:ident == 'locateLocal' + return '<kstandarddirs.h>' + elseif a:ident =~ '\(Small\|Desktop\|Bar\|MainBar\|User\)Icon\(Set\)\?' || + \a:ident == 'IconSize' + return '<kiconloader.h>' + + " aRts stuff + elseif a:ident =~ '\arts_\(debug\|info\|warning\|fatal\)' + return '<debug.h>' + + " Standard Library stuff + elseif a:ident =~ '\(std::\)\?\(cout\|cerr\|endl\)' + return '<iostream>' + elseif a:ident =~ '\(std::\)\?is\(alnum\|alpha\|ascii\|blank\|graph\|lower\|print\|punct\|space\|upper\|xdigit\)' + return '<cctype>' + elseif a:ident == 'printf' + return '<cstdio>' + endif + + let check = header + while 1 + if filereadable( check ) + return '"' . check . '"' + endif + let slash = match( check, '/' ) + if slash == -1 + return '<' . header . '>' + endif + let check = strpart( check, slash + 1 ) + endwhile +endfunction + +" This is a rather dirty hack, but seems to work somehow :-) (malte) +function! AddHeader() + let s = getline( '.' ) + let i = col( '.' ) - 1 + while i > 0 && strpart( s, i, 1 ) !~ '[A-Za-z0-9_:]' + let i = i - 1 + endwhile + while i > 0 && strpart( s, i, 1 ) =~ '[A-Za-z0-9_:]' + let i = i - 1 + endwhile + let start = match( s, '[A-Za-z0-9_]\+\(::[A-Z][A-Za-z0-9_]*\)*', i ) + let end = matchend( s, '[A-Za-z0-9_]\+\(::[A-Z][A-Za-z0-9_]*\)*', i ) +" if end > col( '.' ) +" let end = matchend( s, '[A-Za-z0-9_]\+', i ) +" endif + let ident = strpart( s, start, end - start ) + let header = MapIdentHeader(ident) + let include = '#include '.header + + let line = 1 + let incomment = 0 + let appendpos = 0 + let codestart = 0 + let similarpos = 0 + let similarity = 0 + while line <= line( '$' ) + let s = getline( line ) + if incomment == 1 + let end = matchend( s, '\*/' ) + if end == -1 + let line = line + 1 + continue + else + let s = strpart( s, end ) + let incomment = 0 + endif + endif + let s = substitute( s, '//.*', '', '' ) + let s = substitute( s, '/\*\([^*]\|\*\@!/\)*\*/', '', 'g' ) + if s =~ '/\*' + let incomment = 1 + elseif s =~ '^' . include + break + elseif s =~ '^#include' && s !~ '\.moc"' + let appendpos = line + if s =~ '^#include '.header[0:similarity+1] + let similarpos = line + let similarity = similarity + 1 + while s =~ '^#include '.header[0:similarity+1] + let similarity = similarity + 1 + endwhile + if s[9:strlen(s)-2] > header[0:strlen(header)-2] + let similarpos = similarpos - 1 + let similarity = 100 "this include belongs one line higher (assuming the order of includes already is alphabetically) + endif + endif + elseif codestart == 0 && s !~ '^$' + let codestart = line + endif + let line = line + 1 + endwhile + if similarpos > 0 + let appendpos = similarpos + endif + if line == line( '$' ) + 1 + if appendpos == 0 + call append( codestart - 1, include ) + call append( codestart, '' ) + else + call append( appendpos, include ) + endif + endif +endfunction + +function! AddForward() + let s = getline( '.' ) + let i = col( '.' ) - 1 + while i > 0 && strpart( s, i, 1 ) !~ '[A-Za-z0-9_:]' + let i = i - 1 + endwhile + while i > 0 && strpart( s, i, 1 ) =~ '[A-Za-z0-9_:]' + let i = i - 1 + endwhile + let start = match( s, '[A-Za-z0-9_]\+\(::[A-Za-z0-9_]\+\)*', i ) + let end = matchend( s, '[A-Za-z0-9_]\+\(::[A-Za-z0-9_]\+\)*', i ) + if end > col( '.' ) + let end = matchend( s, '[A-Za-z0-9_]\+', i ) + endif + let ident = strpart( s, start, end - start ) + let forward = 'class ' . ident . ';' + + let line = 1 + let incomment = 0 + let appendpos = 0 + let codestart = 0 + while line <= line( '$' ) + let s = getline( line ) + if incomment == 1 + let end = matchend( s, '\*/' ) + if end == -1 + let line = line + 1 + continue + else + let s = strpart( s, end ) + let incomment = 0 + endif + endif + let s = substitute( s, '//.*', '', '' ) + let s = substitute( s, '/\*\([^*]\|\*\@!/\)*\*/', '', 'g' ) + if s =~ '/\*' + let incomment = 1 + elseif s =~ '^' . forward + break + elseif s =~ '^\s*class [A-za-z0-9_]\+;' || (s =~ '^#include' && s !~ '\.moc"') + let appendpos = line + elseif codestart == 0 && s !~ '^$' + let codestart = line + endif + let line = line + 1 + endwhile + if line == line( '$' ) + 1 + if appendpos == 0 + call append( codestart - 1, forward ) + call append( codestart, '' ) + else + call append( appendpos, forward ) + endif + endif +endfunction + +function! RunDiff() + echo 'Diffing....' + read! cvs diff -bB -I \\\#include | egrep -v '(^Index:|^=+$|^RCS file:|^retrieving revision|^diff -u|^[+-]{3})' +endfunction + +function! CreateChangeLogEntry() + let currentBuffer = expand( "%" ) + + if exists( "g:EMAIL" ) + let mail = g:EMAIL + elseif exists( "$EMAIL" ) + let mail = $EMAIL + else + let mail = inputdialog( "Enter Name/Email for Changelog entry: " ) + if mail == "" + echo "Aborted ChangeLog edit..." + return + endif + let g:EMAIL = mail + endif + + if bufname( "ChangeLog" ) != "" && bufwinnr( bufname( "ChangeLog" ) ) != -1 + execute bufwinnr( bufname( "ChangeLog" ) ) . " wincmd w" + else + execute "split ChangeLog" + endif + + let lastEntry = getline( nextnonblank( 1 ) ) + let newEntry = strftime("%Y-%m-%d") . " " . mail + + if lastEntry != newEntry + call append( 0, "" ) + call append( 0, "" ) + call append( 0, newEntry ) + endif + + " like emacs, prepend the current buffer name to the entry. but unlike + " emacs I have no idea how to figure out the current function name :( + " (Simon) + if currentBuffer != "" + let newLine = "\t* " . currentBuffer . ": " + else + let newLine = "\t* " + endif + + call append( 2, newLine ) + + execute "normal 3G$" +endfunction + +function! AddQtSyntax() + if expand( "<amatch>" ) == "cpp" + syn keyword qtKeywords signals slots emit Q_SLOTS Q_SIGNALS + 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 + syn keyword qtCast qt_cast qobject_cast qvariant_cast qstyleoption_cast + 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 + syn keyword kdeKeywords k_dcop k_dcop_signals + syn keyword kdeMacros K_DCOP 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 + syn keyword cRepeat foreach + syn keyword cRepeat forever + + hi def link qtKeywords Statement + hi def link qtMacros Type + hi def link qtCast Statement + hi def link qtTypedef Type + hi def link kdeKeywords Statement + hi def link kdeMacros Type + endif +endfunction + +function! InsertMethodTracer() + :normal [[kf(yBjokDebug() << ""()" << endl; +endfunction + +function! UpdateMocFiles() + if &syntax == "cpp" + let i = 1 + while i < 80 + let s = getline( i ) + if s =~ '^#include ".*\.moc"' + let s = substitute( s, '.*"\(.*\)\.moc"', '\1.h', '' ) + if stridx( &complete, s ) == -1 + let &complete = &complete . ',k' . s + endif + break + endif + let i = i + 1 + endwhile + endif +endfunction + +autocmd Syntax * call AddQtSyntax() +autocmd CursorHold * call UpdateMocFiles() +autocmd BufNewFile,BufRead * call SetCodingStyle() + +" vim: sw=4 sts=4 et |