1
0
mirror of https://github.com/SpaceVim/SpaceVim.git synced 2025-02-03 12:20:05 +08:00
SpaceVim/bundle/gina.vim/autoload/gina/process.vim

158 lines
4.7 KiB
VimL
Vendored

let s:Job = vital#gina#import('System.Job')
let s:Guard = vital#gina#import('Vim.Guard')
let s:String = vital#gina#import('Data.String')
let s:t_dict = type({})
let s:no_askpass_commands = [
\ 'init',
\ 'config',
\]
let s:runnings = {}
function! gina#process#runnings() abort
return items(s:runnings)
endfunction
function! gina#process#register(job, ...) abort
if get(a:000, 0, 0)
let s:runnings['pseudo:' . a:job] = a:job
call gina#core#emitter#emit('process:registered:pseudo', a:job)
else
let s:runnings['job:' . a:job.pid()] = a:job
call gina#core#emitter#emit('process:registered', a:job.pid(), a:job.params.scheme, a:job.args)
endif
endfunction
function! gina#process#unregister(job, ...) abort
if get(a:000, 0, 0)
silent! unlet s:runnings['pseudo:' . a:job]
call gina#core#emitter#emit('process:unregistered:pseudo', a:job)
else
silent! unlet s:runnings['job:' . a:job.pid()]
call gina#core#emitter#emit('process:unregistered', a:job.pid(), a:job.params.scheme, a:job.args)
endif
endfunction
function! gina#process#wait(...) abort
let timeout = get(a:000, 0, v:null)
let timeout = timeout is# v:null ? v:null : timeout / 1000.0
let start_time = reltime()
let updatetime = g:gina#process#updatetime . 'm'
call gina#core#emitter#emit('wait:start')
while timeout is# v:null || timeout > reltimefloat(reltime(start_time))
if empty(s:runnings)
call gina#core#emitter#emit('wait:end')
return
endif
execute 'sleep' updatetime
endwhile
call gina#core#emitter#emit('wait:timeout')
return -1
endfunction
function! gina#process#open(git, args, ...) abort
let args = type(a:args) == s:t_dict ? a:args : gina#core#args#raw(a:args)
let pipe = extend(gina#process#pipe#default(), get(a:000, 0, {}))
let pipe.params = get(args, 'params', {})
let pipe.params.scheme = get(pipe.params, 'scheme', args.get(0, ''))
let LC_ALL_saved = exists('$LC_ALL') ? $LC_ALL : v:null
let GIT_EDITOR_saved = exists('$GIT_EDITOR') ? $GIT_EDITOR : v:null
try
let $LC_ALL = 'C'
unlet $GIT_EDITOR
let job = s:Job.start(s:build_raw_args(a:git, args), pipe)
finally
if LC_ALL_saved is# v:null
unlet $LC_ALL
else
let $LC_ALL = LC_ALL_saved
endif
if GIT_EDITOR_saved is# v:null
unlet $GIT_EDITOR
else
let $GIT_EDITOR = GIT_EDITOR_saved
endif
endtry
call job.on_start()
call gina#core#console#debug(printf('process: %s', join(job.args)))
return job
endfunction
function! gina#process#call(git, args, ...) abort
let options = extend({
\ 'timeout': g:gina#process#timeout,
\}, get(a:000, 0, {})
\)
let pipe = gina#process#pipe#store()
let job = gina#process#open(a:git, a:args, pipe)
let status = job.wait(options.timeout)
return {
\ 'args': job.args,
\ 'status': status,
\ 'stdout': pipe.stdout,
\ 'stderr': pipe.stderr,
\ 'content': pipe.content,
\}
endfunction
function! gina#process#call_or_fail(git, args, ...) abort
let result = call('gina#process#call', [a:git, a:args] + a:000)
if result.status
throw gina#process#errormsg(result)
endif
return result
endfunction
function! gina#process#inform(result) abort
redraw | echo
if a:result.status
call gina#core#console#warn('Fail: ' . join(a:result.args))
endif
call gina#core#console#echo(s:String.remove_ansi_sequences(
\ join(a:result.content, "\n"))
\)
endfunction
function! gina#process#errormsg(result) abort
return gina#core#revelator#error(printf(
\ "Fail: %s\n%s",
\ join(a:result.args),
\ join(a:result.content, "\n")
\))
endfunction
function! gina#process#build_raw_args(git, args) abort
return s:build_raw_args(a:git, a:args)
endfunction
" Private --------------------------------------------------------------------
function! s:build_raw_args(git, args) abort
let args = gina#core#args#raw(g:gina#process#command).raw
if !empty(a:git) && isdirectory(a:git.worktree)
call extend(args, ['-C', a:git.worktree])
endif
call extend(args, a:args.raw)
call filter(map(args, 's:expand(v:val)'), '!empty(v:val)')
" Assign env GIT_TERMINAL_PROMPT/GIT_ASKPASS if necessary
if index(s:no_askpass_commands, a:args.get(0)) == -1
call gina#core#askpass#wrap(a:git, args)
endif
return args
endfunction
function! s:expand(value) abort
if a:value =~# '^\%([%#]\|<\w\+>\)\%(:[p8~.htreS]\|:g\?s?\S\+?\S\+?\)*$'
return gina#core#path#expand(a:value)
endif
return a:value
endfunction
call gina#config(expand('<sfile>'), {
\ 'command': 'git --no-pager -c core.editor=false -c color.status=always',
\ 'updatetime': 100,
\ 'timeout': 10000,
\})