I have an autocmd set up like this:

au BufWritePost *.sh,*.zsh,.zshrc silent exec "!ctags --language-force=sh %"

When I run :!!<cr> after saving a file, the command !ctags --language-force=sh % is being run.

This does not happen on vim 8.1.

How do I prevent neovim from doing that ?


First - My mistake, this happens also in vim 8.1 so it's not neovim specific.

Second - I wish to clarify my workflow:

  1. Edit a script
  2. Save it
  3. Run it with :!./%<cr>
  4. Edit again.
  5. Run it again with :!!<cr>

When I have the above autocmd in place, #5 breaks and the autocmd command replaces the last :!./%<cr>.

This is what I wish to fix.

  • 1
    Avi, I've edited your question to be hopefully a bit clearer. If it does not match up with what you intended, please edit to clarify your problem.
    – D. Ben Knoble
    Feb 4, 2020 at 23:02

2 Answers 2


You can use system() instead of :!. As the question is specific to Neovim, it makes sense to pass command as a List (not supported in Vim!) to execute the application directly (w/o shell):

au BufWritePost *.sh,*.zsh,.zshrc
    \ silent call system(['ctags', '--language-force=sh', fnameescape(expand('%'))])

Also note that shell quoting rules won't apply then, but you still must escape (at least) spaces in file name.

  • I actually thought about this option, but it seemed to me that my workflow is pretty common, so there must be a way to prevent this behavior in vim. I'm sure it's not
    – Avi
    Feb 5, 2020 at 22:53
  • +1 I actually thought about this option before I posted, but it seems to me that my workflow is pretty common, so there must be a way to prevent this behavior in vim. Surely a user would want to run his previous command with :!!<cr> rather than the content of an autocmd (there could be a few of them anyway)... Just my opinion, I might be wrong here.... (Previous comment should be deleted, accidental)
    – Avi
    Feb 5, 2020 at 23:00

Do note that vim's documentation says

:{range}![!]{filter} [!][arg]               *:range!*
            Filter {range} lines through the external program
            {filter}.  Vim replaces the optional bangs with the
            latest given command and appends the optional [arg].

So :!! should reuse the latest-given command. It's unclear which of the two behaviours (treating autcommands + silent + exec differently or not) is more "correct," but at any rate you could file an issue with NeoVim to change the behaviour.

  • I've edited my question - this is not neovim specific. But in any case I'm not sure how the :{range}![!]filter [!][arg] applies to my situation as I'm not using it in my workflow or my autocmd. (I'm using :!{cmd} ).In any case my cpoptions does not include ! which would trigger this behaviour. :help cpo-!
    – Avi
    Feb 5, 2020 at 7:21
  • The command :!! is covered by this case. Notice the optional second !
    – D. Ben Knoble
    Feb 5, 2020 at 14:00

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.