Просмотр исходного кода

Define d operator for selectively removing invalid directories

Fix #503
Junegunn Choi 9 лет назад
Родитель
Сommit
c9a7ca1e9e
2 измененных файлов с 60 добавлено и 19 удалено
  1. 54 13
      plug.vim
  2. 6 6
      test/workflow.vader

+ 54 - 13
plug.vim

@@ -171,14 +171,22 @@ function! s:assoc(dict, key, val)
   let a:dict[a:key] = add(get(a:dict, a:key, []), a:val)
   let a:dict[a:key] = add(get(a:dict, a:key, []), a:val)
 endfunction
 endfunction
 
 
-function! s:ask(message)
+function! s:ask(message, ...)
   call inputsave()
   call inputsave()
   echohl WarningMsg
   echohl WarningMsg
-  let proceed = input(a:message.' (y/N) ') =~? '^y'
+  let answer = input(a:message.(a:0 ? ' (y/N/a) ' : ' (y/N) '))
   echohl None
   echohl None
   call inputrestore()
   call inputrestore()
   echo "\r"
   echo "\r"
-  return proceed
+  return (a:0 && answer =~? '^a') ? 2 : (answer =~? '^y') ? 1 : 0
+endfunction
+
+function! s:ask_no_interrupt(...)
+  try
+    return call('s:ask', a:000)
+  catch
+    return 0
+  endtry
 endfunction
 endfunction
 
 
 function! plug#end()
 function! plug#end()
@@ -609,6 +617,7 @@ function! s:syntax()
   syn match plugRelDate /([^)]*)$/ contained
   syn match plugRelDate /([^)]*)$/ contained
   syn match plugNotLoaded /(not loaded)$/
   syn match plugNotLoaded /(not loaded)$/
   syn match plugError /^x.*/
   syn match plugError /^x.*/
+  syn region plugDeleted start=/^\~ .*/ end=/^\ze\S/
   syn match plugH2 /^.*:\n-\+$/
   syn match plugH2 /^.*:\n-\+$/
   syn keyword Function PlugInstall PlugStatus PlugUpdate PlugClean
   syn keyword Function PlugInstall PlugStatus PlugUpdate PlugClean
   hi def link plug1       Title
   hi def link plug1       Title
@@ -628,6 +637,7 @@ function! s:syntax()
   hi def link plugUpdate  Type
   hi def link plugUpdate  Type
 
 
   hi def link plugError   Error
   hi def link plugError   Error
+  hi def link plugDeleted Ignore
   hi def link plugRelDate Comment
   hi def link plugRelDate Comment
   hi def link plugEdge    PreProc
   hi def link plugEdge    PreProc
   hi def link plugSha     Identifier
   hi def link plugSha     Identifier
@@ -726,10 +736,9 @@ function! s:prepare(...)
   let s:plug_buf = winbufnr(0)
   let s:plug_buf = winbufnr(0)
   call s:assign_name()
   call s:assign_name()
 
 
-  silent! unmap <buffer> <cr>
-  silent! unmap <buffer> L
-  silent! unmap <buffer> o
-  silent! unmap <buffer> X
+  for k in ['<cr>', 'L', 'o', 'X', 'd', 'dd']
+    execute 'silent! unmap <buffer>' k
+  endfor
   setlocal buftype=nofile bufhidden=wipe nobuflisted noswapfile nowrap cursorline modifiable
   setlocal buftype=nofile bufhidden=wipe nobuflisted noswapfile nowrap cursorline modifiable
   setf vim-plug
   setf vim-plug
   if exists('g:syntax_on')
   if exists('g:syntax_on')
@@ -1989,16 +1998,48 @@ function! s:clean(force)
   if empty(todo)
   if empty(todo)
     call append(line('$'), 'Already clean.')
     call append(line('$'), 'Already clean.')
   else
   else
-    if a:force || s:ask('Proceed?')
-      for dir in todo
-        call s:rm_rf(dir)
-      endfor
-      call append(3, ['Removed.', ''])
+    let s:clean_count = 0
+    call append(3, ['Directories to delete:', ''])
+    redraw!
+    if a:force || s:ask_no_interrupt('Delete all directories?')
+      call s:delete([6, line('$')], 1)
     else
     else
