In XCode, there is an add-on called vvdocument, which can detect three / hits, and transfer /// into:

*  @author Robbie Yi JIANG, 29-Jan-2016 14:01:45

How can I do this in Vim.


The method in my earlier answer doesn't transform well to dynamic content. This is where snippet plugins like UltiSnips and SnipMate come in. I'll provide a demo of UltiSnips here. Install it using your favourite method from How do I install a plugin in vim/vi?

Now, make an UltiSnips directory in your .vim or _vimfiles directory. In it, place a c.snippet file containing:

snippet /// "My header" A
*  @author Robbie Yi JIANG, `date +'%d-%b-%Y %T'`

Now, if you open a C file and type ///, it should automatically get replaced with the header, including the current date and time. That's it!

Usually, UltiSnips inserts a snippet when you press Tab. Here, we have specified that the snippet should be automatically entered - that's what the A at the end of the first line indicates. Checkout :help UltiSnips-syntax for more information on writing snippets.

Most people, however, start off with a collection of snippets, such as vim-snippets. There are too many to describe here, but you might some of them very useful.

  • 3
    +1 for Ultisnips. You can also specify jump locations and default locations for your cursor after expanding a snippet. Feb 18 '16 at 10:33

One way would be to create a file containing this snippet, and read it when you type ///.

For example, create ~/.vim/snippets/my_header.snip containing this header. Then define this mapping:

inoremap /// <esc>:r ~/.vim/snippets/my_header.snip<cr>i


inoremap /// <esc>:call append(line('.')-1, readfile(expand('~/.vim/snippets/my_header.snip')))<cr>i

In the first mapping, your cursor will be placed on the first line of the inserted text; and in the second, the cursor will be placed below the inserted text.

Perhaps the simplest mapping, in terms of jumping around modes, is:

inoremap /// <c-r><c-o>=readfile(expand('~/.vim/snippets/my_header.snip'))<cr>

For more general usage, you might want to look into snippet plugins. UltiSnips and SnipMate are two popular ones. I don't use either, so I won't recommend one.


Write a function that returns the string and call it.

function! InsertHeader()
    let l:header = "/*!\n"
                \. "* @author Robbie Yi JIANG, " . strftime('%d-%b-%Y %H:%M:%S') . "\n"
                \. "*\n"
                \. "* \n"
                \. "*/\n"
    return l:header

inoremap /// <C-R>=InsertHeader()<Enter><C-O>2k<C-O>$

The details of strftime depend on your platform, if you're not on Windows and it's not working then you'll need to man strftime to figure out the arguments.

This works in insert mode but it does weird things to forward-slash processing. If you're doing C++-style // comments, the second slash won't come out until you type a space or something after it.

The <C-R>= inserts an expression at the cursor position. The InsertHeader()<Enter> bit is the expression that gets evaluated. I build up the string line by line in the function, . is string concatenation and \ is the line continuation character (where continuation says "combine this with the previous line," in contrast to how C and its family do it). Finally, two <C-O> operations, one to move up two lines and one to move to the end of the line where presumably a file comment is going to be entered; note the space at the end of the string in the fourth line of l:header.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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