I want to insert a skeleton to .sh files without any plugins. Vim complains that it can't find the file ~/.vim/skeletons/sh<CR><ESC>l. How do I indicate that /sh is the end of the filename and that <CR><ESC>l are key strokes to execute after reading?

augroup filetype_sh
    autocmd BufNewFile *.sh 0:read ~/.vim/skeletons/sh<CR><ESC>l
augroup END

I want to move to the bottom of the skeleton after inserting the file. I tried this:

augroup filetype_sh
    autocmd BufNewFile *.sh 0:read ~/.vim/skeletons/sh | G
augroup END

and Vim complained "Ambiguous use of user-defined command: G".


In general, when you want to execute more than one command on a single line you must separate the commands with the bar aka pipe character |. Note, though, that there are some commands that can't be followed with |. They are listed under :h :bar. Fortunately, in your case that doesn't apply so we will do something like...

autocmd BufNewFile *.sh :0read {filename} | second-command

(I've moved the colon because that's not a common placement for it. Leaving out the colon is valid, too. I'm not typing out your actual filename just to keep things simple.)

So what's the second command? We learned that you want to navigate to the end of the buffer. You, naturally, thought of using G. Problem is that that's a Normal mode command and we are in Command-line mode (just like when you press : from Normal mode). In command-line mode we usually use "Ex" commands and the Ex command to navigate to end-of-buffer is $. So...

autocmd BufNewFile *.sh :0read {filename} | $

And that's it. But what if you needed to do some other stuff that is easy in Normal mode but not so obvious how to do from the command-line? Well, there's an Ex command called normal that takes Normal mode commands from a command-line context. So you actually could use G like so:

autocmd BufNewFile *.sh :0read {filename} | norm! G

norm is an abbreviation for normal and the ! ensures that we execute the native command and not a remapping that you may have configured. (You would, of course, leave off the ! if you wanted to execute the mapped version.)

  • Jumping to mark '] is also an option, it will be set to the last line of the file that's been read into this buffer. For an empty buffer this will be essentially the same as $ or norm! G, but it might be relevant if this gets triggered on a non-empty file for some reason (e.g. adding standard license/copyright header to source files when absent.) – filbranden Dec 7 '20 at 17:40
  • 1
    '] seems a bit far afield for this particular question/answer. The floodgates could be opened. – B Layer Dec 7 '20 at 17:46
  • 1
    In autocmds, after the file pattern, is it always in command line mode? – samuelstevens Dec 7 '20 at 17:53
  • Yes. That's correct. – B Layer Dec 7 '20 at 18:30

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.