From d80f495fabff8446972b8695ba251ca636a047b0 Mon Sep 17 00:00:00 2001 From: Junegunn Choi Date: Tue, 9 Jul 2024 20:09:41 +0900 Subject: [PATCH] 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 --- README.md | 2 +- plug.vim | 53 +++++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 44 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index cf9f9f8e..093173f0 100644 --- a/README.md +++ b/README.md @@ -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` diff --git a/plug.vim b/plug.vim index 6296f8bc..5c910cab 100644 --- a/plug.vim +++ b/plug.vim @@ -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))