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