Vim Tips Wiki
Vim Tips Wiki
Advertisement
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
Tip 335 Printable Monobook Previous Next

created 2002 · complexity basic · author Leif Wickland · version 6.0


There is a plugin for Microsoft Visual Studio called CodeWiz. It can copy a function declaration in a header, then automatically paste the implementation skeleton in the source file.

There are multiple ways to grant similar functionality in Vim.

Simple method

" Copy function declaration from a header file into the implementation file.
nmap <F5> "lYml<nowiki>[[</nowiki>kw"cye'l
nmap <F6> ma:let @n=@/<CR>"lp==:s/\<virtual\>/\/\*&\*\//e<CR>:s/\<static\>/\/\*&\*\//e<CR>:s/\s*=\s*0\s*//e<CR>:s/(.\{-}\zs=\s*[^,)]\{-1,}\>\ze\(\*\/\)\@!.*)/\/\*&\*\//e<CR>:s/(.\{-}\zs=\s*[^,)]\{-1,}\>\ze\(\*\/\)\@!.*)/\/\*&\*\//e<CR>:s/(.\{-}\zs=\s*[^,)]\{-1,}\>\ze\(\*\/\)\@!.*)/\/\*&\*\//e<CR>:let @/=@n<CR>'ajf(b"cPa::<Esc>f;s<CR>{<CR>}<CR><Esc>kk

To use this, source it into Vim, for example by placing it in your vimrc. Then, press F5 (in normal mode) with the cursor on the line in the header file that declares the function you wish to copy. Then go to your source file and hit F6 (in normal mode) with the cursor where you want to insert the function implementation.

Method with namespaces

The above tip does not support namespaces. The script below builds upon the above idea to implement namespace support, along with more portable and reliable ways of determining the class and namespace name.

nmap <F5> :CopyDefinition<CR>
nmap <F6> :ImplementDefinition<CR>
command! CopyDefinition :call s:GetDefinitionInfo()
command! ImplementDefinition :call s:ImplementDefinition()
function! s:GetDefinitionInfo()
  exe 'normal ma'
  " Get class
  call search('^\s*\<class\>', 'b')
  exe 'normal ^w"ayw'
  let s:class = @a
  let l:ns = search('^\s*\<namespace\>', 'b')
  " Get namespace
  if l:ns != 0
    exe 'normal ^w"ayw'
    let s:namespace = @a
  else
    let s:namespace = ''
  endif
  " Go back to definition
  exe 'normal `a'
  exe 'normal "aY'
  let s:defline = substitute(@a, ';\n', '', '')
endfunction

function! s:ImplementDefinition()
  call append('.', s:defline)
  exe 'normal j'
  " Remove keywords
  s/\<virtual\>\s*//e
  s/\<static\>\s*//e
  if s:namespace == ''
    let l:classString = s:class . "::"
  else
    let l:classString = s:namespace . "::" . s:class . "::"
  endif
  " Remove default parameters
  s/\s\{-}=\s\{-}[^,)]\{1,}//e
  " Add class qualifier
  exe 'normal ^f(bi' . l:classString
  " Add brackets
  exe "normal $o{\<CR>\<TAB>\<CR>}\<CR>\<ESC>kkkk"
  " Fix indentation
  exe 'normal =4j^'
endfunction

It is recommended that you copy this into a .vim file, and place it in your plugins directory as opposed to pasting it directly in your .vimrc file.

The script is used similar to the one above. Press F5 (in normal mode) with the cursor on the line in the header file that declares the function you wish to copy. Then, go to your source file and hit F6 (in normal mode) with the cursor where you want to insert the function implementation.

Comments

The tip seems to work in most cases (single line Member functions all(?) seem to work, anything else well, doesn't).

Several things can still be improved:

  • There is no need for using registers.
  • We can easily find the class name (if any) -- easy because I'd already done this for my set of C++ ftplugins.
  • We can accept prototypes written on several lines (this first version only supports parameters written on several lines).

There are still some other things that can be done to improve this ftplugin, but here is a first (third) shot.

The resulting script is now part of my C&C++ ftplugins suite.

--Luc Hermitte 13:04, 24 July 2007 (UTC)
Advertisement