Skip to content

Commit

Permalink
Allow pressing 'q' to abort the running tasks, then 'R' to retry (#1289)
Browse files Browse the repository at this point in the history
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
  • Loading branch information
junegunn authored Jul 9, 2024
1 parent d863d07 commit d80f495
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 11 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`
Expand Down
53 changes: 43 additions & 10 deletions plug.vim
Original file line number Diff line number Diff line change
Expand Up @@ -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 /^*/
Expand All @@ -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

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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)
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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))

Expand Down

0 comments on commit d80f495

Please sign in to comment.