-      call append(3, ['Cancelled.', ''])
+      call setline(4, 'Cancelled.')
+      nnoremap <silent> <buffer> d :set opfunc=<sid>delete_op<cr>g@
+      nmap     <silent> <buffer> dd d_
+      xnoremap <silent> <buffer> d :<c-u>call <sid>delete_op(visualmode(), 1)<cr>
+      echo 'Delete the lines (d{motion}) to delete the corresponding directories'
     endif
     endif
   endif
   endif
   4
   4
+  setlocal nomodifiable
+endfunction
+
+function! s:delete_op(type, ...)
+  call s:delete(a:0 ? [line("'<"), line("'>")] : [line("'["), line("']")], 0)
+endfunction
+
+function! s:delete(range, force)
+  let [l1, l2] = a:range
+  let force = a:force
+  while l1 <= l2
+    let line = getline(l1)
+    if line =~ '^- ' && isdirectory(line[2:])
+      execute l1
+      redraw!
+      let answer = force ? 1 : s:ask('Delete '.line[2:].'?', 1)
+      let force = force || answer > 1
+      if answer
+        call s:rm_rf(line[2:])
+        setlocal modifiable
+        call setline(l1, '~'.line[1:])
+        let s:clean_count += 1
+        call setline(4, printf('Removed %d directories.', s:clean_count))
+        setlocal nomodifiable
+      endif
+    endif
+    let l1 += 1
+  endwhile
 endfunction
 endfunction
 
 
 function! s:upgrade()
 function! s:upgrade()

+ 6 - 6
test/workflow.vader

@@ -240,8 +240,8 @@ Expect:
 Execute (PlugClean! to remove seoul256.vim):
 Execute (PlugClean! to remove seoul256.vim):
   PlugClean!
   PlugClean!
   " Three removed, emoji left
   " Three removed, emoji left
-  AssertEqual 'Removed.', getline(4)
-  AssertExpect '^- ', 3
+  AssertEqual 'Removed 3 directories.', getline(4)
+  AssertExpect '^\~ ', 3
   AssertExpect 'Diverged', 1
   AssertExpect 'Diverged', 1
   Assert empty(globpath(&rtp, 'colors/seoul256.vim'))
   Assert empty(globpath(&rtp, 'colors/seoul256.vim'))
   Assert !empty(globpath(&rtp, 'autoload/emoji.vim'))
   Assert !empty(globpath(&rtp, 'autoload/emoji.vim'))
@@ -268,8 +268,8 @@ Expect:
 
 
 Execute (PlugClean! to remove vim-emoji):
 Execute (PlugClean! to remove vim-emoji):
   PlugClean!
   PlugClean!
-  AssertExpect '^- ', 1
-  AssertEqual 'Removed.', getline(4)
+  AssertExpect '^\~ ', 1
+  AssertEqual 'Removed 1 directories.', getline(4)
   Assert empty(globpath(&rtp, 'colors/seoul256.vim'))
   Assert empty(globpath(&rtp, 'colors/seoul256.vim'))
   Assert empty(globpath(&rtp, 'autoload/emoji.vim'))
   Assert empty(globpath(&rtp, 'autoload/emoji.vim'))
   q
   q
@@ -1273,11 +1273,11 @@ Execute (PlugClean should not try to remove unmanaged plugins inside g:plug_home
 
 
   " Remove z1, z2
   " Remove z1, z2
   PlugClean!
   PlugClean!
-  AssertExpect '^- ', 2
+  AssertExpect '^\~ ', 2
   AssertExpect 'Already clean', 0
   AssertExpect 'Already clean', 0
 
 
   PlugClean!
   PlugClean!
-  AssertExpect '^- ', 0
+  AssertExpect '^\~ ', 0
   AssertExpect 'Already clean', 1
   AssertExpect 'Already clean', 1
   q
   q