2018-01-05 17:37:59 +08:00
|
|
|
" MIT License. Copyright (c) 2013-2018 C.Brabandt et al.
|
2017-08-23 05:21:19 +08:00
|
|
|
" vim: et ts=2 sts=2 sw=2
|
|
|
|
|
2018-01-05 17:18:22 +08:00
|
|
|
scriptencoding utf-8
|
|
|
|
|
2017-08-23 05:21:19 +08:00
|
|
|
let s:untracked_jobs = {}
|
|
|
|
let s:mq_jobs = {}
|
|
|
|
let s:po_jobs = {}
|
|
|
|
|
2017-08-23 05:42:27 +08:00
|
|
|
" Generic functions handling on exit event of the various async functions
|
2017-08-23 05:21:19 +08:00
|
|
|
function! s:untracked_output(dict, buf)
|
|
|
|
if a:buf =~? ('^'. a:dict.cfg['untracked_mark'])
|
|
|
|
let a:dict.cfg.untracked[a:dict.file] = get(g:, 'airline#extensions#branch#notexists', g:airline_symbols.notexists)
|
|
|
|
else
|
|
|
|
let a:dict.cfg.untracked[a:dict.file] = ''
|
|
|
|
endif
|
|
|
|
endfunction
|
|
|
|
|
2017-09-23 03:39:17 +08:00
|
|
|
" also called from branch extension (for non-async vims)
|
2017-09-23 03:37:28 +08:00
|
|
|
function! airline#async#mq_output(buf, file)
|
2017-08-29 18:47:29 +08:00
|
|
|
let buf=a:buf
|
2017-08-23 05:21:19 +08:00
|
|
|
if !empty(a:buf)
|
2017-09-23 03:37:28 +08:00
|
|
|
if a:buf =~# 'no patches applied' ||
|
2017-09-23 03:39:17 +08:00
|
|
|
\ a:buf =~# "unknown command 'qtop'" ||
|
|
|
|
\ a:buf =~# "abort"
|
2017-08-23 05:21:19 +08:00
|
|
|
let buf = ''
|
2017-08-29 18:47:29 +08:00
|
|
|
elseif exists("b:mq") && b:mq isnot# buf
|
2017-08-23 05:21:19 +08:00
|
|
|
" make sure, statusline is updated
|
|
|
|
unlet! b:airline_head
|
|
|
|
endif
|
2017-08-29 18:47:29 +08:00
|
|
|
let b:mq = buf
|
2017-08-23 05:21:19 +08:00
|
|
|
endif
|
|
|
|
if has_key(s:mq_jobs, a:file)
|
|
|
|
call remove(s:mq_jobs, a:file)
|
|
|
|
endif
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
function! s:po_output(buf, file)
|
|
|
|
if !empty(a:buf)
|
2018-11-01 17:39:33 +08:00
|
|
|
let b:airline_po_stats = printf("%s", a:buf)
|
2017-08-23 05:21:19 +08:00
|
|
|
else
|
|
|
|
let b:airline_po_stats = ''
|
|
|
|
endif
|
|
|
|
if has_key(s:po_jobs, a:file)
|
|
|
|
call remove(s:po_jobs, a:file)
|
|
|
|
endif
|
|
|
|
endfunction
|
|
|
|
|
2017-08-26 14:04:44 +08:00
|
|
|
function! s:valid_dir(dir)
|
|
|
|
if empty(a:dir) || !isdirectory(a:dir)
|
|
|
|
return getcwd()
|
|
|
|
endif
|
|
|
|
return a:dir
|
|
|
|
endfunction
|
|
|
|
|
2017-08-23 05:42:27 +08:00
|
|
|
if v:version >= 800 && has("job")
|
|
|
|
" Vim 8.0 with Job feature
|
2018-01-05 06:29:15 +08:00
|
|
|
" TODO: Check if we need the cwd option for the job_start() functions
|
|
|
|
" (only works starting with Vim 8.0.0902)
|
2017-08-23 05:21:19 +08:00
|
|
|
|
|
|
|
function! s:on_stdout(channel, msg) dict abort
|
|
|
|
let self.buf .= a:msg
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
function! s:on_exit_mq(channel) dict abort
|
2017-09-23 03:37:28 +08:00
|
|
|
call airline#async#mq_output(self.buf, self.file)
|
2017-08-23 05:21:19 +08:00
|
|
|
endfunction
|
|
|
|
|
|
|
|
function! s:on_exit_untracked(channel) dict abort
|
|
|
|
call s:untracked_output(self, self.buf)
|
|
|
|
if has_key(s:untracked_jobs, self.file)
|
|
|
|
call remove(s:untracked_jobs, self.file)
|
|
|
|
endif
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
function! s:on_exit_po(channel) dict abort
|
|
|
|
call s:po_output(self.buf, self.file)
|
|
|
|
call airline#extensions#po#shorten()
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
function! airline#async#get_mq_async(cmd, file)
|
|
|
|
if g:airline#init#is_windows && &shell =~ 'cmd'
|
|
|
|
let cmd = a:cmd
|
|
|
|
else
|
|
|
|
let cmd = ['sh', '-c', a:cmd]
|
|
|
|
endif
|
|
|
|
|
|
|
|
let options = {'cmd': a:cmd, 'buf': '', 'file': a:file}
|
|
|
|
if has_key(s:mq_jobs, a:file)
|
|
|
|
if job_status(get(s:mq_jobs, a:file)) == 'run'
|
|
|
|
return
|
|
|
|
elseif has_key(s:mq_jobs, a:file)
|
|
|
|
call remove(s:mq_jobs, a:file)
|
|
|
|
endif
|
|
|
|
endif
|
|
|
|
let id = job_start(cmd, {
|
|
|
|
\ 'err_io': 'out',
|
|
|
|
\ 'out_cb': function('s:on_stdout', options),
|
|
|
|
\ 'close_cb': function('s:on_exit_mq', options)})
|
|
|
|
let s:mq_jobs[a:file] = id
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
function! airline#async#get_msgfmt_stat(cmd, file)
|
|
|
|
if g:airline#init#is_windows || !executable('msgfmt')
|
|
|
|
" no msgfmt on windows?
|
|
|
|
return
|
|
|
|
else
|
|
|
|
let cmd = ['sh', '-c', a:cmd. shellescape(a:file)]
|
|
|
|
endif
|
|
|
|
|
|
|
|
let options = {'buf': '', 'file': a:file}
|
|
|
|
if has_key(s:po_jobs, a:file)
|
|
|
|
if job_status(get(s:po_jobs, a:file)) == 'run'
|
|
|
|
return
|
|
|
|
elseif has_key(s:po_jobs, a:file)
|
|
|
|
call remove(s:po_jobs, a:file)
|
|
|
|
endif
|
|
|
|
endif
|
|
|
|
let id = job_start(cmd, {
|
|
|
|
\ 'err_io': 'out',
|
|
|
|
\ 'out_cb': function('s:on_stdout', options),
|
|
|
|
\ 'close_cb': function('s:on_exit_po', options)})
|
|
|
|
let s:po_jobs[a:file] = id
|
|
|
|
endfunction
|
|
|
|
|
2018-06-14 00:52:13 +08:00
|
|
|
function! airline#async#vim_vcs_untracked(config, file)
|
2017-08-23 05:21:19 +08:00
|
|
|
if g:airline#init#is_windows && &shell =~ 'cmd'
|
|
|
|
let cmd = a:config['cmd'] . shellescape(a:file)
|
|
|
|
else
|
|
|
|
let cmd = ['sh', '-c', a:config['cmd'] . shellescape(a:file)]
|
|
|
|
endif
|
|
|
|
|
|
|
|
let options = {'cfg': a:config, 'buf': '', 'file': a:file}
|
|
|
|
if has_key(s:untracked_jobs, a:file)
|
|
|
|
if job_status(get(s:untracked_jobs, a:file)) == 'run'
|
|
|
|
return
|
|
|
|
elseif has_key(s:untracked_jobs, a:file)
|
|
|
|
call remove(s:untracked_jobs, a:file)
|
|
|
|
endif
|
|
|
|
endif
|
|
|
|
let id = job_start(cmd, {
|
|
|
|
\ 'err_io': 'out',
|
|
|
|
\ 'out_cb': function('s:on_stdout', options),
|
|
|
|
\ 'close_cb': function('s:on_exit_untracked', options)})
|
|
|
|
let s:untracked_jobs[a:file] = id
|
|
|
|
endfunction
|
|
|
|
|
2017-08-23 05:42:27 +08:00
|
|
|
elseif has("nvim")
|
|
|
|
" NVim specific functions
|
2017-08-23 05:21:19 +08:00
|
|
|
|
2017-08-30 19:15:55 +08:00
|
|
|
function! s:nvim_output_handler(job_id, data, event) dict
|
|
|
|
if a:event == 'stdout' || a:event == 'stderr'
|
2017-08-23 05:42:27 +08:00
|
|
|
let self.buf .= join(a:data)
|
2017-08-30 19:15:55 +08:00
|
|
|
endif
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
function! s:nvim_untracked_job_handler(job_id, data, event) dict
|
|
|
|
if a:event == 'exit'
|
2017-08-23 05:42:27 +08:00
|
|
|
call s:untracked_output(self, self.buf)
|
|
|
|
if has_key(s:untracked_jobs, self.file)
|
|
|
|
call remove(s:untracked_jobs, self.file)
|
|
|
|
endif
|
2017-08-23 05:21:19 +08:00
|
|
|
endif
|
2017-08-23 05:42:27 +08:00
|
|
|
endfunction
|
2017-08-23 05:21:19 +08:00
|
|
|
|
2017-08-23 05:42:27 +08:00
|
|
|
function! s:nvim_mq_job_handler(job_id, data, event) dict
|
2017-08-30 19:15:55 +08:00
|
|
|
if a:event == 'exit'
|
2017-09-23 03:37:28 +08:00
|
|
|
call airline#async#mq_output(self.buf, self.file)
|
2017-08-23 05:42:27 +08:00
|
|
|
endif
|
|
|
|
endfunction
|
2017-08-23 05:21:19 +08:00
|
|
|
|
2017-08-23 05:42:27 +08:00
|
|
|
function! s:nvim_po_job_handler(job_id, data, event) dict
|
2017-08-30 19:15:55 +08:00
|
|
|
if a:event == 'exit'
|
2017-08-23 05:42:27 +08:00
|
|
|
call s:po_output(self.buf, self.file)
|
|
|
|
call airline#extensions#po#shorten()
|
|
|
|
endif
|
|
|
|
endfunction
|
2017-08-23 05:21:19 +08:00
|
|
|
|
2017-08-23 05:42:27 +08:00
|
|
|
function! airline#async#nvim_get_mq_async(cmd, file)
|
|
|
|
let config = {
|
|
|
|
\ 'buf': '',
|
|
|
|
\ 'file': a:file,
|
2017-08-29 17:53:20 +08:00
|
|
|
\ 'cwd': s:valid_dir(fnamemodify(a:file, ':p:h')),
|
2017-08-30 19:15:55 +08:00
|
|
|
\ 'on_stdout': function('s:nvim_output_handler'),
|
|
|
|
\ 'on_stderr': function('s:nvim_output_handler'),
|
2017-08-23 05:42:27 +08:00
|
|
|
\ 'on_exit': function('s:nvim_mq_job_handler')
|
|
|
|
\ }
|
|
|
|
if g:airline#init#is_windows && &shell =~ 'cmd'
|
|
|
|
let cmd = a:cmd
|
|
|
|
else
|
|
|
|
let cmd = ['sh', '-c', a:cmd]
|
|
|
|
endif
|
|
|
|
|
|
|
|
if has_key(s:mq_jobs, a:file)
|
|
|
|
call remove(s:mq_jobs, a:file)
|
|
|
|
endif
|
|
|
|
let id = jobstart(cmd, config)
|
|
|
|
let s:mq_jobs[a:file] = id
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
function! airline#async#nvim_get_msgfmt_stat(cmd, file)
|
|
|
|
let config = {
|
|
|
|
\ 'buf': '',
|
|
|
|
\ 'file': a:file,
|
2017-08-29 17:53:20 +08:00
|
|
|
\ 'cwd': s:valid_dir(fnamemodify(a:file, ':p:h')),
|
2017-08-30 19:15:55 +08:00
|
|
|
\ 'on_stdout': function('s:nvim_output_handler'),
|
|
|
|
\ 'on_stderr': function('s:nvim_output_handler'),
|
2017-08-23 05:42:27 +08:00
|
|
|
\ 'on_exit': function('s:nvim_po_job_handler')
|
|
|
|
\ }
|
|
|
|
if g:airline#init#is_windows && &shell =~ 'cmd'
|
2017-08-23 06:00:47 +08:00
|
|
|
" no msgfmt on windows?
|
|
|
|
return
|
2017-08-23 05:42:27 +08:00
|
|
|
else
|
2017-08-23 06:00:47 +08:00
|
|
|
let cmd = ['sh', '-c', a:cmd. shellescape(a:file)]
|
2017-08-23 05:42:27 +08:00
|
|
|
endif
|
|
|
|
|
|
|
|
if has_key(s:po_jobs, a:file)
|
|
|
|
call remove(s:po_jobs, a:file)
|
|
|
|
endif
|
|
|
|
let id = jobstart(cmd, config)
|
|
|
|
let s:po_jobs[a:file] = id
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
endif
|
|
|
|
|
|
|
|
" Should work in either Vim pre 8 or Nvim
|
2017-08-23 05:21:19 +08:00
|
|
|
function! airline#async#nvim_vcs_untracked(cfg, file, vcs)
|
|
|
|
let cmd = a:cfg.cmd . shellescape(a:file)
|
2017-08-25 22:48:45 +08:00
|
|
|
let id = -1
|
2017-08-26 00:50:15 +08:00
|
|
|
let config = {
|
|
|
|
\ 'buf': '',
|
|
|
|
\ 'vcs': a:vcs,
|
|
|
|
\ 'cfg': a:cfg,
|
|
|
|
\ 'file': a:file,
|
2017-08-26 14:04:44 +08:00
|
|
|
\ 'cwd': s:valid_dir(fnamemodify(a:file, ':p:h'))
|
2017-08-26 00:50:15 +08:00
|
|
|
\ }
|
2017-08-25 22:48:45 +08:00
|
|
|
if has("nvim")
|
2017-08-26 00:50:15 +08:00
|
|
|
call extend(config, {
|
2017-08-30 19:15:55 +08:00
|
|
|
\ 'on_stdout': function('s:nvim_output_handler'),
|
2017-08-26 00:50:15 +08:00
|
|
|
\ 'on_exit': function('s:nvim_untracked_job_handler')})
|
2017-08-23 05:21:19 +08:00
|
|
|
if has_key(s:untracked_jobs, config.file)
|
|
|
|
" still running
|
|
|
|
return
|
|
|
|
endif
|
2018-03-20 21:01:46 +08:00
|
|
|
try
|
2017-08-23 05:21:19 +08:00
|
|
|
let id = jobstart(cmd, config)
|
2018-03-20 21:01:46 +08:00
|
|
|
catch
|
|
|
|
" catch-all, jobstart() failed, fall back to system()
|
|
|
|
let id=-1
|
|
|
|
endtry
|
2017-08-23 05:21:19 +08:00
|
|
|
let s:untracked_jobs[a:file] = id
|
|
|
|
endif
|
|
|
|
" vim without job feature or nvim jobstart failed
|
|
|
|
if id < 1
|
|
|
|
let output=system(cmd)
|
|
|
|
call s:untracked_output(config, output)
|
|
|
|
call airline#extensions#branch#update_untracked_config(a:file, a:vcs)
|
|
|
|
endif
|
|
|
|
endfunction
|