Asynchronous Vim
In my last post I explored using Python and nccurses to asynchronously render
streamed content from curl. Upon a re-think of my strategy, I wondered why I
even needed Python at all. In modern versions of Vim, I knew that asynchronous
abilities were available, but I had no idea how to use it at all. After quite a
bit of experimentation and reading the docs, this is what I learned:
Jobs
The job_start command can execute a shell command and intercept the results
with callbacks. You can even create partial functions and use them as callbacks!
" job_demo.vim
function! OutCb(bufchannel, msg) abort
call append('$', a:msg)
endfunction
function! ExitCb(foo, job, status) abort
call append('$', "Status: ".a:status)
call append("$", a:foo)
endfunction
let cmd = ['/bin/bash', '-c', 'for i in 1 2 3; do echo $i; sleep 1; done']
let callbacks = {'out_cb': function("OutCb"), 'exit_cb': function("ExitCb", [456])}
let job_id = job_start(cmd, callbacks)Write this script to as buffer and running :w job_demo.vim | so % will append the script with
1
2
3
Status: 0
456as the job progresses. With this working example, I was able to understand :h job much more!
Timers
Sometimes you just need a function to call every N seconds or so.
" timer_demo.vim
let g:counter = 0
function! MyFunc(msg, timer_id) abort
if g:counter > 3
return
endif
let g:counter += 1
call append("$",a:msg)
let n_msecs = 1000
call timer_start(n_msecs, function('MyFunc', [1000 * n_msecs]))
endfunction
let timer_id = timer_start(1000, function('MyFunc', ["timer go!"]))This appends the text
timer go!
1000
2000
3000As the timer executes. Check out :h timer for more info.
And both these methods don’t block other actions in Vim! You can keep editing or processing text in another buffer without interruption.
Reply to this post by email blZake@proZbableodyssey.blog (remove Z characters) ↪