-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
job.vim
96 lines (86 loc) · 2.88 KB
/
job.vim
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
" ref: https://github.com/tani/vim-jetpack/blob/b5cf6209866c1acdf06d4047ff33e7734bfa2879/plugin/jetpack.vim#L170-L217
function! s:jobcount(jobs) abort
return len(filter(copy(a:jobs), {_, val -> s:jobstatus(val) ==# 'run'}))
endfunction
function! s:jobwait(jobs, njobs) abort
let running = s:jobcount(a:jobs)
while running > a:njobs
let running = s:jobcount(a:jobs)
endwhile
endfunction
let s:jobs = {}
if has('nvim')
function! s:jobstatus(job) abort
return jobwait([a:job], 0)[0] == -1 ? 'run' : 'dead'
endfunction
function! mi#job#list() abort
let result = []
for id in keys(s:jobs)
call add(result, {'id': id, 'status': s:jobstatus(id)})
endfor
return result
endfunction
function! mi#job#start(cmd, opts = {}) abort
let buf = []
let On_out = get(a:opts, 'out', {data->0})
let On_err = get(a:opts, 'err', {data->0})
let On_exit = get(a:opts, 'exit', {data->0})
let job = jobstart(a:cmd, {
\ 'stdin': 'null',
\ 'on_stdout': {_, data -> [extend(buf, data), On_out(data)]},
\ 'on_stderr': {_, data -> [extend(buf, data), On_err(data)]},
\ 'on_exit': {-> On_exit(join(buf, "\n"))}
\ })
let s:jobs[job] = 1
return job
endfunction
else
function! s:jobstatus(job) abort
return job_status(a:job)
endfunction
function! s:job_id(job)
return job_info(a:job).process
endfunction
function! s:job_exit_cb(buf, cb, job, ...) abort
let ch = job_getchannel(a:job)
while ch_status(ch) ==# 'open' | sleep 1ms | endwhile
while ch_status(ch) ==# 'buffered' | sleep 1ms | endwhile
call a:cb(join(a:buf, "\n"))
endfunction
function! mi#job#list() abort
let result = []
for [id, job] in items(s:jobs)
call add(result, {'id': id, 'status': s:jobstatus(job)})
endfor
return result
endfunction
function! mi#job#start(cmd, opts = {}) abort
let buf = []
let On_out = get(a:opts, 'out', {_->0})
let On_err = get(a:opts, 'err', {_->0})
let On_exit = get(a:opts, 'exit', {_->0})
let job_opts = {
\ 'out_mode': 'raw',
\ 'out_cb': {_, data -> [extend(buf, split(data, "\n")), On_out(split(data, "\n"))]},
\ 'err_mode': 'raw',
\ 'err_cb': {_, data -> [extend(buf, split(data, "\n")), On_err(split(data, "\n"))]},
\ 'exit_cb': function('s:job_exit_cb', [buf, On_exit])
\ }
let in_opts = get(a:opts, 'in', {})
if has_key(in_opts, 'buf')
let job_opts['in_io'] = 'buffer'
let job_opts['in_buf'] = in_opts['buf']
if has_key(in_opts, 'top')
let job_opts['in_top'] = in_opts['top']
endif
if has_key(in_opts, 'bot')
let job_opts['in_bot'] = in_opts['bot']
endif
else
let job_opts['in_io'] = 'null'
endif
let job = job_start(a:cmd, job_opts)
let s:jobs[s:job_id(job)] = job
return job
endfunction
endif