Search code examples
vimautocmdvim-quickfix

vim autocmd: Event based removal and addition of group commands


I am using quickfix and I have it set up so that a cwindow is run right after a Quick fix command. Also, I have a template file for my C++ source files which I want to be copied at the beginning of my new source files. Here is my .vimrc:

augroup SourceTemplate
    autocmd!
    autocmd bufnewfile *.c,*.cpp,*.hpp,*.h so /home/username/.vim/template.cpp
augroup QuickFix
    autocmd!
   " #1 autocmd QuickFixCmdPre * augroup! SourceTemplate
   " #2 autocmd! SourceTemplate bufnewfile
    autocmd QuickFixCmdPost [^l]* nested cwindow
    autocmd QuickFixCmdPost    l* nested lwindow
augroup END 

My template.cpp file has a :insert in the beginning and a '.' at the end with some text in between that I want to insert in the beginning of a new source file. The two augroups above work well if I use only one of them!

The problem is, whenever I run :make, the quickfix command opens a window at the bottom, as expected, but I am also presented with a new buffer with my template text in it (instead of the file I was editing). On doing Ctrl-G the file name displayed was (in one case) "In file included from...", which was also the highlighted line in the cwindow. So, the bufnewfile event is being triggered for some reason and I need to disable the autocmds corresponding to the bufnewfile in case of quickfix. I was able to think of a couple of solutions to this. But none of them work as I want them to.

If I uncomment #2 above, the SourceTemplate group is deleted forever. It's commands are not even executed on a fresh new file. And if I uncomment #1, the SourceTemplate commands are not disabled at all and the problem persists.

How do I achieve this?


Solution

  • Based on your description, I think the following happens:

    As you run :make without !, the first error is jumped to. Cp. :help :make:

          7. If [!] is not given the first error is jumped to.
    

    Your error parsing seems to be off, so non-existing files (In file included from...) are picked from the compiler output. That triggers the BufNewFile event, and therefore the insertion of the template.

    Remedies

    Easiest solution is to use :make!, so there's no jump. While inspecting the error list, make sure the location actually exists (or else you'll get the template again when you jump to the error).

    You could define an :autocmd QuickFixCmdPost that removes non-existing error locations from the quickfix list (using getqflist() / setqflist(), and filereadable()).

    Of course, the best solution would be to tweak the compiler output and/or error parsing (cp. :help errorformat), so that only actual, existing source code files are reported.