.vim/autoload/plug.vim

changeset 795
b6105413b6b7
parent 781
eddff1b70d20
child 806
fb0c343bb872
equal deleted inserted replaced
794:152f0c95cbb0 795:b6105413b6b7
348 endfunction 348 endfunction
349 349
350 function! s:is_local_plug(repo) 350 function! s:is_local_plug(repo)
351 return a:repo =~? '^[a-z]:\|^[%~]' 351 return a:repo =~? '^[a-z]:\|^[%~]'
352 endfunction 352 endfunction
353
354 " Copied from fzf
355 function! s:wrap_cmds(cmds)
356 return map(['@echo off','setlocal enabledelayedexpansion','for /f "delims=: tokens=2" %%a in (''chcp'') do set origchcp=%%a','set origchcp=!origchcp: =!','chcp 65001 > nul'] +
357 \ (type(a:cmds) == type([]) ? a:cmds : [a:cmds]) +
358 \ ['chcp !origchcp! > nul','setlocal disabledelayedexpansion'],'v:val."\r"')
359 endfunction
360
361 function! s:batchfile(cmd)
362 let batchfile = tempname().'.bat'
363 call writefile(s:wrap_cmds(a:cmd), batchfile)
364 let cmd = plug#shellescape(batchfile, {'shell': &shell, 'script': 1})
365 if &shell =~# 'powershell\.exe$'
366 let cmd = '& ' . cmd
367 endif
368 return [batchfile, cmd]
369 endfunction
353 else 370 else
354 function! s:rtp(spec) 371 function! s:rtp(spec)
355 return s:dirpath(a:spec.dir . get(a:spec, 'rtp', '')) 372 return s:dirpath(a:spec.dir . get(a:spec, 'rtp', ''))
356 endfunction 373 endfunction
357 374
805 let [sh, shellcmdflag, shrd] = s:chsh(a:0) 822 let [sh, shellcmdflag, shrd] = s:chsh(a:0)
806 " FIXME: Escaping is incomplete. We could use shellescape with eval, 823 " FIXME: Escaping is incomplete. We could use shellescape with eval,
807 " but it won't work on Windows. 824 " but it won't work on Windows.
808 let cmd = a:0 ? s:with_cd(a:cmd, a:1) : a:cmd 825 let cmd = a:0 ? s:with_cd(a:cmd, a:1) : a:cmd
809 if s:is_win 826 if s:is_win
810 let batchfile = tempname().'.bat' 827 let [batchfile, cmd] = s:batchfile(cmd)
811 call writefile(["@echo off\r", cmd . "\r"], batchfile)
812 let cmd = s:shellesc(expand(batchfile))
813 endif 828 endif
814 let g:_plug_bang = (s:is_win && has('gui_running') ? 'silent ' : '').'!'.escape(cmd, '#!%') 829 let g:_plug_bang = (s:is_win && has('gui_running') ? 'silent ' : '').'!'.escape(cmd, '#!%')
815 execute "normal! :execute g:_plug_bang\<cr>\<cr>" 830 execute "normal! :execute g:_plug_bang\<cr>\<cr>"
816 finally 831 finally
817 unlet g:_plug_bang 832 unlet g:_plug_bang
1090 call s:log4(name, 'Checking out '.spec.commit) 1105 call s:log4(name, 'Checking out '.spec.commit)
1091 let out = s:checkout(spec) 1106 let out = s:checkout(spec)
1092 elseif has_key(spec, 'tag') 1107 elseif has_key(spec, 'tag')
1093 let tag = spec.tag 1108 let tag = spec.tag
1094 if tag =~ '\*' 1109 if tag =~ '\*'
1095 let tags = s:lines(s:system('git tag --list '.s:shellesc(tag).' --sort -version:refname 2>&1', spec.dir)) 1110 let tags = s:lines(s:system('git tag --list '.plug#shellescape(tag).' --sort -version:refname 2>&1', spec.dir))
1096 if !v:shell_error && !empty(tags) 1111 if !v:shell_error && !empty(tags)
1097 let tag = tags[0] 1112 let tag = tags[0]
1098 call s:log4(name, printf('Latest tag for %s -> %s', spec.tag, tag)) 1113 call s:log4(name, printf('Latest tag for %s -> %s', spec.tag, tag))
1099 call append(3, '') 1114 call append(3, '')
1100 endif 1115 endif
1147 silent! call jobstop(j.jobid) 1162 silent! call jobstop(j.jobid)
1148 elseif s:vim8 1163 elseif s:vim8
1149 silent! call job_stop(j.jobid) 1164 silent! call job_stop(j.jobid)
1150 endif 1165 endif
1151 if j.new 1166 if j.new
1152 call s:system('rm -rf ' . s:shellesc(g:plugs[name].dir)) 1167 call s:system('rm -rf ' . plug#shellescape(g:plugs[name].dir))
1153 endif 1168 endif
1154 endfor 1169 endfor
1155 let s:jobs = {} 1170 let s:jobs = {}
1156 endfunction 1171 endfunction
1157 1172
1200 \ s:job_cb('s:job_exit_cb', self, 0, a:data) 1215 \ s:job_cb('s:job_exit_cb', self, 0, a:data)
1201 endfunction 1216 endfunction
1202 1217
1203 function! s:spawn(name, cmd, opts) 1218 function! s:spawn(name, cmd, opts)
1204 let job = { 'name': a:name, 'running': 1, 'error': 0, 'lines': [''], 1219 let job = { 'name': a:name, 'running': 1, 'error': 0, 'lines': [''],
1205 \ 'batchfile': (s:is_win && (s:nvim || s:vim8)) ? tempname().'.bat' : '',
1206 \ 'new': get(a:opts, 'new', 0) } 1220 \ 'new': get(a:opts, 'new', 0) }
1207 let s:jobs[a:name] = job 1221 let s:jobs[a:name] = job
1208 let cmd = has_key(a:opts, 'dir') ? s:with_cd(a:cmd, a:opts.dir) : a:cmd 1222 let cmd = has_key(a:opts, 'dir') ? s:with_cd(a:cmd, a:opts.dir, 0) : a:cmd
1209 if !empty(job.batchfile) 1223 let argv = s:is_win ? ['cmd', '/s', '/c', '"'.cmd.'"'] : ['sh', '-c', cmd]
1210 call writefile(["@echo off\r", cmd . "\r"], job.batchfile)
1211 let cmd = s:shellesc(expand(job.batchfile))
1212 endif
1213 let argv = add(s:is_win ? ['cmd', '/c'] : ['sh', '-c'], cmd)
1214 1224
1215 if s:nvim 1225 if s:nvim
1216 call extend(job, { 1226 call extend(job, {
1217 \ 'on_stdout': function('s:nvim_cb'), 1227 \ 'on_stdout': function('s:nvim_cb'),
1218 \ 'on_exit': function('s:nvim_cb'), 1228 \ 'on_exit': function('s:nvim_cb'),
1258 let bullet = job.error ? 'x' : '-' 1268 let bullet = job.error ? 'x' : '-'
1259 let result = job.error ? join(job.lines, "\n") : s:last_non_empty_line(job.lines) 1269 let result = job.error ? join(job.lines, "\n") : s:last_non_empty_line(job.lines)
1260 call s:log(bullet, a:name, empty(result) ? 'OK' : result) 1270 call s:log(bullet, a:name, empty(result) ? 'OK' : result)
1261 call s:bar() 1271 call s:bar()
1262 1272
1263 if has_key(job, 'batchfile') && !empty(job.batchfile)
1264 call delete(job.batchfile)
1265 endif
1266 call remove(s:jobs, a:name) 1273 call remove(s:jobs, a:name)
1267 endfunction 1274 endfunction
1268 1275
1269 function! s:bar() 1276 function! s:bar()
1270 if s:switch_in() 1277 if s:switch_in()
1350 else 1357 else
1351 call s:spawn(name, 1358 call s:spawn(name,
1352 \ printf('git clone %s %s %s %s 2>&1', 1359 \ printf('git clone %s %s %s %s 2>&1',
1353 \ has_tag ? '' : s:clone_opt, 1360 \ has_tag ? '' : s:clone_opt,
1354 \ prog, 1361 \ prog,
1355 \ s:shellesc(spec.uri), 1362 \ plug#shellescape(spec.uri, {'script': 0}),
1356 \ s:shellesc(s:trim(spec.dir))), { 'new': 1 }) 1363 \ plug#shellescape(s:trim(spec.dir), {'script': 0})), { 'new': 1 })
1357 endif 1364 endif
1358 1365
1359 if !s:jobs[name].running 1366 if !s:jobs[name].running
1360 call s:reap(name) 1367 call s:reap(name)
1361 endif 1368 endif
1978 refresh.kill if refresh 1985 refresh.kill if refresh
1979 watcher.kill 1986 watcher.kill
1980 EOF 1987 EOF
1981 endfunction 1988 endfunction
1982 1989
1983 function! s:shellesc_cmd(arg) 1990 function! s:shellesc_cmd(arg, script)
1984 let escaped = substitute(a:arg, '[&|<>()@^]', '^&', 'g') 1991 let escaped = substitute('"'.a:arg.'"', '[&|<>()@^!"]', '^&', 'g')
1985 let escaped = substitute(escaped, '%', '%%', 'g') 1992 return substitute(escaped, '%', (a:script ? '%' : '^') . '&', 'g')
1986 let escaped = substitute(escaped, '"', '\\^&', 'g') 1993 endfunction
1987 let escaped = substitute(escaped, '\(\\\+\)\(\\^\)', '\1\1\2', 'g') 1994
1988 return '^"'.substitute(escaped, '\(\\\+\)$', '\1\1', '').'^"' 1995 function! s:shellesc_ps1(arg)
1989 endfunction 1996 return "'".substitute(escape(a:arg, '\"'), "'", "''", 'g')."'"
1990 1997 endfunction
1991 function! s:shellesc(arg) 1998
1992 if &shell =~# 'cmd.exe$' 1999 function! plug#shellescape(arg, ...)
1993 return s:shellesc_cmd(a:arg) 2000 let opts = a:0 > 0 && type(a:1) == s:TYPE.dict ? a:1 : {}
2001 let shell = get(opts, 'shell', s:is_win ? 'cmd.exe' : 'sh')
2002 let script = get(opts, 'script', 1)
2003 if shell =~# 'cmd\.exe$'
2004 return s:shellesc_cmd(a:arg, script)
2005 elseif shell =~# 'powershell\.exe$' || shell =~# 'pwsh$'
2006 return s:shellesc_ps1(a:arg)
1994 endif 2007 endif
1995 return shellescape(a:arg) 2008 return shellescape(a:arg)
1996 endfunction 2009 endfunction
1997 2010
1998 function! s:glob_dir(path) 2011 function! s:glob_dir(path)
2022 let lines = map(s:lines(a:message), '" ".v:val') 2035 let lines = map(s:lines(a:message), '" ".v:val')
2023 return extend([printf('x %s:', a:name)], lines) 2036 return extend([printf('x %s:', a:name)], lines)
2024 endif 2037 endif
2025 endfunction 2038 endfunction
2026 2039
2027 function! s:with_cd(cmd, dir) 2040 function! s:with_cd(cmd, dir, ...)
2028 return printf('cd%s %s && %s', s:is_win ? ' /d' : '', s:shellesc(a:dir), a:cmd) 2041 let script = a:0 > 0 ? a:1 : 1
2042 return printf('cd%s %s && %s', s:is_win ? ' /d' : '', plug#shellescape(a:dir, {'script': script}), a:cmd)
2029 endfunction 2043 endfunction
2030 2044
2031 function! s:system(cmd, ...) 2045 function! s:system(cmd, ...)
2032 try 2046 try
2033 let [sh, shellcmdflag, shrd] = s:chsh(1) 2047 let [sh, shellcmdflag, shrd] = s:chsh(1)
2034 let cmd = a:0 > 0 ? s:with_cd(a:cmd, a:1) : a:cmd 2048 let cmd = a:0 > 0 ? s:with_cd(a:cmd, a:1) : a:cmd
2035 if s:is_win 2049 if s:is_win
2036 let batchfile = tempname().'.bat' 2050 let [batchfile, cmd] = s:batchfile(cmd)
2037 call writefile(["@echo off\r", cmd . "\r"], batchfile)
2038 let cmd = s:shellesc(expand(batchfile))
2039 endif 2051 endif
2040 return system(cmd) 2052 return system(cmd)
2041 finally 2053 finally
2042 let [&shell, &shellcmdflag, &shellredir] = [sh, shellcmdflag, shrd] 2054 let [&shell, &shellcmdflag, &shellredir] = [sh, shellcmdflag, shrd]
2043 if s:is_win 2055 if s:is_win
2111 return [err, err =~# 'PlugClean'] 2123 return [err, err =~# 'PlugClean']
2112 endfunction 2124 endfunction
2113 2125
2114 function! s:rm_rf(dir) 2126 function! s:rm_rf(dir)
2115 if isdirectory(a:dir) 2127 if isdirectory(a:dir)
2116 call s:system((s:is_win ? 'rmdir /S /Q ' : 'rm -rf ') . s:shellesc(a:dir)) 2128 call s:system((s:is_win ? 'rmdir /S /Q ' : 'rm -rf ') . plug#shellescape(a:dir))
2117 endif 2129 endif
2118 endfunction 2130 endfunction
2119 2131
2120 function! s:clean(force) 2132 function! s:clean(force)
2121 call s:prepare() 2133 call s:prepare()
2220 redraw 2232 redraw
2221 let tmp = tempname() 2233 let tmp = tempname()
2222 let new = tmp . '/plug.vim' 2234 let new = tmp . '/plug.vim'
2223 2235
2224 try 2236 try
2225 let out = s:system(printf('git clone --depth 1 %s %s', s:shellesc(s:plug_src), s:shellesc(tmp))) 2237 let out = s:system(printf('git clone --depth 1 %s %s', plug#shellescape(s:plug_src), plug#shellescape(tmp)))
2226 if v:shell_error 2238 if v:shell_error
2227 return s:err('Error upgrading vim-plug: '. out) 2239 return s:err('Error upgrading vim-plug: '. out)
2228 endif 2240 endif
2229 2241
2230 if readfile(s:me) ==# readfile(new) 2242 if readfile(s:me) ==# readfile(new)
2363 wincmd P 2375 wincmd P
2364 endif 2376 endif
2365 setlocal previewwindow filetype=git buftype=nofile nobuflisted modifiable 2377 setlocal previewwindow filetype=git buftype=nofile nobuflisted modifiable
2366 try 2378 try
2367 let [sh, shellcmdflag, shrd] = s:chsh(1) 2379 let [sh, shellcmdflag, shrd] = s:chsh(1)
2368 let cmd = 'cd '.s:shellesc(g:plugs[name].dir).' && git show --no-color --pretty=medium '.sha 2380 let cmd = 'cd '.plug#shellescape(g:plugs[name].dir).' && git show --no-color --pretty=medium '.sha
2369 if s:is_win 2381 if s:is_win
2370 let batchfile = tempname().'.bat' 2382 let [batchfile, cmd] = s:batchfile(cmd)
2371 call writefile(["@echo off\r", cmd . "\r"], batchfile)
2372 let cmd = expand(batchfile)
2373 endif 2383 endif
2374 execute 'silent %!' cmd 2384 execute 'silent %!' cmd
2375 finally 2385 finally
2376 let [&shell, &shellcmdflag, &shellredir] = [sh, shellcmdflag, shrd] 2386 let [&shell, &shellcmdflag, &shellredir] = [sh, shellcmdflag, shrd]
2377 if s:is_win 2387 if s:is_win
2416 continue 2426 continue
2417 endif 2427 endif
2418 call s:append_ul(2, origin ? 'Pending updates:' : 'Last update:') 2428 call s:append_ul(2, origin ? 'Pending updates:' : 'Last update:')
2419 for [k, v] in plugs 2429 for [k, v] in plugs
2420 let range = origin ? '..origin/'.v.branch : 'HEAD@{1}..' 2430 let range = origin ? '..origin/'.v.branch : 'HEAD@{1}..'
2421 let cmd = 'git log --graph --color=never '.join(map(['--pretty=format:%x01%h%x01%d%x01%s%x01%cr', range], 's:shellesc(v:val)')) 2431 let cmd = 'git log --graph --color=never '.join(map(['--pretty=format:%x01%h%x01%d%x01%s%x01%cr', range], 'plug#shellescape(v:val)'))
2422 if has_key(v, 'rtp') 2432 if has_key(v, 'rtp')
2423 let cmd .= ' -- '.s:shellesc(v.rtp) 2433 let cmd .= ' -- '.plug#shellescape(v.rtp)
2424 endif 2434 endif
2425 let diff = s:system_chomp(cmd, v.dir) 2435 let diff = s:system_chomp(cmd, v.dir)
2426 if !empty(diff) 2436 if !empty(diff)
2427 let ref = has_key(v, 'tag') ? (' (tag: '.v.tag.')') : has_key(v, 'commit') ? (' '.v.commit) : '' 2437 let ref = has_key(v, 'tag') ? (' (tag: '.v.tag.')') : has_key(v, 'commit') ? (' '.v.commit) : ''
2428 call append(5, extend(['', '- '.k.':'.ref], map(s:lines(diff), 's:format_git_log(v:val)'))) 2438 call append(5, extend(['', '- '.k.':'.ref], map(s:lines(diff), 's:format_git_log(v:val)')))

mercurial