Allow pressing 'q' to abort the running tasks, then 'R' to retry (#1289)

If you press 'q' while `PlugInstall` or `PlugUpdate` is in progress,
the current version of vim-plug immediately closes its window and aborts
all the running processes.

This commit enhances the 'q' map so that it doesn't close the window,
but instead displays the aborted tasks so that the user can press 'R' to
retry the tasks.

Fix #1285
This commit is contained in:
Junegunn Choi 2024-07-09 20:09:41 +09:00 committed by GitHub
parent d863d07832
commit d80f495fab
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 44 additions and 11 deletions

View File

@ -315,7 +315,7 @@ vim.cmd('silent! colorscheme seoul256')
- `S` - `PlugStatus`
- `R` - Retry failed update or installation tasks
- `U` - Update plugins in the selected range
- `q` - Close the window
- `q` - Abort the running tasks or close the window
- `:PlugStatus`
- `L` - Load plugin
- `:PlugDiff`

View File

@ -783,10 +783,11 @@ endfunction
function! s:syntax()
syntax clear
syntax region plug1 start=/\%1l/ end=/\%2l/ contains=plugNumber
syntax region plug2 start=/\%2l/ end=/\%3l/ contains=plugBracket,plugX
syntax region plug2 start=/\%2l/ end=/\%3l/ contains=plugBracket,plugX,plugAbort
syn match plugNumber /[0-9]\+[0-9.]*/ contained
syn match plugBracket /[[\]]/ contained
syn match plugX /x/ contained
syn match plugAbort /\~/ contained
syn match plugDash /^-\{1}\ /
syn match plugPlus /^+/
syn match plugStar /^*/
@ -811,6 +812,7 @@ function! s:syntax()
hi def link plug2 Repeat
hi def link plugH2 Type
hi def link plugX Exception
hi def link plugAbort Ignore
hi def link plugBracket Structure
hi def link plugNumber Number
@ -908,7 +910,7 @@ function! s:prepare(...)
endif
endfor
call s:job_abort()
call s:job_abort(0)
if s:switch_in()
if b:plug_preview == 1
pc
@ -944,6 +946,8 @@ function! s:close_pane()
if b:plug_preview == 1
pc
let b:plug_preview = -1
elseif exists('s:jobs') && !empty(s:jobs)
call s:job_abort(1)
else
bd
endif
@ -1326,7 +1330,12 @@ function! s:update_finish()
endif
endfunction
function! s:job_abort()
function! s:mark_aborted(name, message)
let attrs = { 'running': 0, 'error': 1, 'abort': 1, 'lines': [a:message] }
let s:jobs[a:name] = extend(get(s:jobs, a:name, {}), attrs)
endfunction
function! s:job_abort(cancel)
if (!s:nvim && !s:vim8) || !exists('s:jobs')
return
endif
@ -1340,8 +1349,18 @@ function! s:job_abort()
if j.new
call s:rm_rf(g:plugs[name].dir)
endif
if a:cancel
call s:mark_aborted(name, 'Aborted')
endif
endfor
let s:jobs = {}
if a:cancel
for todo in values(s:update.todo)
let todo.abort = 1
endfor
else
let s:jobs = {}
endif
endfunction
function! s:last_non_empty_line(lines)
@ -1355,6 +1374,16 @@ function! s:last_non_empty_line(lines)
return ''
endfunction
function! s:bullet_for(job, ...)
if a:job.running
return a:job.new ? '+' : '*'
endif
if get(a:job, 'abort', 0)
return '~'
endif
return a:job.error ? 'x' : get(a:000, 0, '-')
endfunction
function! s:job_out_cb(self, data) abort
let self = a:self
let data = remove(self.lines, -1) . a:data
@ -1363,10 +1392,9 @@ function! s:job_out_cb(self, data) abort
" To reduce the number of buffer updates
let self.tick = get(self, 'tick', -1) + 1
if !self.running || self.tick % len(s:jobs) == 0
let bullet = self.running ? (self.new ? '+' : '*') : (self.error ? 'x' : '-')
let result = self.error ? join(self.lines, "\n") : s:last_non_empty_line(self.lines)
if len(result)
call s:log(bullet, self.name, result)
call s:log(s:bullet_for(self), self.name, result)
endif
endif
endfunction
@ -1380,7 +1408,7 @@ endfunction
function! s:job_cb(fn, job, ch, data)
if !s:plug_window_exists() " plug window closed
return s:job_abort()
return s:job_abort(0)
endif
call call(a:fn, [a:job, a:data])
endfunction
@ -1452,17 +1480,16 @@ function! s:reap(name)
endif
let more = len(get(job, 'queue', []))
let bullet = job.error ? 'x' : more ? (job.new ? '+' : '*') : '-'
let result = job.error ? join(job.lines, "\n") : s:last_non_empty_line(job.lines)
if len(result)
call s:log(bullet, a:name, result)
call s:log(s:bullet_for(job), a:name, result)
endif
if !job.error && more
let job.spec.queue = job.queue
let s:update.todo[a:name] = job.spec
else
let s:update.bar .= job.error ? 'x' : '='
let s:update.bar .= s:bullet_for(job, '=')
call s:bar()
endif
endfunction
@ -1541,6 +1568,12 @@ while 1 " Without TCO, Vim stack is bound to explode
let name = keys(s:update.todo)[0]
let spec = remove(s:update.todo, name)
if get(spec, 'abort', 0)
call s:mark_aborted(name, 'Skipped')
call s:reap(name)
continue
endif
let queue = get(spec, 'queue', [])
let new = empty(globpath(spec.dir, '.git', 1))