created January 4, 2005 · complexity intermediate · author Vladimír Marek · version 6.0
I have been seeking for some 'perfect' abbrevs for long time. They have to work in C code, but not in strings or comments. They have to place cursor inside the function and leave Vim in insert mode, so that I can just continue typing. They have to respect my indenting, and they have to produce exactly the same results when I start the abbreviation by <C-]> or just by <Space> (no bothersome space should appear). And they should be easy to maintain. I thought that this is not possible, but after seeing Luc Hermitte's lh-cpp-ftplugins, I found my way through.
Here is what I got:
" Help delete character if it is 'empty space' " stolen from Vim manual function! Eatchar() let c = nr2char(getchar()) return (c =~ '\s') ? '' : c endfunction " Replace abbreviation if we're not in comment or other unwanted places " stolen from Luc Hermitte's excellent http://hermitte.free.fr/vim/ function! MapNoContext(key, seq) let syn = synIDattr(synID(line('.'),col('.')-1,1),'name') if syn =~? 'comment\|string\|character\|doxygen' return a:key else exe 'return "' . \ substitute( a:seq, '\\<\(.\{-}\)\\>', '"."\\<\1>"."', 'g' ) . '"' endif endfunction " Create abbreviation suitable for MapNoContext function! Iab (ab, full) exe "iab <silent> <buffer> ".a:ab." <C-R>=MapNoContext('". \ a:ab."', '".escape (a:full.'<C-R>=Eatchar()<CR>', '<>\"'). \"')<CR>" endfunction call Iab('#d', '#define ') call Iab('#i', '#include <><Left>') call Iab('#I', '#include ""<Left>') call Iab('printf', 'printf ("\n");<C-O>?\<CR>') call Iab('if', 'if ()<CR>{<CR>}<Left><C-O>?)<CR>') call Iab('for', 'for (;;)<CR>{<CR>}<C-O>?;;<CR>') call Iab('while', 'while ()<CR>{<CR>}<C-O>?)<CR>') call Iab('else', 'else<CR>{<CR>x;<CR>}<C-O>?x;<CR><Del><Del>') call Iab('ifelse', 'if ()<CR>{<CR>}<CR>else<CR>{<CR>}<C-O>?)<CR>') call Iab('intmain', 'int<CR>main (int argc, char **argv)<CR>'. \ '{<CR>x;<CR>return 0;<CR>}<CR><C-O>?x;<CR><Del><Del>')
For me it's working, I also tried it with plain Vim (without .vimrc), but it may depend on some settings.
Comments[]
You can look at Dr Chip's C Stubs plugin "drcstubs.vim".
May I ask why this "simplified" version? Why get rid of the support of markers (aka placeholders)?
BTW, with my last version of lh-cpp (not yet uploaded), the mappings and abbreviations, are much more easier to maintain -> e.g. for "if":
Inoreabbr <buffer> <silent> if <C-R>=Def_AbbrC('if ', \ '\<c-f\>if (!cursorhere!) {\n!mark!\n}!mark!')<CR> " Surround the visual selection with curly-brackets -> instructions-block vnoremap <buffer> <silent> <localleader>if \ <c-\><c-n>@=Surround('if (!cursorhere!) {', '}!mark!', \ 1, 1, '', 1, 'if ')<CR> " Surround the visual selection with "round"-brackets -> condition vnoremap <buffer> <silent> <LocalLeader><localleader>if \ <c-\><c-n>@=Surround('if (', '!cursorhere!) {\n!mark!\n}!mark!', \ 0, 1, '', 1, 'if ')<CR> nmap <buffer> <LocalLeader>if V<LocalLeader>if nmap <buffer> <LocalLeader><LocalLeader>if V<LocalLeader><LocalLeader>if