commit 88f50bba604f353c21dea554bf9932ad5c76265e (tree)
parent 9bd7c264662e7ed5e58b29898508b290f0b260eb
Author: Tim Pope <code@tpope.net>
Date: Mon, 29 Mar 2021 20:05:00 -0400
Press escape to background :Git to preview window
This can one day hopefully be generalized to handle --paginate, but for
now, leave it as undocumented experiment.
Diffstat:
| M | autoload/fugitive.vim | | | 97 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------ |
1 file changed, 90 insertions(+), 7 deletions(-)
diff --git a/autoload/fugitive.vim b/autoload/fugitive.vim
@@ -2365,7 +2365,9 @@ endfunction
function! s:TempReadPost(file) abort
if has_key(s:temp_files, s:cpath(a:file))
let dict = s:temp_files[s:cpath(a:file)]
- setlocal nobuflisted
+ if !has_key(dict, 'job')
+ setlocal nobuflisted
+ endif
if get(dict, 'filetype', '') ==# 'git'
call fugitive#MapJumps()
endif
@@ -2414,7 +2416,7 @@ function! s:AskPassArgs(dir) abort
endfunction
function! s:RunJobs() abort
- return exists('*job_start') || exists('*jobstart')
+ return (exists('*job_start') || exists('*jobstart')) && exists('*bufwinid')
endfunction
function! s:RunSave(state) abort
@@ -2430,6 +2432,10 @@ function! s:RunFinished(state, ...) abort
if get(a:state, 'filetype', '') ==# 'git' && first =~# '\<\([[:upper:][:digit:]_-]\+(\d\+)\).*\1'
let a:state.filetype = 'man'
endif
+ if !has_key(a:state, 'capture_bufnr')
+ return
+ endif
+ call fugitive#ReloadStatus(a:state, 1)
endfunction
function! s:RunEdit(state, tmp, job) abort
@@ -2479,6 +2485,38 @@ function! s:RunReceive(state, tmp, type, job, data, ...) abort
endif
let a:tmp.echo .= data
endif
+ let line_count = a:tmp.line_count
+ let a:tmp.line_count += len(lines) - 1
+ if !has_key(a:state, 'capture_bufnr') || !bufloaded(a:state.capture_bufnr)
+ return
+ endif
+ call remove(lines, -1)
+ try
+ call setbufvar(a:state.capture_bufnr, '&modifiable', 1)
+ if !line_count && len(lines) > 1000
+ let first = remove(lines, 0, 999)
+ call setbufline(a:state.capture_bufnr, 1, first)
+ redraw
+ call setbufline(a:state.capture_bufnr, 1001, lines)
+ else
+ call setbufline(a:state.capture_bufnr, line_count + 1, lines)
+ endif
+ call setbufvar(a:state.capture_bufnr, '&modifiable', 0)
+ if !getwinvar(bufwinid(a:state.capture_bufnr), '&previewwindow')
+ " no-op
+ elseif exists('*win_execute')
+ call win_execute(bufwinid(a:state.capture_bufnr), '$')
+ else
+ let winnr = bufwinnr(a:state.capture_bufnr)
+ if winnr > 0
+ let old_winnr = winnr()
+ exe 'noautocmd' winnr.'wincmd w'
+ $
+ exe 'noautocmd' old_winnr.'wincmd w'
+ endif
+ endif
+ catch
+ endtry
endfunction
function! s:RunExit(state, tmp, job, exit_status) abort
@@ -2496,6 +2534,19 @@ function! s:RunClose(state, tmp, job, ...) abort
let noeol = substitute(substitute(a:tmp.err, "\r$", '', ''), ".*\r", '', '') . a:tmp.out
call writefile([noeol], a:state.file, 'ba')
call remove(a:state, 'job')
+ if has_key(a:state, 'capture_bufnr') && bufloaded(a:state.capture_bufnr)
+ if len(noeol)
+ call setbufvar(a:state.capture_bufnr, '&modifiable', 1)
+ call setbufline(a:state.capture_bufnr, a:tmp.line_count + 1, [noeol])
+ call setbufvar(a:state.capture_bufnr, '&eol', 0)
+ call setbufvar(a:state.capture_bufnr, '&modifiable', 0)
+ endif
+ call setbufvar(a:state.capture_bufnr, '&modified', 0)
+ call setbufvar(a:state.capture_bufnr, '&buflisted', 0)
+ if a:state.filetype !=# getbufvar(a:state.capture_bufnr, '&filetype', '')
+ call setbufvar(a:state.capture_bufnr, '&filetype', a:state.filetype)
+ endif
+ endif
if !has_key(a:state, 'exit_status')
return
endif
@@ -2552,13 +2603,31 @@ function! s:RunWait(state, tmp, job, ...) abort
if peek != 0 && !(has('win32') && peek == 128)
let c = getchar()
let c = type(c) == type(0) ? nr2char(c) : c
- if c ==# "\<C-D>"
+ if c ==# "\<C-D>" || c ==# "\<Esc>"
let a:state.closed_in = 1
if type(a:job) ==# type(0)
call chanclose(a:job, 'stdin')
else
call ch_close_in(a:job)
endif
+ let can_pedit = exists('*setbufline')
+ for winnr in range(1, winnr('$'))
+ if getwinvar(winnr, '&previewwindow') && getbufvar(winbufnr(winnr), '&modified')
+ let can_pedit = 0
+ endif
+ endfor
+ if can_pedit
+ if has_key(a:tmp, 'echo')
+ call remove(a:tmp, 'echo')
+ endif
+ call writefile(['fugitive: aborting edit due to background operation.'], a:state.file . '.exit')
+ exe (&splitbelow ? 'botright' : 'topleft') 'silent pedit ++ff=unix' fnameescape(a:state.file)
+ let a:state.capture_bufnr = bufnr(a:state.file)
+ call setbufvar(a:state.capture_bufnr, '&modified', 1)
+ let finished = 0
+ redraw!
+ return ''
+ endif
else
call s:RunSend(a:job, c)
if !a:state.pty
@@ -2601,13 +2670,26 @@ if !exists('s:resume_queue')
endif
function! fugitive#Resume() abort
while len(s:resume_queue)
- try
- call call('s:RunWait', remove(s:resume_queue, 0))
- endtry
+ if s:resume_queue[0][2] isnot# ''
+ try
+ call call('s:RunWait', remove(s:resume_queue, 0))
+ endtry
+ endif
endwhile
endfunction
function! s:RunBufDelete(bufnr) abort
+ let state = s:TempState(bufname(+a:bufnr))
+ if has_key(state, 'job')
+ try
+ if type(state.job) == type(0)
+ call jobstop(state.job)
+ else
+ call job_stop(state.job)
+ endif
+ catch
+ endtry
+ endif
if has_key(s:edit_jobs, a:bufnr) |
call add(s:resume_queue, remove(s:edit_jobs, a:bufnr))
call feedkeys(":redraw!|call delete(" . string(s:resume_queue[-1][0].file . '.edit') .
@@ -2617,7 +2699,7 @@ endfunction
augroup fugitive_job
autocmd!
- autocmd BufDelete * call s:RunBufDelete(expand('<abuf>'))
+ autocmd BufDelete * call s:RunBufDelete(+expand('<abuf>'))
autocmd VimLeave *
\ for s:jobbuf in keys(s:edit_jobs) |
\ call writefile(['Aborting edit due to Vim exit.'], s:edit_jobs[s:jobbuf][0].file . '.exit') |
@@ -2782,6 +2864,7 @@ function! fugitive#Command(line1, line2, range, bang, mods, arg) abort
let args = s:AskPassArgs(dir) + args
endif
let tmp = {
+ \ 'line_count': 0,
\ 'err': '',
\ 'out': '',
\ 'echo': '',