Define d operator for selectively removing invalid directories

Fix #503
This commit is contained in:
Junegunn Choi 2016-07-23 10:02:35 +09:00
parent 5695fb8474
commit c9a7ca1e9e
No known key found for this signature in database
GPG Key ID: 254BC280FEF9C627
2 changed files with 60 additions and 19 deletions

View File

@ -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> for k in ['<cr>', 'L', 'o', 'X', 'd', 'dd']
silent! unmap <buffer> L execute 'silent! unmap <buffer>' k
silent! unmap <buffer> o endfor
silent! unmap <buffer> X
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?') let s:clean_count = 0
for dir in todo call append(3, ['Directories to delete:', ''])
call s:rm_rf(dir) redraw!
endfor if a:force || s:ask_no_interrupt('Delete all directories?')
call append(3, ['Removed.', '']) 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()

View File

@ -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) AssertEqual 'Removed 3 directories.', getline(4)
AssertExpect '^- ', 3 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 AssertExpect '^\~ ', 1
AssertEqual 'Removed.', getline(4) 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