mirror of
https://github.com/SpaceVim/SpaceVim.git
synced 2025-02-03 20:00:06 +08:00
148 lines
3.9 KiB
VimL
148 lines
3.9 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')
|
|||
|
|
|||
|
let s:SLUG = eval(s:Store.get_slug_expr())
|
|||
|
|
|||
|
|
|||
|
function! gina#component#status#staged() abort
|
|||
|
let git = gina#core#get()
|
|||
|
if empty(git)
|
|||
|
return ''
|
|||
|
endif
|
|||
|
let c = get(s:status_count(git), 'staged', 0)
|
|||
|
return c == 0 ? '' : (c . '')
|
|||
|
endfunction
|
|||
|
|
|||
|
function! gina#component#status#unstaged() abort
|
|||
|
let git = gina#core#get()
|
|||
|
if empty(git)
|
|||
|
return ''
|
|||
|
endif
|
|||
|
let c = get(s:status_count(git), 'unstaged', 0)
|
|||
|
return c == 0 ? '' : (c . '')
|
|||
|
endfunction
|
|||
|
|
|||
|
function! gina#component#status#conflicted() abort
|
|||
|
let git = gina#core#get()
|
|||
|
if empty(git)
|
|||
|
return ''
|
|||
|
endif
|
|||
|
let c = get(s:status_count(git), 'conflicted', 0)
|
|||
|
return c == 0 ? '' : (c . '')
|
|||
|
endfunction
|
|||
|
|
|||
|
function! gina#component#status#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:get_store(git) abort
|
|||
|
let ref = get(s:Git.ref(a:git, 'HEAD'), 'path', 'HEAD')
|
|||
|
let store = s:Store.of([
|
|||
|
\ s:Git.resolve(a:git, 'index'),
|
|||
|
\ s:Git.resolve(a:git, ref),
|
|||
|
\])
|
|||
|
return store
|
|||
|
endfunction
|
|||
|
|
|||
|
function! s:status_count(git) abort
|
|||
|
let store = s:get_store(a:git)
|
|||
|
let status_count = store.get(s:SLUG, {})
|
|||
|
if !empty(status_count)
|
|||
|
return status_count
|
|||
|
endif
|
|||
|
if !exists('s:status_job')
|
|||
|
let pipe = gina#process#pipe#store()
|
|||
|
let pipe.__on_exit = pipe.on_exit
|
|||
|
let pipe.on_exit = funcref('s:status_on_exit', [store])
|
|||
|
let s:status_job = gina#process#open(a:git, [
|
|||
|
\ 'status',
|
|||
|
\ '--porcelain',
|
|||
|
\ '--ignore-submodules',
|
|||
|
\], pipe)
|
|||
|
endif
|
|||
|
return {
|
|||
|
\ 'staged': 0,
|
|||
|
\ 'unstaged': 0,
|
|||
|
\ 'conflicted': 0,
|
|||
|
\}
|
|||
|
endfunction
|
|||
|
|
|||
|
function! s:status_on_exit(store, exitval) abort dict
|
|||
|
call self.__on_exit(a:exitval)
|
|||
|
silent! unlet! s:status_job
|
|||
|
if a:exitval
|
|||
|
return
|
|||
|
endif
|
|||
|
let status_count = {
|
|||
|
\ 'staged': 0,
|
|||
|
\ 'unstaged': 0,
|
|||
|
\ 'conflicted': 0,
|
|||
|
\}
|
|||
|
for record in self.stdout
|
|||
|
let sign = record[:1]
|
|||
|
if sign =~# '^\%(DD\|AU\|UD\|UA\|DU\|AA\|UU\)$'
|
|||
|
let status_count.conflicted += 1
|
|||
|
elseif sign ==# '??' || sign ==# '!!'
|
|||
|
continue
|
|||
|
else
|
|||
|
if sign =~# '^\S.$'
|
|||
|
let status_count.staged += 1
|
|||
|
endif
|
|||
|
if sign =~# '^.\S$'
|
|||
|
let status_count.unstaged += 1
|
|||
|
endif
|
|||
|
endif
|
|||
|
endfor
|
|||
|
call a:store.set(s:SLUG, status_count)
|
|||
|
endfunction
|
|||
|
|
|||
|
function! s:preset_ascii() abort
|
|||
|
let staged = gina#component#status#staged()
|
|||
|
let unstaged = gina#component#status#unstaged()
|
|||
|
let conflicted = gina#component#status#conflicted()
|
|||
|
let staged = empty(staged) ? '' : ('<' . staged)
|
|||
|
let unstaged = empty(unstaged) ? '' : ('>' . unstaged)
|
|||
|
let conflicted = empty(conflicted) ? '' : ('x' . conflicted)
|
|||
|
return join(filter([staged, unstaged, conflicted], '!empty(v:val)'))
|
|||
|
endfunction
|
|||
|
|
|||
|
function! s:preset_fancy() abort
|
|||
|
let staged = gina#component#status#staged()
|
|||
|
let unstaged = gina#component#status#unstaged()
|
|||
|
let conflicted = gina#component#status#conflicted()
|
|||
|
let staged = empty(staged) ? '' : ('«' . staged)
|
|||
|
let unstaged = empty(unstaged) ? '' : ('»' . unstaged)
|
|||
|
let conflicted = empty(conflicted) ? '' : ('×' . conflicted)
|
|||
|
return join(filter([staged, unstaged, conflicted], '!empty(v:val)'))
|
|||
|
endfunction
|
|||
|
|
|||
|
" NOTE:
|
|||
|
" Tracked files might be changed (unstaged) so remove cache when 'modified'
|
|||
|
" event has called.
|
|||
|
function! s:on_modified(...) abort
|
|||
|
let git = gina#core#get()
|
|||
|
if empty(git)
|
|||
|
return
|
|||
|
endif
|
|||
|
let store = s:get_store(git)
|
|||
|
call store.remove(s:SLUG)
|
|||
|
endfunction
|
|||
|
|
|||
|
if !exists('s:subscribed')
|
|||
|
let s:subscribed = 1
|
|||
|
call gina#core#emitter#subscribe(
|
|||
|
\ 'modified',
|
|||
|
\ function('s:on_modified')
|
|||
|
\)
|
|||
|
endif
|