In Vim, it’s easy to run builds with :make and :set makeprg, but just for fun I tried out making Vim trigger builds in a separate terminal. Though :make is really useful in general, there are some advantages of doing it this way instead:

  • The output is separate from your Vim window. If there’s a lot of output, it won’t cover up you editing window, but you can still read it.
  • Sometimes the quickfix patterns pick up phrases that are unhelpful in the build output. Vim may think something in the output looks like a filename and it jumps to that file, but that file may not exist. Keeping the output separate works around this.

In this example, the build command that I want to trigger is docker build -f Dockerfile.test .. I will read from a named pipe. Whenever a message comes in on the pipe, I will run the build command. Vim will send messages to that pipe when it’s time to run a build.

mkfifo buildwait

while read tmp < buildwait; do
   docker build -f Dockerfile.test .
done

In Vim, set up the sending side:

:set makeprg=echo\ >>\ buildwait

Now, when you type :make, Vim will set a message to the waiting shell loop. There are a lot of ways you could shortcut having to type :make when you want to run the build. For example:

  • Build when you press F5: :noremap <F5> :silent make<CR>
  • Build on file save: :autocmd BufWritePost * :silent make
    • I have this in my vimrc to make gvim write files when the window loses focus: audocmd FocusLost * silent! wa