Skip to content

Commit 8c8cdf4

Browse files
committed
Use callback based workflow for status buffer
1 parent 5661dea commit 8c8cdf4

File tree

1 file changed

+75
-39
lines changed

1 file changed

+75
-39
lines changed

autoload/fugitive.vim

Lines changed: 75 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2730,50 +2730,21 @@ function! s:MapStatus() abort
27302730
call s:Map('x', '.', ':<C-U> <C-R>=<SID>StageArgs(1)<CR><Home>')
27312731
endfunction
27322732

2733-
function! fugitive#BufReadStatus(cmdbang) abort
2734-
exe s:VersionCheck()
2735-
let amatch = s:Slash(expand('%:p'))
2736-
if a:cmdbang
2737-
unlet! b:fugitive_expanded
2738-
endif
2739-
let b:fugitive_type = 'index'
2740-
let dir = s:Dir()
2741-
let stat = {'bufnr': bufnr(''), 'reltime': reltime(), 'work_tree': s:Tree(dir)}
2733+
function! s:StatusProcess(result, stat) abort
2734+
let stat = a:stat
2735+
let status_exec = a:stat.status
2736+
let config = a:stat.config
2737+
let dir = s:Dir(config)
27422738
try
2743-
let b:fugitive_loading = stat
2744-
let config = fugitive#Config(dir)
2745-
2746-
let cmd = [dir]
2747-
if amatch !~# '^fugitive:' && s:cpath($GIT_INDEX_FILE !=# '' ? resolve(s:GitIndexFileEnv()) : fugitive#Find('.git/index', dir)) !=# s:cpath(amatch)
2748-
let cmd += [{'env': {'GIT_INDEX_FILE': FugitiveGitPath(amatch)}}]
2749-
endif
2750-
2751-
if fugitive#GitVersion(2, 15)
2752-
call add(cmd, '--no-optional-locks')
2753-
endif
2754-
2755-
let rev_parse_cmd = cmd + ['rev-parse', '--short', 'HEAD', '--']
2756-
let stat.rev_parse = fugitive#Execute(rev_parse_cmd, function('len'))
2757-
2758-
if !empty(stat.work_tree)
2759-
let status_cmd = cmd + ['status', '-bz']
2760-
call add(status_cmd, fugitive#GitVersion(2, 11) ? '--porcelain=v2' : '--porcelain')
2761-
let status_exec = fugitive#Execute(status_cmd, function('len'))
2762-
endif
2763-
2764-
doautocmd <nomodeline> BufReadPre
2765-
2766-
setlocal readonly nomodifiable noswapfile nomodeline buftype=nowrite
2767-
call s:MapStatus()
2768-
27692739
let [staged, unstaged, untracked] = [[], [], []]
27702740
let stat.props = {}
27712741

2772-
if !exists('status_exec')
2742+
if empty(status_exec)
27732743
let stat.branch = FugitiveHead(0, config)
27742744

2775-
elseif fugitive#Wait(status_exec).exit_status
2776-
return 'echoerr ' . string('fugitive: ' . s:JoinChomp(status_exec.stderr))
2745+
elseif status_exec.exit_status
2746+
let stat.error = s:JoinChomp(status_exec.stderr)
2747+
return
27772748

27782749
elseif status_exec.args[-1] ==# '--porcelain=v2'
27792750
let output = split(tr(join(status_exec.stdout, "\1"), "\1\n", "\n\1"), "\1", 1)[0:-2]
@@ -2850,7 +2821,7 @@ function! fugitive#BufReadStatus(cmdbang) abort
28502821
endwhile
28512822
endif
28522823

2853-
let diff_cmd = cmd + ['-c', 'diff.suppressBlankEmpty=false', '-c', 'core.quotePath=false', 'diff', '--color=never', '--no-ext-diff', '--no-prefix']
2824+
let diff_cmd = stat.cmd + ['-c', 'diff.suppressBlankEmpty=false', '-c', 'core.quotePath=false', 'diff', '--color=never', '--no-ext-diff', '--no-prefix']
28542825
let stat.diff = {'Staged': {'stdout': ['']}, 'Unstaged': {'stdout': ['']}}
28552826
if len(staged)
28562827
let stat.diff['Staged'] = fugitive#Execute(diff_cmd + ['--cached'], function('len'))
@@ -2859,6 +2830,8 @@ function! fugitive#BufReadStatus(cmdbang) abort
28592830
let stat.diff['Unstaged'] = fugitive#Execute(diff_cmd + ['--'] + map(copy(unstaged), 'stat.work_tree . "/" . v:val.relative[0]'), function('len'))
28602831
endif
28612832

2833+
let [stat.staged, stat.unstaged, stat.untracked] = [staged, unstaged, untracked]
2834+
28622835
let stat.files = {'Staged': {}, 'Unstaged': {}}
28632836
for dict in staged
28642837
let stat.files['Staged'][dict.filename] = dict
@@ -2910,6 +2883,18 @@ function! fugitive#BufReadStatus(cmdbang) abort
29102883
let stat.pull_type = 'Merge'
29112884
endif
29122885
endif
2886+
endtry
2887+
endfunction
2888+
2889+
function! s:StatusRender(stat) abort
2890+
try
2891+
let stat = a:stat
2892+
call fugitive#Wait(stat.running)
2893+
if has_key(stat, 'error')
2894+
return 'echoerr ' . string('fugitive: ' . stat.error)
2895+
endif
2896+
let [staged, unstaged, untracked, config] = [stat.staged, stat.unstaged, stat.untracked, stat.config]
2897+
let dir = s:Dir(config)
29132898

29142899
let pull_ref = stat.merge
29152900
if stat.fetch_remote !=# '.'
@@ -3028,6 +3013,57 @@ function! fugitive#BufReadStatus(cmdbang) abort
30283013
call setbufvar(bufnr, 'fugitive_status', stat)
30293014
call setbufvar(bufnr, 'fugitive_expanded', stat.expanded)
30303015
setlocal nomodified readonly nomodifiable
3016+
return ''
3017+
finally
3018+
let b:fugitive_type = 'index'
3019+
endtry
3020+
endfunction
3021+
3022+
function! s:StatusRetrieve(bufnr, ...) abort
3023+
let amatch = s:Slash(fnamemodify(bufname(a:bufnr), ':p'))
3024+
let dir = s:Dir(a:bufnr)
3025+
let config = fugitive#Config(dir, function('len'))
3026+
3027+
let cmd = [dir]
3028+
if amatch !~# '^fugitive:' && s:cpath($GIT_INDEX_FILE !=# '' ? resolve(s:GitIndexFileEnv()) : fugitive#Find('.git/index', dir)) !=# s:cpath(amatch)
3029+
let cmd += [{'env': {'GIT_INDEX_FILE': FugitiveGitPath(amatch)}}]
3030+
endif
3031+
3032+
if fugitive#GitVersion(2, 15)
3033+
call add(cmd, '--no-optional-locks')
3034+
endif
3035+
3036+
let rev_parse_cmd = cmd + ['rev-parse', '--short', 'HEAD', '--']
3037+
3038+
let stat = {'bufnr': a:bufnr, 'reltime': reltime(), 'work_tree': s:Tree(dir), 'cmd': cmd, 'config': config}
3039+
if empty(stat.work_tree)
3040+
let stat.rev_parse = call('fugitive#Execute', [rev_parse_cmd, function('s:StatusProcess'), stat] + a:000)
3041+
let stat.status = {}
3042+
let stat.running = stat.rev_parse
3043+
else
3044+
let stat.rev_parse = fugitive#Execute(rev_parse_cmd)
3045+
let status_cmd = cmd + ['status', '-bz', fugitive#GitVersion(2, 11) ? '--porcelain=v2' : '--porcelain']
3046+
let stat.status = call('fugitive#Execute', [status_cmd, function('s:StatusProcess'), stat] + a:000)
3047+
let stat.running = stat.status
3048+
endif
3049+
return stat
3050+
endfunction
3051+
3052+
function! fugitive#BufReadStatus(cmdbang) abort
3053+
exe s:VersionCheck()
3054+
if a:cmdbang
3055+
unlet! b:fugitive_expanded
3056+
endif
3057+
let b:fugitive_type = 'index'
3058+
let stat = s:StatusRetrieve(bufnr(''))
3059+
try
3060+
let b:fugitive_loading = stat
3061+
doautocmd <nomodeline> BufReadPre
3062+
3063+
setlocal readonly nomodifiable noswapfile nomodifiable buftype=nowrite
3064+
call s:MapStatus()
3065+
3066+
call s:StatusRender(stat)
30313067

30323068
doautocmd <nomodeline> BufReadPost
30333069
if &bufhidden ==# ''

0 commit comments

Comments
 (0)