mirror of
https://github.com/SpaceVim/SpaceVim.git
synced 2025-02-03 17:50:05 +08:00
137 lines
4.5 KiB
VimL
137 lines
4.5 KiB
VimL
" ============================================================================
|
|
" File: autoload/gitstatus/job.vim
|
|
" Description: async-jobs
|
|
" Maintainer: Xuyuan Pang <xuyuanp at gmail dot com>
|
|
" License: This program is free software. It comes without any warranty,
|
|
" to the extent permitted by applicable law. You can redistribute
|
|
" it and/or modify it under the terms of the Do What The Fuck You
|
|
" Want To Public License, Version 2, as published by Sam Hocevar.
|
|
" See http://sam.zoy.org/wtfpl/COPYING for more details.
|
|
" ============================================================================
|
|
if exists('g:loaded_nerdtree_git_status_job')
|
|
finish
|
|
endif
|
|
let g:loaded_nerdtree_git_status_job = 1
|
|
|
|
" stolen from vim-plug
|
|
let s:nvim = has('nvim-0.2') || (has('nvim') && exists('*jobwait'))
|
|
let s:vim8 = has('patch-8.0.0039') && exists('*job_start')
|
|
|
|
let s:Job = {
|
|
\ 'running': 0,
|
|
\ 'failed': 0,
|
|
\ 'chunks': [''],
|
|
\ 'err_chunks': [''],
|
|
\ }
|
|
|
|
" disabled ProhibitImplicitScopeVariable because we will use lots of `self`
|
|
" disabled ProhibitUnusedVariable because lambda
|
|
" vint: -ProhibitImplicitScopeVariable -ProhibitUnusedVariable
|
|
function! s:newJob(name, opts) abort
|
|
return extend(deepcopy(s:Job), {
|
|
\ 'name': a:name,
|
|
\ 'opts': a:opts
|
|
\ })
|
|
endfunction
|
|
|
|
function! s:Job.onStdoutCB(data) abort
|
|
let self.chunks[-1] .= a:data[0]
|
|
call extend(self.chunks, a:data[1:])
|
|
endfunction
|
|
|
|
function! s:Job.onStderrCB(data) abort
|
|
let self.failed = self.failed || !s:isEOF(a:data)
|
|
let self.err_chunks[-1] .= a:data[0]
|
|
call extend(self.err_chunks, a:data[1:])
|
|
endfunction
|
|
|
|
function! s:Job.onExitCB() abort
|
|
let self.running = 0
|
|
if self.failed
|
|
call self.onFailed()
|
|
else
|
|
call self.onSuccess()
|
|
endif
|
|
endfunction
|
|
|
|
function! s:Job.onFailed() abort
|
|
if has_key(self.opts, 'on_failed_cb')
|
|
call call(self.opts.on_failed_cb, [self])
|
|
endif
|
|
endfunction
|
|
|
|
function! s:Job.onSuccess() abort
|
|
if has_key(self.opts, 'on_success_cb')
|
|
call call(self.opts.on_success_cb, [self])
|
|
endif
|
|
endfunction
|
|
|
|
if s:nvim
|
|
function! s:Job.run(cmd) abort
|
|
let jid = jobstart(a:cmd, {
|
|
\ 'on_stdout': {_job_id, data, _event -> self.onStdoutCB(data)},
|
|
\ 'on_stderr': {_job_id, data, _event -> self.onStderrCB(data)},
|
|
\ 'on_exit': {_job_id, _data, _event -> self.onExitCB()},
|
|
\ 'env': {'GIT_OPTIONAL_LOCKS': '0'},
|
|
\ })
|
|
let self.id = jid
|
|
let self.running = jid > 0
|
|
if jid <= 0
|
|
let self.failed = 1
|
|
let self.err_chunks = jid == 0 ?
|
|
\ ['invalid arguments'] :
|
|
\ ['command is not executable']
|
|
call self.onExitCB()
|
|
endif
|
|
endfunction
|
|
elseif s:vim8
|
|
function! s:Job.run(cmd) abort
|
|
let options = {
|
|
\ 'out_cb': { _ch, data -> self.onStdoutCB([data]) },
|
|
\ 'err_cb': { _ch, data -> self.onStderrCB([data]) },
|
|
\ 'close_cb': { _ch -> self.onExitCB() },
|
|
\ 'out_mode': 'nl',
|
|
\ 'err_mode': 'nl',
|
|
\ 'env': {'GIT_OPTIONAL_LOCKS': '0'},
|
|
\ }
|
|
if has('patch-8.1.350')
|
|
let options['noblock'] = 1
|
|
endif
|
|
let jid = job_start(a:cmd, options)
|
|
if job_status(jid) ==# 'run'
|
|
let self.id = jid
|
|
let self.running = 1
|
|
else
|
|
let self.running = 0
|
|
let self.failed = 1
|
|
let self.err_chunks = ['failed to start job']
|
|
call self.onExitCB()
|
|
endif
|
|
endfunction
|
|
else
|
|
function! s:Job.run(cmd) abort
|
|
let bak = $GIT_OPTIONAL_LOCKS
|
|
let $GIT_OPTIONAL_LOCKS = 0
|
|
let output = substitute(system(join(a:cmd, ' ')), "\<C-A>", "\n", 'g')
|
|
let $GIT_OPTIONAL_LOCKS = bak
|
|
let self.failed = v:shell_error isnot# 0
|
|
if self.failed
|
|
let self.err_chunks = [output]
|
|
else
|
|
let self.chunks = [output]
|
|
endif
|
|
call self.onExitCB()
|
|
endfunction
|
|
endif
|
|
" vint: +ProhibitImplicitScopeVariable +ProhibitUnusedVariable
|
|
|
|
function! s:isEOF(data) abort
|
|
return len(a:data) == 1 && a:data[0] is# ''
|
|
endfunction
|
|
|
|
function! gitstatus#job#Spawn(name, cmd, opts) abort
|
|
let l:job = s:newJob(a:name, a:opts)
|
|
call l:job.run(a:cmd)
|
|
return l:job
|
|
endfunction
|