Vim Tips Wiki
(Started organizing the page.)
(Fixed source tags)
Line 22: Line 22:
 
The simplest method is from a tip on VIM.org submitted by Leif Wickland on October 1, 2002.
 
The simplest method is from a tip on VIM.org submitted by Leif Wickland on October 1, 2002.
   
<source>
+
<source lang="vim">
 
" Copy Function Declaration from a header file into the implementation file.
 
" Copy Function Declaration from a header file into the implementation file.
 
nmap <F5> "lYml<nowiki>[[</nowiki>kw"cye'l
 
nmap <F5> "lYml<nowiki>[[</nowiki>kw"cye'l
Line 36: Line 36:
 
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 ;) )
 
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 ;) )
   
  +
<source lang="vim">
<code>
 
 
" vim:ff=unix ts=4 ss=4
 
" vim:ff=unix ts=4 ss=4
 
" vim60:fdm=marker
 
" vim60:fdm=marker
Line 219: Line 219:
 
" void Test_Member_Function_B3(int _iSomeNum2/*5*/, char * _cpStr/*"Yea buddy!"*/);
 
" void Test_Member_Function_B3(int _iSomeNum2/*5*/, char * _cpStr/*"Yea buddy!"*/);
 
:command! -nargs=0 GHPH call <SID>GrabFromHeaderPasteInSource(0,0,3)
 
:command! -nargs=0 GHPH call <SID>GrabFromHeaderPasteInSource(0,0,3)
</code>
+
</source>
   
 
Several things can still be improved:
 
Several things can still be improved:

Revision as of 07:29, 1 March 2011

Tip 335 Printable Monobook Previous Next

created October 1, 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.

Simple Method

The simplest method is from a tip on VIM.org submitted by Leif Wickland on October 1, 2002.

" 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.


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) an besides I knew just how I wanted to do it! Along the way I've made a slight improvement or two (no longer clobbers registers/marks for instance). This is formatted to stuff into a file and drop into your plugin directory.

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 ;) )

" vim:ff=unix ts=4 ss=4
" vim60:fdm=marker
" \file copycppdectoimp.vim
"
" \brief From Vim-Tip #335: Copy C++ function declaration into implementation file
" by Leif Wickland as of Vim: 5.7
" \note See: http://vim.sourceforge.net/tip_view.php?tip_id=335
"
" \author Leif Wickland
" \author (Mangled by) Robert KellyIV <Feral>
" \note This file and work is based totally on Leif Wickland's Vim-TIP#335
" \date Tue, 01 Oct 2002 21:03 Pacific Daylight Time
" \version $Id$
" Version: 0.2
" History: {{{
" [Feral:274/02@20:42] 0.2
" Improvments: from Leif's Tip (#335):
" * can handle any number of default prams (as long as they are all
" on the same line!)
" * Options on how to format default params, virtual and static.
" (see below) TextLink:||@|Prototype:|
" * placed commands into a function (at least I think it's an
" improvement ;) )
" * Improved clarity of the code, at least I hope.
" * Preserves registers/marks. (rather does not use marks), Should
" not dirty anything.
" * All normal operations do not use mappings i.e. :normal!
" (I have Y mapped to y$ so Leif's mappings could fail.)
"
" Limitations:
" * fails on multi line declorations. All prams must be on the same
" line.
" * fails for non member functions. (though not horibly, just have
" to remove the IncorectClass:: text...
" 0.1
" Leif's original Vim-Tip #335
" }}}

if exists("loaded_copycppdectoimp")
  finish
endif
let loaded_copycppdectoimp = 1

"{{{ [basic] Tip #335: Copy C++ function declaration into implementation file
" tip karma Rating 5/2, Viewed by 49
"
"created: October 1, 2002 6:47 complexity: basic
"author: Leif Wickland as of Vim: 5.7
"
"There's a handy plugin for MS Visual Studio called CodeWiz that has a nifty ability to copy a function declaration and deposit it into the implementation file on command. I actually missed while using vim, so I wrote an approximation of that capability. This isn't foolproof, but it works alright.
"
"" 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, 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 implementation file and hit F6 in normal mode with the cursor where you want the function implementation inserted.
" }}}

function! <SID>GrabFromHeaderPasteInSource(howtoshowVirtual, howtoshowStatic, howtoshowDefaultParams) "{{{
" echo confirm(expand("%:e"))
 if expand("%:e") ==? "h"

