dmo.ca/ blog/ Perl test output in a temporary vim buffer

I recently came across a Vim tip explaining how to display shell commands in a different buffer. While useful, it opens a separate scratch buffer every time you run the command. I wanted to make it reuse the same scratch buffer, so that whenever I ran my unit tests using it, they overwrote the previous run's output. As it turns out, Vim has a way to do this.

Vim has a feature known as "quickfix", which lets it subsume your compiler output and display any errors in a separate global buffer, with quick jumps to the line/file that caused the error. There's also a local per-window equivalent called "location-list". See ":help location-list" for further details, but for now all you need to know is that it's a special per-window buffer for command output that we can abuse to display test output.

The original vim tip contains:

function! s:RunShellCommand(cmdline)
  botright new
  setlocal buftype=nofile bufhidden=wipe nobuflisted noswapfile nowrap
  call setline(1,a:cmdline)
  call setline(2,substitute(a:cmdline,'.','=','g'))
  execute 'silent $read !'.escape(a:cmdline,'%#')
  setlocal nomodifiable
  1
endfunction

What we want to do is make this use the location-list buffer for our currently-edited file. To do this, we change this to:

function! s:RunShellCommand(cmdline)
  botright lwindow
  lexpr system(escape(a:cmdline,'%#'))
  lopen
  1
endfunction

command! -complete=file -nargs=+ Test call s:RunShellCommand('prove -v '.<q-args> )

Now we can run :Test t/mytest.t within vim, and get our results in a separate buffer, which we can manipulate with :lopen and :lclose

It's not perfect, as quickfix and location-list expect results formatted with line and file information and an error message, not 'prove' output, but it's still better than having multiple output windows.