Browse Source

Update `v`, `z` and vim-plug

Weiyi Lou 9 years ago
parent
commit
22d295a053
4 changed files with 108 additions and 29 deletions
  1. 12 2
      bin/v
  2. 5 1
      docs/man/man1/v.1
  3. 5 3
      shell/common/z.sh
  4. 86 23
      vim/autoload/plug.vim

+ 12 - 2
bin/v

@@ -3,13 +3,16 @@
 [ "$vim" ] || vim=vim
 [ $viminfo ] || viminfo=~/.viminfo
 
-usage="$(basename $0) [-a] [-l] [-[0-9]] [--debug] [--help] [regexes]"
+usage="$(basename $0) [-a] [-c] [-l] [-[0-9]] [--debug] [--help] [regexes]"
 
 [ $1 ] || list=1
 
+_pwd="$(command pwd)"
+
 fnd=()
 for x; do case $x in
     -a) deleted=1;;
+    -c) subdir=1; shift;;
     -l) list=1;;
     -[0-9]) edit=${x:1}; shift;;
     --help) echo $usage; exit;;
@@ -27,11 +30,18 @@ set -- "${fnd[@]}"
 while IFS=" " read line; do
     [ "${line:0:1}" = ">" ] || continue
     fl=${line:2}
-    [ -f "${fl/\~/$HOME/}" -o "$deleted" ] || continue
+    _fl="${fl/~\//$HOME/}"
+    [ -f "$_fl" -o "$deleted" ] || continue
     match=1
     for x; do
         [[ "$fl" =~ $x ]] || match=
     done
+    [ "$subdir" ] && {
+        case "$_fl" in
+          $_pwd*);;
+          *) match=;;
+        esac
+    }
     [ "$match" ] || continue
     i=$((i+1))
     files[$i]="$fl"

+ 5 - 1
docs/man/man1/v.1

@@ -4,7 +4,7 @@
 v \- z for vim
 
 .SH SYNOPSIS
-v [\-a] [\-l] [\-[0\-9]] [\-\-debug] [\-\-help] [regex1 regex2 ... regexn]
+v [\-a] [\-c] [\-l] [\-[0\-9]] [\-\-debug] [\-\-help] [regex1 regex2 ... regexn]
 
 .SH AVAILABILITY
 bash, vim
@@ -25,6 +25,8 @@ provided regular expressions.
 .SH OPTIONS
 \fB\-a\fR           don't skip deleted files
 .br
+\fB\-c\fR           restrict matches to subdirectories of the current dir
+.br
 \fB\-l\fR           when multiple matches, show a list
 .br
 \fB\-[0\-9]\fR       edit nth most recent file
@@ -40,6 +42,8 @@ provided regular expressions.
 .br
 \fBv foo bar\fR    edit first file matching foo and bar
 .br
+\fBv -c foo bar\fR choose files in current dir matching foo and bar
+.br
 \fBv -l foo bar\fR list and choose files matching foo and bar
 
 .SH NOTES

+ 5 - 3
shell/common/z.sh

