mirror of
https://github.com/SpaceVim/SpaceVim.git
synced 2025-01-24 09:20:06 +08:00
143 lines
4.0 KiB
VimL
143 lines
4.0 KiB
VimL
" dispatch.vim job strategy
|
|
|
|
if exists('g:autoloaded_dispatch_job')
|
|
finish
|
|
endif
|
|
let g:autoloaded_dispatch_job = 1
|
|
|
|
if !exists('s:waiting')
|
|
let s:waiting = {}
|
|
endif
|
|
|
|
let g:dispatch_waiting_jobs = s:waiting
|
|
|
|
function! dispatch#job#handle(request) abort
|
|
if !get(g:, 'dispatch_experimental', 1)
|
|
return 0
|
|
endif
|
|
if a:request.action !=# 'make'
|
|
return 0
|
|
endif
|
|
if exists('*job_start')
|
|
if has('win32')
|
|
let cmd = &shell . ' ' . &shellcmdflag . ' ' . dispatch#windows#escape(a:request.expanded)
|
|
else
|
|
let cmd = split(&shell) + split(&shellcmdflag) + [a:request.expanded]
|
|
endif
|
|
let job = job_start(cmd, {
|
|
\ 'mode': 'raw',
|
|
\ 'callback': function('s:output'),
|
|
\ 'close_cb': function('s:closed'),
|
|
\ 'exit_cb': function('s:exit'),
|
|
\ })
|
|
call ch_close_in(job)
|
|
let a:request.pid = job_info(job).process
|
|
let a:request.job = job
|
|
let ch_id = ch_info(job_info(job).channel).id
|
|
let s:waiting[ch_id] = {'request': a:request, 'output': ['']}
|
|
elseif exists('*jobpid') && exists('*jobstart')
|
|
let job_id = jobstart(a:request.expanded, {
|
|
\ 'on_stdout': function('s:output'),
|
|
\ 'on_stderr': function('s:output'),
|
|
\ 'on_exit': function('s:complete'),
|
|
\ })
|
|
call chanclose(job_id, 'stdin')
|
|
let a:request.pid = jobpid(job_id)
|
|
let a:request.job = job_id
|
|
let s:waiting[job_id] = {'request': a:request, 'output': ['']}
|
|
else
|
|
return 0
|
|
endif
|
|
let a:request.handler = 'job'
|
|
call writefile([], a:request.file)
|
|
call writefile([a:request.pid], a:request.file . '.pid')
|
|
return 2
|
|
endfunction
|
|
|
|
function! s:complete(id, status, ...) abort
|
|
let waiting = remove(s:waiting, a:id)
|
|
call writefile([a:status], waiting.request.file . '.complete')
|
|
call DispatchComplete(waiting.request.id)
|
|
endfunction
|
|
|
|
function! s:closed(ch) abort
|
|
let id = ch_info(a:ch).id
|
|
if has_key(s:waiting, id) && has_key(s:waiting[id], 'exit_status')
|
|
call s:complete(id, s:waiting[id].exit_status)
|
|
endif
|
|
endfunction
|
|
|
|
function! s:exit(job, status) abort
|
|
let ch = job_info(a:job).channel
|
|
let info = ch_info(ch)
|
|
if info.status ==# 'closed'
|
|
return s:complete(info.id, a:status)
|
|
else
|
|
let s:waiting[info.id].exit_status = a:status
|
|
endif
|
|
endfunction
|
|
|
|
function! s:output(ch, output, ...) abort
|
|
if a:0
|
|
" nvim
|
|
let waiting = s:waiting[a:ch]
|
|
let output = a:output
|
|
else
|
|
" vim
|
|
let waiting = s:waiting[ch_info(a:ch).id]
|
|
let output = split(a:output, "\n", 1)
|
|
endif
|
|
let request = waiting.request
|
|
call writefile(output, request.file, 'ab')
|
|
let waiting.output[-1] .= remove(output, 0)
|
|
call extend(waiting.output, output)
|
|
|
|
if dispatch#request(get(getqflist({'title': 1}), 'title', '')) is# request && len(waiting.output) > 1
|
|
let lefm = &l:efm
|
|
let gefm = &g:efm
|
|
let makeprg = &l:makeprg
|
|
let compiler = get(b:, 'current_compiler', '')
|
|
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd' : exists(':tcd') && haslocaldir(-1) ? 'tcd' : 'cd'
|
|
let dir = getcwd()
|
|
let modelines = &modelines
|
|
try
|
|
let &modelines = 0
|
|
let b:current_compiler = get(request, 'compiler', '')
|
|
if empty(b:current_compiler)
|
|
unlet! b:current_compiler
|
|
endif
|
|
exe cd fnameescape(request.directory)
|
|
let &l:efm = request.format
|
|
let &g:efm = request.format
|
|
let &l:makeprg = request.command
|
|
caddexpr remove(waiting.output, 0, -2)
|
|
finally
|
|
let &modelines = modelines
|
|
exe cd fnameescape(dir)
|
|
let &l:efm = lefm
|
|
let &g:efm = gefm
|
|
let &l:makeprg = makeprg
|
|
if empty(compiler)
|
|
unlet! b:current_compiler
|
|
else
|
|
let b:current_compiler = compiler
|
|
endif
|
|
endtry
|
|
cbottom
|
|
endif
|
|
endfunction
|
|
|
|
function! dispatch#job#kill(pid, force) abort
|
|
let request = dispatch#request('job/' . a:pid)
|
|
if exists('*job_stop')
|
|
return job_stop(request.job, a:force ? 'kill' : 'hup')
|
|
elseif exists('*jobstop')
|
|
call jobstop(request.job)
|
|
return 1
|
|
endif
|
|
endfunction
|
|
|
|
function! dispatch#job#activate(pid) abort
|
|
return 0
|
|
endfunction
|