mirror of
https://github.com/SpaceVim/SpaceVim.git
synced 2025-02-03 23:50:05 +08:00
145 lines
4.0 KiB
VimL
145 lines
4.0 KiB
VimL
|
scriptencoding utf-8
|
||
|
|
||
|
let s:Git = vital#gina#import('Git')
|
||
|
let s:Path = vital#gina#import('System.Filepath')
|
||
|
let s:Store = vital#gina#import('System.Store')
|
||
|
|
||
|
|
||
|
function! gina#component#traffic#ahead() abort
|
||
|
let git = gina#core#get()
|
||
|
if empty(git)
|
||
|
return ''
|
||
|
endif
|
||
|
let slug = eval(s:Store.get_slug_expr())
|
||
|
let ref = get(s:Git.ref(git, 'HEAD'), 'path', 'HEAD')
|
||
|
let track = s:get_tracking_ref(git)
|
||
|
let store = s:Store.of([
|
||
|
\ s:Git.resolve(git, 'index'),
|
||
|
\ s:Git.resolve(git, ref),
|
||
|
\ s:Git.resolve(git, track),
|
||
|
\])
|
||
|
let ahead = store.get(slug, '')
|
||
|
if !empty(ahead)
|
||
|
return str2nr(ahead)
|
||
|
endif
|
||
|
if !exists('s:ahead_job')
|
||
|
let pipe = gina#process#pipe#store()
|
||
|
let pipe.__on_exit = pipe.on_exit
|
||
|
let pipe.on_exit = funcref('s:ahead_on_exit', [store, slug])
|
||
|
let s:ahead_job = gina#process#open(git, [
|
||
|
\ 'log',
|
||
|
\ '--oneline',
|
||
|
\ '@{upstream}..',
|
||
|
\], pipe)
|
||
|
endif
|
||
|
return ''
|
||
|
endfunction
|
||
|
|
||
|
function! gina#component#traffic#behind() abort
|
||
|
let git = gina#core#get()
|
||
|
if empty(git)
|
||
|
return ''
|
||
|
endif
|
||
|
let slug = eval(s:Store.get_slug_expr())
|
||
|
let ref = get(s:Git.ref(git, 'HEAD'), 'path', 'HEAD')
|
||
|
let track = s:get_tracking_ref(git)
|
||
|
let store = s:Store.of([
|
||
|
\ s:Git.resolve(git, 'index'),
|
||
|
\ s:Git.resolve(git, ref),
|
||
|
\ s:Git.resolve(git, track),
|
||
|
\])
|
||
|
let behind = store.get(slug, '')
|
||
|
if !empty(behind)
|
||
|
return str2nr(behind)
|
||
|
endif
|
||
|
if !exists('s:behind_job')
|
||
|
let pipe = gina#process#pipe#store()
|
||
|
let pipe.__on_exit = pipe.on_exit
|
||
|
let pipe.on_exit = funcref('s:behind_on_exit', [store, slug])
|
||
|
let s:behind_job = gina#process#open(git, [
|
||
|
\ 'log',
|
||
|
\ '--oneline',
|
||
|
\ '..@{upstream}',
|
||
|
\], pipe)
|
||
|
endif
|
||
|
return ''
|
||
|
endfunction
|
||
|
|
||
|
function! gina#component#traffic#preset(...) abort
|
||
|
let git = gina#core#get()
|
||
|
if empty(git)
|
||
|
return ''
|
||
|
endif
|
||
|
let kind = get(a:000, 0, 'ascii')
|
||
|
return call('s:preset_' . kind, [])
|
||
|
endfunction
|
||
|
|
||
|
" Private --------------------------------------------------------------------
|
||
|
function! s:ahead_on_exit(store, slug, exitval) abort dict
|
||
|
call self.__on_exit(a:exitval)
|
||
|
silent! unlet! s:ahead_job
|
||
|
if a:exitval
|
||
|
return
|
||
|
endif
|
||
|
let ahead = len(filter(copy(self.stdout), '!empty(v:val)')) . ''
|
||
|
call a:store.set(a:slug, ahead)
|
||
|
endfunction
|
||
|
|
||
|
function! s:behind_on_exit(store, slug, exitval) abort dict
|
||
|
call self.__on_exit(a:exitval)
|
||
|
silent! unlet! s:behind_job
|
||
|
if a:exitval
|
||
|
return
|
||
|
endif
|
||
|
let behind = len(filter(copy(self.stdout), '!empty(v:val)')) . ''
|
||
|
call a:store.set(a:slug, behind)
|
||
|
endfunction
|
||
|
|
||
|
function! s:get_tracking_ref(git) abort
|
||
|
let slug = eval(s:Store.get_slug_expr())
|
||
|
let store = s:Store.of([
|
||
|
\ s:Git.resolve(a:git, 'HEAD'),
|
||
|
\ s:Git.resolve(a:git, 'config'),
|
||
|
\])
|
||
|
let ref = store.get(slug, '')
|
||
|
if !empty(ref)
|
||
|
return ref
|
||
|
endif
|
||
|
if !exists('s:tracking_ref_job')
|
||
|
let pipe = gina#process#pipe#store()
|
||
|
let pipe.__on_exit = pipe.on_exit
|
||
|
let pipe.on_exit = funcref('s:tracking_ref_on_exit', [store, slug])
|
||
|
let s:tracking_ref_job = gina#process#open(a:git, [
|
||
|
\ 'rev-parse',
|
||
|
\ '--symbolic-full-name',
|
||
|
\ '@{upstream}',
|
||
|
\], pipe)
|
||
|
endif
|
||
|
return ''
|
||
|
endfunction
|
||
|
|
||
|
function! s:tracking_ref_on_exit(store, slug, exitval) abort dict
|
||
|
call self.__on_exit(a:exitval)
|
||
|
silent! unlet! s:tracking_ref_job
|
||
|
if a:exitval
|
||
|
return
|
||
|
endif
|
||
|
call a:store.set(a:slug, get(self.stdout, 0))
|
||
|
endfunction
|
||
|
|
||
|
function! s:preset_ascii() abort
|
||
|
let ahead = gina#component#traffic#ahead()
|
||
|
let behind = gina#component#traffic#behind()
|
||
|
let ahead = empty(ahead) ? '' : ('^' . ahead)
|
||
|
let behind = empty(behind) ? '' : ('v' . behind)
|
||
|
return join(filter([ahead, behind], '!empty(v:val)'))
|
||
|
endfunction
|
||
|
|
||
|
function! s:preset_fancy() abort
|
||
|
let ahead = gina#component#traffic#ahead()
|
||
|
let behind = gina#component#traffic#behind()
|
||
|
let ahead = empty(ahead) ? '' : ('↑' . ahead)
|
||
|
let behind = empty(behind) ? '' : ('↓' . behind)
|
||
|
return join(filter([ahead, behind], '!empty(v:val)'))
|
||
|
endfunction
|