@@ -57,7 +57,7 @@ _z() {
 
         # maintain the data file
         local tempfile="$datafile.$RANDOM"
-        awk < <( _z_dirs ) -v path="$*" -v now="$(date +%s)" -F"|" '
+        awk < <(_z_dirs 2>/dev/null) -v path="$*" -v now="$(date +%s)" -F"|" '
             BEGIN {
                 rank[path] = 1
                 time[path] = now
@@ -125,7 +125,7 @@ _z() {
         # if we hit enter on a completion just go there
         case "$last" in
             # completions will always start with /
-            /*) [ -z "$list" -a -d "$last" ] && cd "$last" && return;;
+            /*) [ -z "$list" -a -d "$last" ] && builtin cd "$last" && return;;
         esac
 
         # no file yet
@@ -202,7 +202,9 @@ _z() {
             }
         ')"
 
-        [ $? -eq 0 ] && [ "$cd" ] && ${echo:-cd} "$cd"
+        [ $? -eq 0 ] && [ "$cd" ] && {
+          if [ "$echo" ]; then echo "$cd"; else builtin cd "$cd"; fi
+        }
     fi
 }
 

+ 86 - 23
vim/autoload/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)
 endfunction
 
-function! s:ask(message)
+function! s:ask(message, ...)
   call inputsave()
   echohl WarningMsg
-  let proceed = input(a:message.' (y/N) ') =~? '^y'
+  let answer = input(a:message.(a:0 ? ' (y/N/a) ' : ' (y/N) '))
   echohl None
   call inputrestore()
   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
 
 function! plug#end()
@@ -196,6 +204,9 @@ function! plug#end()
 
   filetype off
   for name in g:plugs_order
+    if !has_key(g:plugs, name)
+      continue
+    endif
     let plug = g:plugs[name]
     if get(s:loaded, name, 0) || !has_key(plug, 'on') && !has_key(plug, 'for')
       let s:loaded[name] = 1
@@ -264,7 +275,7 @@ function! plug#end()
       syntax enable
     end
   else
-    call s:reload()
+    call s:reload_plugins()
   endif
 endfunction
 
@@ -272,9 +283,13 @@ function! s:loaded_names()
   return filter(copy(g:plugs_order), 'get(s:loaded, v:val, 0)')
 endfunction
 
-function! s:reload()
+function! s:load_plugin(spec)
+  call s:source(s:rtp(a:spec), 'plugin/**/*.vim', 'after/plugin/**/*.vim')
+endfunction
+
+function! s:reload_plugins()
   for name in s:loaded_names()
-    call s:source(s:rtp(g:plugs[name]), 'plugin/**/*.vim', 'after/plugin/**/*.vim')
+    call s:load_plugin(g:plugs[name])
   endfor
 endfunction
 
@@ -602,6 +617,7 @@ function! s:syntax()
   syn match plugRelDate /([^)]*)$/ contained
   syn match plugNotLoaded /(not loaded)$/
   syn match plugError /^x.*/
+  syn region plugDeleted start=/^\~ .*/ end=/^\ze\S/
   syn match plugH2 /^.*:\n-\+$/
   syn keyword Function PlugInstall PlugStatus PlugUpdate PlugClean
   hi def link plug1       Title
@@ -621,6 +637,7 @@ function! s:syntax()
   hi def link plugUpdate  Type
 
   hi def link plugError   Error
+  hi def link plugDeleted Ignore
   hi def link plugRelDate Comment
   hi def link plugEdge    PreProc
   hi def link plugSha     Identifier
@@ -698,6 +715,12 @@ function! s:prepare(...)
     throw 'Invalid current working directory. Cannot proceed.'
   endif
 
+  for evar in ['$GIT_DIR', '$GIT_WORK_TREE']
+    if exists(evar)
+      throw evar.' detected. Cannot proceed.'
+    endif
+  endfor
+
   call s:job_abort()
   if s:switch_in()
     normal q
@@ -713,10 +736,9 @@ function! s:prepare(...)
   let s:plug_buf = winbufnr(0)
   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
   setf vim-plug
   if exists('g:syntax_on')
@@ -782,7 +804,12 @@ function! s:do(pull, force, todo)
       let error = ''
       let type = type(spec.do)
       if type == s:TYPE.string
-        let error = s:bang(spec.do)
+        if spec.do[0] == ':'
+          call s:load_plugin(spec)
+          execute spec.do[1:]
+        else
+          let error = s:bang(spec.do)
+        endif
       elseif type == s:TYPE.funcref
         try
           let status = installed ? 'installed' : (updated ? 'updated' : 'unchanged')
@@ -1971,16 +1998,48 @@ function! s:clean(force)
   if empty(todo)
     call append(line('$'), 'Already clean.')
   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
-      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
   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
 
 function! s:upgrade()
@@ -2122,11 +2181,15 @@ function! s:preview_commit()
     return
   endif
 
-  execute 'pedit' sha
-  wincmd P
-  setlocal filetype=git buftype=nofile nobuflisted modifiable
-  execute 'silent read !cd' s:shellesc(g:plugs[name].dir) '&& git show --no-color --pretty=medium' sha
-  normal! gg"_dd
+  if exists('g:plug_pwindow') && !s:is_preview_window_open()
+    execute g:plug_pwindow
+    execute 'e' sha
+  else
+    execute 'pedit' sha
+    wincmd P
+  endif
+  setlocal previewwindow filetype=git buftype=nofile nobuflisted modifiable
+  execute 'silent %!cd' s:shellesc(g:plugs[name].dir) '&& git show --no-color --pretty=medium' sha
   setlocal nomodifiable
   nnoremap <silent> <buffer> q :q<cr>
   wincmd p
@@ -2212,7 +2275,7 @@ function! s:revert()
   setlocal modifiable
   normal! "_dap
   setlocal nomodifiable
-  echo 'Reverted.'
+  echo 'Reverted'
 endfunction
 
 function! s:snapshot(force, ...) abort