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

148 lines
3.9 KiB
VimL
Vendored
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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