59 lines
1.6 KiB
VimL
59 lines
1.6 KiB
VimL
|
" don't spam the user when Vim is started in Vi compatibility mode
|
||
|
let s:cpo_save = &cpo
|
||
|
set cpo&vim
|
||
|
|
||
|
scriptencoding utf-8
|
||
|
|
||
|
" New returns a promise. A promise's primary purpose is to make async jobs
|
||
|
" synchronous by awaiting fn.
|
||
|
"
|
||
|
" A promise is a dictionary with two keys:
|
||
|
" 'wrapper':
|
||
|
" A function that wraps fn. It can be used in place of fn.
|
||
|
" 'await':
|
||
|
" A function that waits for wrapper to be called and returns the value
|
||
|
" returned by fn. Returns default if timeout expires.
|
||
|
function! go#promise#New(fn, timeout, default) abort
|
||
|
let l:state = {}
|
||
|
|
||
|
" explicitly bind to state so that within l:promise's methods, self will
|
||
|
" always refer to state. See :help Partial for more information.
|
||
|
return {
|
||
|
\ 'wrapper': function('s:wrapper', [a:fn, a:default], l:state),
|
||
|
\ 'await': function('s:await', [a:timeout, a:default], l:state),
|
||
|
\ }
|
||
|
endfunction
|
||
|
|
||
|
function! s:wrapper(fn, default, ...) dict
|
||
|
try
|
||
|
let self.retval = call(a:fn, a:000)
|
||
|
catch
|
||
|
let self.retval = substitute(v:exception, '^Vim', '', '')
|
||
|
let self.exception = 1
|
||
|
endtry
|
||
|
return self.retval
|
||
|
endfunction
|
||
|
|
||
|
function! s:await(timeout, default) dict
|
||
|
let l:timer = timer_start(a:timeout, function('s:setretval', [a:default], self))
|
||
|
while !has_key(self, 'retval')
|
||
|
sleep 50m
|
||
|
endwhile
|
||
|
call timer_stop(l:timer)
|
||
|
|
||
|
if get(self, 'exception', 0)
|
||
|
throw self.retval
|
||
|
endif
|
||
|
return self.retval
|
||
|
endfunction
|
||
|
|
||
|
function! s:setretval(val, timer) dict
|
||
|
let self.retval = a:val
|
||
|
endfunction
|
||
|
|
||
|
" restore Vi compatibility settings
|
||
|
let &cpo = s:cpo_save
|
||
|
unlet s:cpo_save
|
||
|
|
||
|
" vim: sw=2 ts=2 et
|