浏览代码

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
Junegunn Choi 1 年之前
父节点
当前提交
d80f495fab
共有 2 个文件被更改,包括 44 次插入11 次删除
  1. 1 1
      README.md
  2. 43 10
      plug.vim

+ 1 - 1
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`

+ 43 - 10
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))