Wikia

Vim Tips Wiki

Copy C++ function declaration into implementation file

Talk0
1,613pages on
this wiki
Revision as of 03:33, March 27, 2011 by JohnBot (Talk | contribs)

Tip 335 Printable Monobook Previous Next

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


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.

Simplest 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

I liked the idea behind Leif's tip and I thought a command you could call in the header or source file would be good (one less thing for me to remember) Along the way I've made a slight improvement or two (no longer clobbers registers/marks for instance).

So it seems to work in most cases (single line Member functions all(?) seem to work, anything else well, doesn't) (trips on the same things Leif's implementation does of course because it IS Leif's implementation! I just moved some lines around ;) )

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)

Around Wikia's network

Random Wiki