Vim Tips Wiki
(Adjust previous/next navigation)
(Remove html character entities)
Line 12: Line 12:
 
|category2=C++
 
|category2=C++
 
}}
 
}}
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 [[User:Luc Hermitte|Luc Hermitte]]'s [http://hermitte.free.fr/vim/c.php lh-cpp-ftplugins], I found my way through.
+
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 [[User:Luc Hermitte|Luc Hermitte]]'s [http://hermitte.free.fr/vim/c.php lh-cpp-ftplugins], I found my way through.
   
 
Here is what I got:
 
Here is what I got:
Line 32: Line 32:
 
else
 
else
 
exe 'return "' .
 
exe 'return "' .
\ substitute( a:seq, '\\&lt;\(.\{-}\)\\&gt;', '"."\\&lt;\1&gt;"."', 'g' ) . '"'
+
\ substitute( a:seq, '\\<\(.\{-}\)\\>', '"."\\<\1>"."', 'g' ) . '"'
 
endif
 
endif
 
endfunction
 
endfunction
Line 38: Line 38:
 
" Create abbreviation suitable for MapNoContext
 
" Create abbreviation suitable for MapNoContext
 
function! Iab (ab, full)
 
function! Iab (ab, full)
exe "iab &lt;silent&gt; &lt;buffer&gt; ".a:ab." &lt;C-R&gt;=MapNoContext('".
+
exe "iab <silent> <buffer> ".a:ab." <C-R>=MapNoContext('".
\ a:ab."', '".escape (a:full.'&lt;C-R&gt;=Eatchar()&lt;CR&gt;', '&lt;&gt;\"').
+
\ a:ab."', '".escape (a:full.'<C-R>=Eatchar()<CR>', '<>\"').
\"')&lt;CR&gt;"
+
\"')<CR>"
 
endfunction
 
endfunction
   
 
call Iab('#d', '#define ')
 
call Iab('#d', '#define ')
call Iab('#i', '#include &lt;&gt;&lt;Left&gt;')
+
call Iab('#i', '#include <><Left>')
call Iab('#I', '#include ""&lt;Left&gt;')
+
call Iab('#I', '#include ""<Left>')
call Iab('printf', 'printf ("\n");&lt;C-O&gt;?\&lt;CR&gt;')
+
call Iab('printf', 'printf ("\n");<C-O>?\<CR>')
call Iab('if', 'if ()&lt;CR&gt;{&lt;CR&gt;}&lt;Left&gt;&lt;C-O&gt;?)&lt;CR&gt;')
+
call Iab('if', 'if ()<CR>{<CR>}<Left><C-O>?)<CR>')
call Iab('for', 'for (;;)&lt;CR&gt;{&lt;CR&gt;}&lt;C-O&gt;?;;&lt;CR&gt;')
+
call Iab('for', 'for (;;)<CR>{<CR>}<C-O>?;;<CR>')
call Iab('while', 'while ()&lt;CR&gt;{&lt;CR&gt;}&lt;C-O&gt;?)&lt;CR&gt;')
+
call Iab('while', 'while ()<CR>{<CR>}<C-O>?)<CR>')
call Iab('else', 'else&lt;CR&gt;{&lt;CR&gt;x;&lt;CR&gt;}&lt;C-O&gt;?x;&lt;CR&gt;&lt;Del&gt;&lt;Del&gt;')
+
call Iab('else', 'else<CR>{<CR>x;<CR>}<C-O>?x;<CR><Del><Del>')
call Iab('ifelse', 'if ()&lt;CR&gt;{&lt;CR&gt;}&lt;CR&gt;else&lt;CR&gt;{&lt;CR&gt;}&lt;C-O&gt;?)&lt;CR&gt;')
+
call Iab('ifelse', 'if ()<CR>{<CR>}<CR>else<CR>{<CR>}<C-O>?)<CR>')
call Iab('intmain', 'int&lt;CR&gt;main (int argc, char **argv)&lt;CR&gt;'.
+
call Iab('intmain', 'int<CR>main (int argc, char **argv)<CR>'.
\ '{&lt;CR&gt;x;&lt;CR&gt;return 0;&lt;CR&gt;}&lt;CR&gt;&lt;C-O&gt;?x;&lt;CR&gt;&lt;Del&gt;&lt;Del&gt;')
+
\ '{<CR>x;<CR>return 0;<CR>}<CR><C-O>?x;<CR><Del><Del>')
 
</pre>
 
</pre>
   
Line 64: Line 64:
 
May I ask why this "simplified" version? Why get rid of the support of markers (aka placeholders)?
 
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 -&gt; e.g. for "if":
+
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":
   
 
<pre>
 
<pre>
Inoreabbr &lt;buffer&gt; &lt;silent&gt; if &lt;C-R&gt;=Def_AbbrC('if ',
+
Inoreabbr <buffer> <silent> if <C-R>=Def_AbbrC('if ',
\ '\&lt;c-f\&gt;if (!cursorhere!) {\n!mark!\n}!mark!')&lt;cr&gt;
+
\ '\<c-f\>if (!cursorhere!) {\n!mark!\n}!mark!')<CR>
   
" Surround the visual selection with curly-brackets -&gt; instructions-block
+
" Surround the visual selection with curly-brackets -> instructions-block
vnoremap &lt;buffer&gt; &lt;silent&gt; &lt;localleader&gt;if
+
vnoremap <buffer> <silent> <localleader>if
\ &lt;c-\&gt;&lt;c-n&gt;@=Surround('if (!cursorhere!) {', '}!mark!',
+
\ <c-\><c-n>@=Surround('if (!cursorhere!) {', '}!mark!',
\ 1, 1, '', 1, 'if ')&lt;cr&gt;
+
\ 1, 1, '', 1, 'if ')<CR>
   
" Surround the visual selection with "round"-brackets -&gt; condition
+
" Surround the visual selection with "round"-brackets -> condition
vnoremap &lt;buffer&gt; &lt;silent&gt; &lt;LocalLeader&gt;&lt;localleader&gt;if
+
vnoremap <buffer> <silent> <LocalLeader><localleader>if
\ &lt;c-\&gt;&lt;c-n&gt;@=Surround('if (', '!cursorhere!) {\n!mark!\n}!mark!',
+
\ <c-\><c-n>@=Surround('if (', '!cursorhere!) {\n!mark!\n}!mark!',
\ 0, 1, '', 1, 'if ')&lt;cr&gt;
+
\ 0, 1, '', 1, 'if ')<CR>
   
nmap &lt;buffer&gt; &lt;LocalLeader&gt;if V&lt;LocalLeader&gt;if
+
nmap <buffer> <LocalLeader>if V<LocalLeader>if
nmap &lt;buffer&gt; &lt;LocalLeader&gt;&lt;LocalLeader&gt;if V&lt;LocalLeader&gt;&lt;LocalLeader&gt;if
+
nmap <buffer> <LocalLeader><LocalLeader>if V<LocalLeader><LocalLeader>if
 
</pre>
 
</pre>
   

Revision as of 09:32, 29 September 2008

Tip 842 Printable Monobook Previous Next

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

Luc Hermitte