Skip to content

Commit

Permalink
feat: add job.vim
Browse files Browse the repository at this point in the history
  • Loading branch information
kawarimidoll committed Nov 28, 2023
1 parent ae5da5e commit 6f8a36d
Showing 1 changed file with 96 additions and 0 deletions.
96 changes: 96 additions & 0 deletions job.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1,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! 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! 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(buf)}
\ })
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(a:buf)
endfunction

function! 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! 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

0 comments on commit 6f8a36d

Please sign in to comment.