I use Vim for writing C++, and I have quite a few #include<> statements, comments, etc. that I must include in each new file I create. I've added

autocmd BufNewFile *.cpp r C:\(full file path of skeleton text file) 

to my vimrc, because I heard this creates a buffer with the text I need in it. How do I go about adding this text to a new file? Is there an easy way to do this from the buffer, or is there another easy way to go about doing this? I've also heard a little about template plugins. Is there a very simple one that could do this for me?

  • 1
    Did you try out editing a new C++ file after adding this autocmd, and creating the skeleton file?
    – muru
    Commented Feb 4, 2016 at 1:00
  • 1
    I tried creating a new file with a .cpp file extension and editing it with Vim. Upon opening it for editing, it was still blank is there another step I need to do? Commented Feb 4, 2016 at 1:12
  • 2
    No, you should have seen the contents of the skeleton file already included. What if you manually run :r C:\(full file path of skeleton text file)? Do you get any errors?
    – muru
    Commented Feb 4, 2016 at 1:14
  • 3
    @electriccello Ah, :enew won't work, but :e newfile.cpp should work if newfile.cpp didn't already exist (even if empty).
    – muru
    Commented Feb 4, 2016 at 1:28
  • 5
    The reason :enew wont work is because you're editing a new, unnamed buffer, and then saving it as a .cpp file. BufNewFile only triggers if you're editing a new file with the target filename. Commented Feb 4, 2016 at 1:40

3 Answers 3


Skeleton text from an existing file can be added to a new file by inserting the line

autocmd BufNewFile *.cpp r C:\(full file path of skeleton text file)

into the vimrc. The BufNewFile event does not work if the new file is created in two steps using :enew then :sav filename. Instead, creating a new file using :e filename triggers the BufNewFile event's autocommand in the vimrc, adding the contents of the skeleton text file to the newly created file.

  • 2
    Also see :help template. Commented Aug 23, 2018 at 12:04
  • To prevent my .vimrc from being congested, is there any other location in the ~/.vim/ hierarchy I can put it into? Commented Jun 7, 2019 at 20:45
  • This also adds an additional blank line on the top in the new file. Commented Jun 8, 2019 at 4:32

Indeed, template expander plugins will help you in this task. :read is the step 0 of template expander plugins.

For instance, mu-template will try to include foo.h from foo.cpp if foo.h is detected. It'll also permit to expand headers with dynamic data within them (date, author, license/copyright, etc).


To setup default skeleton for all filetypes and customize it for specific project:

function! s:load_skeleton(type)
  " do nothing if no filetype
  if empty(a:type) | return | endif

  " glob every directory of rtp to search for skeleton/filetype
  let skeletons = globpath(&rtp, 'skeleton/' . a:type, 0, 1)
  if empty(skeletons) | return | endif

  " read last skeleton into 1st line.
  exe '0read ' . skeletons[-1]

augroup aug_skeleton

  " BufNewFile event is trigged when you edit a new file.
  autocmd BufNewFile * call s:load_skeleton(&filetype)
augroup end

Put default skeletons under ~/.vim/skeleton, eg: ~/.vim/skeleton/vim, ~/.vim/skeleton/sh.

Put project specific skeleton under balabala/project/.vim/skeleton. As long as ~/.vim appears before balabala/project/.vim in :h rtp, balabala/project/skeleton/ will be used as skeleton directory.

  • What's the reason for the first two lines of the augroup?
    – bongbang
    Commented Apr 30, 2022 at 20:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.