## Async VimScript (1/2) ### Timers and Jobs Thomas Allen [thomas@oinksoft.com](mailto:thomas@oinksoft.com) Septemper 18, 2018 Vim Chicago Hashrocket, Chicago, IL
## History * vi, vim: Single-threaded * Emacs, IDEs, Neovim: Multi-threaded
## Vim 8 Async * Terminals (`:help terminal`) * Timers (`:help timer`) * Jobs (`:help channel`) * Channels (`:help channel`)
## Timers Execute a function after a number of milliseconds pass. Single: Exit immediately, but cancel before it can run. ``` let timer_id = timer_start(0, {id -> execute('quit!')}) call timer_stop(timer_id) ```
## Timers (2) Loop: Delete lines, rotate. ``` let s:timeouts = [5000, 10000, 30000, 1000, 1000, 3200, 500, 700] function! s:noop(timer_id) " Rotate let s:timeouts = insert(s:timeouts, remove(s:timeouts, len(s:timeouts) - 1)) normal dd call timer_start(s:timeouts[0], function('<SID>noop')) endfunction call s:noop(0) ```
## Timers (3) Weather in the statusline. ``` function! s:fetch_weather(station_code) let out = system('weather --imperial ' . shellescape(a:station_code)) " Parse... endfunction function! s:sync_statusline_weather(station_code, interval, timer_id) let conditions = s:fetch_weather(a:station_code) if conditions != s:last_conditions let s:last_conditions = conditions " Force statusline render execute 'let &ro = &ro' endif call timer_start( \ a:interval, \ function('<SID>sync_statusline_weather'), \ [a:interval, a:station_code]) endfunction call s:sync_statusline_weather('klot', 60 * 1000, 0) set statusline=%!FormatConditions() ```
## Jobs Run a shell command without blocking. `find` to the location list: ``` function! s:on_find(chan, msg) lgetexpr split(a:msg, '') endfunction call job_start('find . -print0', { \ 'out_mode': 'raw', \ 'callback': function('<SID>on_find') \ }) ```

Jobs (2)

HTTP response.

function! s:on_line(chan, msg)
  if empty(a:msg)
    let body = "Hello from Vim!"
    call ch_sendraw(a:chan, join([
          \ "HTTP/1.1 200 OK",
          \ "Content-Length: " . len(body),
          \ "Content-Type: text/plain",
          \ "",
          \ body
          \ ], "\n"))
  endif
endfunction

" Save reference to long-running job or it will be garbage collected
let server = call job_start('nc -lp 3000', {
      \ 'callback': function('<SID>on_line'),
      \ 'in_mode': 'raw',
      \ 'out_mode': 'nl'
      \ })
## Q/A