"nmap <F5> "lYml<nowiki>[[</nowiki>kw"cye'l
" execute ":normal! ml"
 let SaveL = line(".")
 let SaveC = virtcol(".")

 " into l yank the entire line
 " ([Feral:274/02@19:06] MY Y is mapped to y$, so I account for that below)
 :let Was_Reg_l = @l
" execute ':normal! "lY'
 execute ':normal! 0"ly$'
" echo confirm(@l)
 :let s:LineWithDecloration = @l
 :let @l=Was_Reg_l

 " [Feral:274/02@14:41] this works peachy for a member function, not so
 " well for a normal function, how can we fix this? Or do we bother?
 execute ":normal! <nowiki>[[</nowiki>"
 execute ":normal! kw"
 :let Was_Reg_c = @c
 execute ':normal! "cye'
 :let s:ClassName = @c
 :let @c=Was_Reg_c

" execute ":normal! 'l"
 :execute ":normal! ".SaveL."G"
 :execute ":normal! ".SaveC."|"

" echo confirm(s:ClassName)
 else
" echo confirm(s:ClassName)
 let SaveL = line(".")
 let SaveC = virtcol(".")
" :execute ':normal! ma'
 :let Was_Reg_n = @n
 :let @n=@/
 :execute ':normal! O'.s:LineWithDecloration
 :execute ':normal! =='

 " XXX if you want virtual commented in the implimentation:
 if a:howtoshowVirtual == 1
 :s/\<virtual\>/\/\*&\*\//e
 else
 " XXX else, remove virtual and any spaces/tabs after it.
 :s/\<virtual\>\s*//e
 endif

 " XXX if you want static commented in the implimentation:
 if a:howtoshowStatic == 1
 :s/\<static\>/\/\*&\*\//e
 else
 " XXX else, remove static and any spaces/tabs after it.
 :s/\<static\>\s*//e
 endif

 " wipe out a pure virtual thingie-ma-bob. (technical term? (= )
 :s/\s*=\s*0\s*//e

 " Handle default params, if any.
 if a:howtoshowDefaultParams == 1
 " Remove the default param assignments.
 :s/\s\{-}=\s\{-}[^,)]\{1,}//ge
 else
 " Comment the default param assignments.
 :s/\s\{-}\(=\s\{-}[^,)]\{1,}\)/\/\*\1\*\//ge

 if a:howtoshowDefaultParams == 3
 " Remove the = and any spaces to the left or right.
 :s/\s*=\s*//ge
 endif
 endif

 :let @/=@n
 :let @n=Was_Reg_n
 :execute ":normal! ".SaveL."G"
 :execute ":normal! ".SaveC."|"
 :execute ':normal! f(b'
 :execute ':normal! i'.s:ClassName.'::'

 " find the ending ; and replace it with a brace structure on the next line.
 :execute ":normal! f;s\<CR>{\<CR>}\<CR>\<Esc>kk"
 endif
endfunc
"}}}

" given:
" virtual void Test_Member_Function_B3(int _iSomeNum2 = 5, char * _cpStr = "Yea buddy!");

" Prototype:
"GrabFromHeaderPasteInSource(VirtualFlag, StaticFlag, DefaultParamsFlag)

" VirtualFlag:
" 1: if you want virtual commented in the implimentation:
" /*virtual*/ void Test_Member_Function_B3(int _iSomeNum2 = 5, char * _cpStr = "Yea buddy!");
" else: remove virtual and any spaces/tabs after it.
" void Test_Member_Function_B3(int _iSomeNum2 = 5, char * _cpStr = "Yea buddy!");

" StaticFlag:
" 1: if you want static commented in the implementation:
" Same as virtual, save deal with static
" else: remove static and any spaces/tabs after it.
" Same as virtual, save deal with static

" DefaultParamsFlag:
" 1: If you want to remove default param reminders, i.e.
" Test_Member_Function_B3(int _iSomeNum2, char * _cpStr);
" 2: If you want to comment default param assignments, i.e.
" Test_Member_Function_B3(int _iSomeNum2/*= 5*/, char * _cpStr/*= "Yea buddy!"*/);
" 3: Like 2 but, If you do not want the = in the comment, i.e.
" Test_Member_Function_B3(int _iSomeNum2/*5*/, char * _cpStr/*"Yea buddy!"*/);
"
" Examples:
" smallest implimentation:
" void Test_Member_Function_B3(int _iSomeNum2, char * _cpStr);
":command! -nargs=0 GHPH call <SID>GrabFromHeaderPasteInSource(0,0,1)
" Verbose...:
" /*virtual*/ void Test_Member_Function_B3(int _iSomeNum2/*5*/, char * _cpStr/*"Yea buddy!"*/);
":command! -nargs=0 GHPH call <SID>GrabFromHeaderPasteInSource(1,1,3)
" What I like:
" void Test_Member_Function_B3(int _iSomeNum2/*5*/, char * _cpStr/*"Yea buddy!"*/);
:command! -nargs=0 GHPH call <SID>GrabFromHeaderPasteInSource(0,0,3)

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)