ProbableOdyssey | Blake Cook

Asynchronous Vim

· 2 min read · 282 words

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
456

as 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
3000

As 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.

#programming #shell-integration #jobs #software-design #async #non-blocking #timers #shell-scripting #vim #job_start #asynchronous-programming #vimscript #callbacks

Reply to this post by email blZake@proZbableodyssey.blog (remove Z characters) ↪

Comments

Leave a comment

Markdown is supported. Your email is private and only used if you'd like a reply.