Update: turns out, the official
coffee-script plugin for Vim
already defines a command to do something like this:
Guess I should have read the docs more carefully :).
The first step is setting up some parameters:
function! SetupPreview(extension, command) let b:preview_file = tempname().'.'.a:extension let b:preview_command = printf(a:command, shellescape(expand('%'))) let b:preview_command .= ' > ' . b:preview_file . ' 2>&1' autocmd BufWritePost <buffer> \ if bufwinnr(b:preview_file) >= 0 | \ call UpdatePreview() | \ endif endfunction
After calling it with
SetupPreview('js', 'coffee -p %s'), this generates a
temporary name for the preview file and stores that and the command in
buffer-local variables. It also schedules an update to the buffer on every
save, provided the window is still open. Note that the generated command uses
shell redirection, so there’s no chance of it running on Windows.
This should be called in an ftplugin vim file:
" ftplugin/coffee.vim call SetupPreview('js', 'coffee -p %s')
Next, how to actually start the functionality:
command! Preview call s:InitPreview() function! s:InitPreview() if !exists('b:preview_file') echoerr 'No preview command has been defined for this buffer.' return endif if bufwinnr(b:preview_file) < 0 let original_buffer = bufnr('%') exe 'split '.b:preview_file call s:SwitchWindow(original_buffer) endif call UpdatePreview() endfunction
:Preview opens up the buffer with the temporary file, goes back to
the original one and triggers an update.
function! UpdatePreview() if !exists('b:preview_file') || bufwinnr(b:preview_file) < 0 return endif call system(b:preview_command) let original_buffer = bufnr('%') call s:SwitchWindow(b:preview_file) silent edit! syntax on " workaround for weird lack of syntax normal! zR call s:SwitchWindow(original_buffer) endfunction function! s:SwitchWindow(bufname) let window = bufwinnr(a:bufname) exe window.'wincmd w' endfunction
UpdatePreview() is called once on
:Preview and automatically on every save.
It executes the stored shell command and does an
:edit! in the preview
buffer. The function
s:SwitchWindow simply finds a window in the current tab,
corresponding to a buffer, and jumps to it.
The full source can be found here. If you’re wondering why it expects the extension and the external command as parameters, it’s because you can use the same code for other kinds of preprocessing. To get it to work for markdown, this should be enough:
" fplugin/markdown.vim call SetupPreview('markdown', 'markdown %s')