branch: display dirty state

If the repository is considered dirty, do display the
g:airline_symbols.dirty symbol right after the branch name.
This commit is contained in:
Christian Brabandt
2019-04-24 15:15:29 +02:00
parent a8c96d7c07
commit 9112675ad8
5 changed files with 93 additions and 5 deletions
+73
View File
@@ -6,6 +6,7 @@ scriptencoding utf-8
let s:untracked_jobs = {}
let s:mq_jobs = {}
let s:po_jobs = {}
let s:clean_jobs = {}
" Generic functions handling on exit event of the various async functions
function! s:untracked_output(dict, buf)
@@ -63,6 +64,29 @@ function! airline#async#vcs_untracked(config, file, vcs)
endif
endfunction
function! s:on_exit_clean(...) dict abort
let buf=self.buf
if !empty(buf)
let var=getbufvar(self.file, 'buffer_vcs_config', {})
let var[self.vcs].dirty=1
call setbufvar(self.file, 'buffer_vcs_config', var)
unlet! b:airline_head
endif
if has_key(get(s:clean_jobs, 'self.vcs', {}), self.file)
call remove(s:clean_jobs[self.vcs], self.file)
endif
endfunction
function! airline#async#vcs_clean(cmd, file, vcs)
if g:airline#init#vim_async
" Vim 8 with async support
noa call airline#async#vim_vcs_clean(a:cmd, a:file, a:vcs)
else
" nvim async or vim without job-feature
noa call airline#async#nvim_vcs_clean(a:cmd, a:file, a:vcs)
endif
endfunction
if v:version >= 800 && has("job")
" Vim 8.0 with Job feature
" TODO: Check if we need the cwd option for the job_start() functions
@@ -133,6 +157,29 @@ if v:version >= 800 && has("job")
let s:po_jobs[a:file] = id
endfunction
function! airline#async#vim_vcs_clean(cmd, file, vcs)
if g:airline#init#is_windows && &shell =~ 'cmd'
let cmd = a:cmd
else
let cmd = ['sh', '-c', a:cmd]
endif
let options = {'buf': '', 'vcs': a:vcs, 'file': a:file}
let jobs = get(s:clean_jobs, a:vcs, {})
if has_key(jobs, a:file)
if job_status(get(jobs, a:file)) == 'run'
return
elseif has_key(jobs, a:file)
call remove(jobs, a:file)
endif
endif
let id = job_start(cmd, {
\ 'err_io': 'null',
\ 'out_cb': function('s:on_stdout', options),
\ 'close_cb': function('s:on_exit_clean', options)})
let jobs[a:file] = id
endfunction
function! airline#async#vim_vcs_untracked(config, file)
if g:airline#init#is_windows && &shell =~ 'cmd'
let cmd = a:config['cmd'] . shellescape(a:file)
@@ -208,6 +255,32 @@ elseif has("nvim")
let s:mq_jobs[a:file] = id
endfunction
function! airline#async#nvim_vcs_clean(cmd, file, vcs)
let config = {
\ 'buf': '',
\ 'vcs': a:vcs,
\ 'file': a:file,
\ 'cwd': s:valid_dir(fnamemodify(a:file, ':p:h')),
\ 'on_stdout': function('s:nvim_output_handler'),
\ 'on_stderr': function('s:nvim_output_handler'),
\ 'on_exit': function('s:on_exit_clean')
\ }
if g:airline#init#is_windows && &shell =~ 'cmd'
let cmd = a:cmd
else
let cmd = ['sh', '-c', a:cmd]
endif
if !has_key(s:clean_jobs, a:vcs)
let s:clean_jobs[a:vcs] = {}
endif
if has_key(s:clean_jobs[a:vcs], a:file)
call remove(s:clean_jobs[a:vcs], a:file)
endif
let id = jobstart(cmd, config)
let s:clean_jobs[a:vcs][a:file] = id
endfunction
function! airline#async#nvim_get_msgfmt_stat(cmd, file)
let config = {
\ 'buf': '',
+12 -3
View File
@@ -17,6 +17,7 @@ let s:vcs_config = {
\ 'git': {
\ 'exe': 'git',
\ 'cmd': 'git status --porcelain -- ',
\ 'dirty': 'git status --porcelain',
\ 'untracked_mark': '??',
\ 'exclude': '\.git',
\ 'update_branch': 's:update_git_branch',
@@ -27,6 +28,7 @@ let s:vcs_config = {
\ 'mercurial': {
\ 'exe': 'hg',
\ 'cmd': 'hg status -u -- ',
\ 'dirty': 'hg status -muard',
\ 'untracked_mark': '?',
\ 'exclude': '\.hg',
\ 'update_branch': 's:update_hg_branch',
@@ -51,6 +53,7 @@ function! s:init_buffer()
let b:buffer_vcs_config[vcs] = {
\ 'branch': '',
\ 'untracked': '',
\ 'dirty': 0,
\ }
endfor
unlet! b:airline_head
@@ -200,6 +203,8 @@ function! s:update_untracked()
" result of the previous call, i.e. the head string is not updated. It
" doesn't happen often in practice, so we let it be.
call airline#async#vcs_untracked(config, file, vcs)
" Check clean state of repo
call airline#async#vcs_clean(config.dirty, file, vcs)
endfor
endfunction
@@ -233,7 +238,11 @@ function! airline#extensions#branch#head()
let b:airline_head .= s:vcs_config[vcs].exe .':'
endif
let b:airline_head .= s:format_name({s:vcs_config[vcs].display_branch}())
let b:airline_head .= b:buffer_vcs_config[vcs].untracked
let additional = b:buffer_vcs_config[vcs].untracked
if empty(additional) && b:buffer_vcs_config[vcs].dirty
let additional = g:airline_symbols['dirty']
endif
let b:airline_head .= additional
endfor
if empty(heads)
@@ -269,10 +278,10 @@ function! airline#extensions#branch#get_head()
let winwidth = get(airline#parts#get('branch'), 'minwidth', 120)
let minwidth = empty(get(b:, 'airline_hunks', '')) ? 14 : 7
let head = airline#util#shorten(head, winwidth, minwidth)
let empty_message = get(g:, 'airline#extensions#branch#empty_message', '')
let symbol = get(g:, 'airline#extensions#branch#symbol', g:airline_symbols.branch)
let dirty = get(b:, 'airline_branch_dirty', '')
return empty(head)
\ ? empty_message
\ ? get(g:, 'airline#extensions#branch#empty_message', '')
\ : printf('%s%s', empty(symbol) ? '' : symbol.(g:airline_symbols.space), head)
endfunction
+3 -1
View File
@@ -86,7 +86,7 @@ function! airline#init#bootstrap()
call s:check_defined('g:airline_left_alt_sep', "\ue0b1") " 
call s:check_defined('g:airline_right_sep', "\ue0b2") " 
call s:check_defined('g:airline_right_alt_sep', "\ue0b3") " 
" ro=, ws=☲, lnr=☰, mlnr=, br=, nx=Ɇ, crypt=🔒
" ro=, ws=☲, lnr=☰, mlnr=, br=, nx=Ɇ, crypt=🔒, dirty=⚡
call extend(g:airline_symbols, {
\ 'readonly': "\ue0a2",
\ 'whitespace': "\u2632",
@@ -94,6 +94,7 @@ function! airline#init#bootstrap()
\ 'maxlinenr': " \ue0a1",
\ 'branch': "\ue0a0",
\ 'notexists': "\u0246",
\ 'dirty': "\u26a1",
\ 'crypt': nr2char(0x1F512),
\ }, 'keep')
elseif &encoding==?'utf-8' && !get(g:, "airline_symbols_ascii", 0)
@@ -111,6 +112,7 @@ function! airline#init#bootstrap()
\ 'branch': "\u16A0",
\ 'notexists': "\u0246",
\ 'crypt': nr2char(0x1F512),
\ 'dirty': '!',
\ }, 'keep')
else
" Symbols for ASCII terminals