Writing async jobs in vim 8

Wed, Sep 14, 2016

You may have seen the new async job support added to VIM 8. Today I tried to hack together a script that would run my rake spec in the background, and then open up a quickfix window to show me the results.

This needs a lot of work, but it gets the job done for now!

" This callback will be executed when the entire command is completed
function! BackgroundCommandClose(channel)
  " Read the output from the command into the quickfix window
  execute "cfile! " . g:backgroundCommandOutput
  " Open the quickfix window
  unlet g:backgroundCommandOutput

function! RunBackgroundCommand(command)
  " Make sure we're running VIM version 8 or higher.
  if v:version < 800
    echoerr 'RunBackgroundCommand requires VIM version 8 or higher'

  if exists('g:backgroundCommandOutput')
    echo 'Already running task in background'
    echo 'Running task in background'
    " Launch the job.
    " Notice that we're only capturing out, and not err here. This is because, for some reason, the callback
    " will not actually get hit if we write err out to the same file. Not sure if I'm doing this wrong or?
    let g:backgroundCommandOutput = tempname()
    call job_start(a:command, {'close_cb': 'BackgroundCommandClose', 'out_io': 'file', 'out_name': g:backgroundCommandOutput})

" So we can use :BackgroundCommand to call our function.
command! -nargs=+ -complete=shellcmd RunBackgroundCommand call RunBackgroundCommand(<q-args>)

Add this code into your .vimrc and use it with :RunBackgroundCommand rake spec.