plug.vim 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710
  1. " vim-plug: Vim plugin manager
  2. " ============================
  3. "
  4. " Download plug.vim and put it in ~/.vim/autoload
  5. "
  6. " mkdir -p ~/.vim/autoload
  7. " curl -fLo ~/.vim/autoload/plug.vim \
  8. " https://raw.github.com/junegunn/vim-plug/master/plug.vim
  9. "
  10. " Edit your .vimrc
  11. "
  12. " call plug#begin()
  13. "
  14. " Plug 'junegunn/seoul256.vim'
  15. " Plug 'junegunn/vim-easy-align'
  16. " Plug 'junegunn/goyo.vim', { 'on': 'Goyo' }
  17. " " Plug 'user/repo1', 'branch_or_tag'
  18. " " Plug 'user/repo2', { 'rtp': 'vim/plugin/dir', 'branch': 'branch_or_tag' }
  19. " " ...
  20. "
  21. " call plug#end()
  22. "
  23. " Then :PlugInstall to install plugins. (default: ~/.vim/plugged)
  24. " You can change the location of the plugins with plug#begin(path) call.
  25. "
  26. "
  27. " Copyright (c) 2013 Junegunn Choi
  28. "
  29. " MIT License
  30. "
  31. " Permission is hereby granted, free of charge, to any person obtaining
  32. " a copy of this software and associated documentation files (the
  33. " "Software"), to deal in the Software without restriction, including
  34. " without limitation the rights to use, copy, modify, merge, publish,
  35. " distribute, sublicense, and/or sell copies of the Software, and to
  36. " permit persons to whom the Software is furnished to do so, subject to
  37. " the following conditions:
  38. "
  39. " The above copyright notice and this permission notice shall be
  40. " included in all copies or substantial portions of the Software.
  41. "
  42. " THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  43. " EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  44. " MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  45. " NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  46. " LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  47. " OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  48. " WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  49. if exists('g:loaded_plug')
  50. finish
  51. endif
  52. let g:loaded_plug = 1
  53. let s:cpo_save = &cpo
  54. set cpo&vim
  55. let s:plug_source = 'https://raw.github.com/junegunn/vim-plug/master/plug.vim'
  56. let s:plug_file = 'Plugfile'
  57. let s:plug_win = 0
  58. let s:is_win = has('win32') || has('win64')
  59. let s:me = expand('<sfile>:p')
  60. function! plug#begin(...)
  61. if a:0 > 0
  62. let home = s:path(fnamemodify(a:1, ':p'))
  63. elseif exists('g:plug_home')
  64. let home = s:path(g:plug_home)
  65. elseif !empty(&rtp)
  66. let home = s:path(split(&rtp, ',')[0]) . '/plugged'
  67. else
  68. echoerr "Unable to determine plug home. Try calling plug#begin() with a path argument."
  69. return
  70. endif
  71. if !isdirectory(home)
  72. try
  73. call mkdir(home, 'p')
  74. catch
  75. echoerr 'Invalid plug directory: '. home
  76. return 0
  77. endtry
  78. endif
  79. if !executable('git')
  80. echoerr "`git' executable not found. vim-plug requires git."
  81. return 0
  82. endif
  83. let g:plug_home = home
  84. let g:plugs = {}
  85. command! -nargs=+ Plug call s:add(1, <args>)
  86. command! -nargs=* PlugInstall call s:install(<f-args>)
  87. command! -nargs=* PlugUpdate call s:update(<f-args>)
  88. command! -nargs=0 -bang PlugClean call s:clean('<bang>' == '!')
  89. command! -nargs=0 PlugUpgrade if s:upgrade() | execute "source ". s:me | endif
  90. command! -nargs=0 PlugStatus call s:status()
  91. return 1
  92. endfunction
  93. function! plug#end()
  94. if !exists('g:plugs')
  95. echoerr 'Call plug#begin() first'
  96. return
  97. endif
  98. let keys = keys(g:plugs)
  99. while !empty(keys)
  100. let keys = keys(s:extend(keys))
  101. endwhile
  102. filetype off
  103. for plug in values(g:plugs)
  104. if has_key(plug, 'on')
  105. let commands = type(plug.on) == 1 ? [plug.on] : plug.on
  106. for cmd in commands
  107. if !exists(':'.cmd)
  108. execute printf(
  109. \ "command! -nargs=* -bang %s call s:lod(%s, '<bang>', <q-args>, %s)",
  110. \ cmd, string(cmd), string(plug))
  111. endif
  112. endfor
  113. else
  114. call s:add_rtp(s:rtp(plug))
  115. endif
  116. endfor
  117. filetype plugin indent on
  118. syntax on
  119. endfunction
  120. function! s:rtp(spec)
  121. let rtp = s:dirpath(a:spec.dir . get(a:spec, 'rtp', ''))
  122. if s:is_win
  123. let rtp = substitute(rtp, '\\*$', '', '')
  124. endif
  125. return rtp
  126. endfunction
  127. function! s:add_rtp(rtp)
  128. execute "set rtp^=".a:rtp
  129. if isdirectory(a:rtp.'after')
  130. execute "set rtp+=".a:rtp.'after'
  131. endif
  132. endfunction
  133. function! s:lod(cmd, bang, args, plug)
  134. execute 'delc '.a:cmd
  135. let rtp = s:rtp(a:plug)
  136. call s:add_rtp(rtp)
  137. for dir in ['plugin', 'after']
  138. for vim in split(globpath(rtp, dir.'/*.vim'), '\n')
  139. execute 'source '.vim
  140. endfor
  141. endfor
  142. execute printf("%s%s %s", a:cmd, a:bang, a:args)
  143. endfunction
  144. function! s:add(...)
  145. let force = a:1
  146. let opts = { 'branch': 'master' }
  147. if a:0 == 2
  148. let plugin = a:2
  149. elseif a:0 == 3
  150. let plugin = a:2
  151. if type(a:3) == 1
  152. let opts.branch = a:3
  153. elseif type(a:3) == 4
  154. call extend(opts, a:3)
  155. else
  156. echoerr "Invalid argument type (expected: string or dictionary)"
  157. return
  158. endif
  159. else
  160. echoerr "Invalid number of arguments (1..2)"
  161. return
  162. endif
  163. if plugin =~ ':'
  164. let uri = plugin
  165. else
  166. if plugin !~ '/'
  167. let plugin = 'vim-scripts/'. plugin
  168. endif
  169. let uri = 'https://git:@github.com/' . plugin . '.git'
  170. endif
  171. let name = substitute(split(plugin, '/')[-1], '\.git$', '', '')
  172. if !force && has_key(g:plugs, name) | return | endif
  173. let dir = s:dirpath( fnamemodify(join([g:plug_home, name], '/'), ':p') )
  174. let spec = extend(opts, { 'dir': dir, 'uri': uri })
  175. let g:plugs[name] = spec
  176. endfunction
  177. function! s:install(...)
  178. call s:update_impl(0, a:000)
  179. endfunction
  180. function! s:update(...)
  181. call s:update_impl(1, a:000)
  182. endfunction
  183. function! s:apply()
  184. for spec in values(g:plugs)
  185. let docd = join([spec.dir, 'doc'], '/')
  186. if isdirectory(docd)
  187. execute "helptags ". join([spec.dir, 'doc'], '/')
  188. endif
  189. endfor
  190. runtime! plugin/*.vim
  191. runtime! after/*.vim
  192. silent! source $MYVIMRC
  193. endfunction
  194. function! s:syntax()
  195. syntax clear
  196. syntax region plug1 start=/\%1l/ end=/\%2l/ contains=ALL
  197. syntax region plug2 start=/\%2l/ end=/\%3l/ contains=ALL
  198. syn match plugNumber /[0-9]\+[0-9.]*/ containedin=plug1 contained
  199. syn match plugBracket /[[\]]/ containedin=plug2 contained
  200. syn match plugX /x/ containedin=plug2 contained
  201. syn match plugDash /^-/
  202. syn match plugName /\(^- \)\@<=[^:]*/
  203. syn match plugError /^x.*/
  204. syn keyword Function PlugInstall PlugStatus PlugUpdate PlugClean
  205. hi def link plug1 Title
  206. hi def link plug2 Repeat
  207. hi def link plugX Exception
  208. hi def link plugBracket Structure
  209. hi def link plugNumber Number
  210. hi def link plugDash Special
  211. hi def link plugName Label
  212. hi def link plugError Error
  213. endfunction
  214. function! s:lpad(str, len)
  215. return a:str . repeat(' ', a:len - len(a:str))
  216. endfunction
  217. function! s:lastline(msg)
  218. let lines = split(a:msg, '\n')
  219. return get(lines, -1, '')
  220. endfunction
  221. function! s:prepare()
  222. execute s:plug_win . 'wincmd w'
  223. if exists('b:plug')
  224. %d
  225. else
  226. vertical topleft new
  227. noremap <silent> <buffer> q :q<cr>
  228. let b:plug = 1
  229. let s:plug_win = winnr()
  230. call s:assign_name()
  231. endif
  232. setlocal buftype=nofile bufhidden=wipe nobuflisted noswapfile nowrap cursorline
  233. setf vim-plug
  234. call s:syntax()
  235. endfunction
  236. function! s:assign_name()
  237. " Assign buffer name
  238. let prefix = '[Plugins]'
  239. let name = prefix
  240. let idx = 2
  241. while bufexists(name)
  242. let name = printf("%s (%s)", prefix, idx)
  243. let idx = idx + 1
  244. endwhile
  245. silent! execute "f ".fnameescape(name)
  246. endfunction
  247. function! s:finish()
  248. call append(3, '- Finishing ... ')
  249. redraw
  250. call s:apply()
  251. call s:syntax()
  252. call setline(4, getline(4) . 'Done!')
  253. normal! gg
  254. endfunction
  255. function! s:update_impl(pull, args)
  256. let threads = len(a:args) > 0 ? a:args[0] : get(g:, 'plug_threads', 16)
  257. call s:prepare()
  258. call append(0, a:pull ? 'Updating plugins' : 'Installing plugins')
  259. call append(1, '['. s:lpad('', len(g:plugs)) .']')
  260. normal! 2G
  261. redraw
  262. if has('ruby') && threads > 1
  263. call s:update_parallel(a:pull, threads)
  264. else
  265. call s:update_serial(a:pull)
  266. endif
  267. call s:finish()
  268. endfunction
  269. function! s:extend(names)
  270. let prev = copy(g:plugs)
  271. try
  272. command! -nargs=+ Plug call s:add(0, <args>)
  273. for name in a:names
  274. let plugfile = s:rtp(g:plugs[name]) . s:plug_file
  275. if filereadable(plugfile)
  276. execute "source ". plugfile
  277. endif
  278. endfor
  279. finally
  280. command! -nargs=+ Plug call s:add(1, <args>)
  281. endtry
  282. return filter(copy(g:plugs), '!has_key(prev, v:key)')
  283. endfunction
  284. function! s:update_progress(pull, cnt, bar, total)
  285. call setline(1, (a:pull ? 'Updating' : 'Installing').
  286. \ " plugins (".a:cnt."/".a:total.")")
  287. call s:progress_bar(2, a:bar, a:total)
  288. normal! 2G
  289. redraw
  290. endfunction
  291. function! s:update_serial(pull)
  292. let st = reltime()
  293. let base = g:plug_home
  294. let todo = copy(g:plugs)
  295. let total = len(todo)
  296. let done = {}
  297. let bar = ''
  298. while !empty(todo)
  299. for [name, spec] in items(todo)
  300. let done[name] = 1
  301. if isdirectory(spec.dir)
  302. execute 'cd '.spec.dir
  303. let [valid, msg] = s:git_valid(spec, 0, 0)
  304. if valid
  305. let result = a:pull ?
  306. \ system(
  307. \ printf('git checkout -q %s 2>&1 && git pull origin %s 2>&1',
  308. \ spec.branch, spec.branch)) : 'Already installed'
  309. let error = a:pull ? v:shell_error != 0 : 0
  310. else
  311. let result = msg
  312. let error = 1
  313. endif
  314. else
  315. if !isdirectory(base)
  316. call mkdir(base, 'p')
  317. endif
  318. execute 'cd '.base
  319. let d = shellescape(substitute(spec.dir, '[\/]\+$', '', ''))
  320. let result = system(
  321. \ printf('git clone --recursive %s -b %s %s 2>&1',
  322. \ shellescape(spec.uri), shellescape(spec.branch), d))
  323. let error = v:shell_error != 0
  324. endif
  325. cd -
  326. let bar .= error ? 'x' : '='
  327. call append(3, s:format_message(!error, name, result))
  328. call s:update_progress(a:pull, len(done), bar, total)
  329. endfor
  330. if !empty(s:extend(keys(todo)))
  331. let todo = filter(copy(g:plugs), '!has_key(done, v:key)')
  332. let total += len(todo)
  333. call s:update_progress(a:pull, len(done), bar, total)
  334. else
  335. break
  336. endif
  337. endwhile
  338. call setline(1, "Updated. Elapsed time: " . split(reltimestr(reltime(st)))[0] . ' sec.')
  339. endfunction
  340. function! s:update_parallel(pull, threads)
  341. ruby << EOF
  342. st = Time.now
  343. require 'thread'
  344. require 'fileutils'
  345. require 'timeout'
  346. running = true
  347. iswin = VIM::evaluate('s:is_win').to_i == 1
  348. pull = VIM::evaluate('a:pull').to_i == 1
  349. base = VIM::evaluate('g:plug_home')
  350. all = VIM::evaluate('copy(g:plugs)')
  351. limit = VIM::evaluate('get(g:, "plug_timeout", 60)')
  352. nthr = VIM::evaluate('a:threads').to_i
  353. cd = iswin ? 'cd /d' : 'cd'
  354. done = {}
  355. tot = 0
  356. bar = ''
  357. skip = 'Already installed'
  358. mtx = Mutex.new
  359. take1 = proc { mtx.synchronize { running && all.shift } }
  360. logh = proc {
  361. cnt = done.length
  362. tot = VIM::evaluate('len(g:plugs)') || tot
  363. $curbuf[1] = "#{pull ? 'Updating' : 'Installing'} plugins (#{cnt}/#{tot})"
  364. $curbuf[2] = '[' + bar.ljust(tot) + ']'
  365. VIM::command('normal! 2G')
  366. VIM::command('redraw') unless iswin
  367. }
  368. log = proc { |name, result, ok|
  369. mtx.synchronize do
  370. bar += ok ? '=' : 'x'
  371. done[name] = true
  372. result =
  373. if ok
  374. ["- #{name}: #{result.lines.to_a.last.strip}"]
  375. elsif result =~ /^Interrupted|^Timeout/
  376. ["x #{name}: #{result}"]
  377. else
  378. ["x #{name}"] + result.lines.map { |l| " " << l }
  379. end
  380. result.each_with_index do |line, offset|
  381. $curbuf.append 3 + offset, line.chomp
  382. end
  383. logh.call
  384. end
  385. }
  386. bt = proc { |cmd|
  387. begin
  388. fd = nil
  389. Timeout::timeout(limit) do
  390. if iswin
  391. tmp = VIM::evaluate('tempname()')
  392. system("#{cmd} > #{tmp}")
  393. data = File.read(tmp).chomp
  394. File.unlink tmp rescue nil
  395. else
  396. fd = IO.popen(cmd)
  397. data = fd.read.chomp
  398. fd.close
  399. end
  400. [$? == 0, data]
  401. end
  402. rescue Timeout::Error, Interrupt => e
  403. if fd && !fd.closed?
  404. pids = [fd.pid]
  405. unless `which pgrep`.empty?
  406. children = pids
  407. until children.empty?
  408. children = children.map { |pid|
  409. `pgrep -P #{pid}`.lines.map(&:chomp)
  410. }.flatten
  411. pids += children
  412. end
  413. end
  414. pids.each { |pid| Process.kill 'TERM', pid.to_i rescue nil }
  415. fd.close
  416. end
  417. [false, e.is_a?(Interrupt) ? "Interrupted!" : "Timeout!"]
  418. end
  419. }
  420. main = Thread.current
  421. threads = []
  422. watcher = Thread.new {
  423. while VIM::evaluate('getchar(1)')
  424. sleep 0.1
  425. end
  426. mtx.synchronize do
  427. running = false
  428. threads.each { |t| t.raise Interrupt }
  429. end
  430. threads.each { |t| t.join rescue nil }
  431. main.kill
  432. }
  433. until all.empty?
  434. names = all.keys
  435. [names.length, nthr].min.times do
  436. mtx.synchronize do
  437. threads << Thread.new {
  438. while pair = take1.call
  439. name = pair.first
  440. dir, uri, branch = pair.last.values_at *%w[dir uri branch]
  441. ok, result =
  442. if File.directory? dir
  443. ret, data = bt.call "#{cd} #{dir} && git rev-parse --abbrev-ref HEAD 2>&1 && git config remote.origin.url"
  444. current_uri = data.lines.to_a.last
  445. if !ret
  446. if data =~ /^Interrupted|^Timeout/
  447. [false, data]
  448. else
  449. [false, [data.chomp, "PlugClean required."].join($/)]
  450. end
  451. elsif current_uri.sub(/git:@/, '') != uri.sub(/git:@/, '')
  452. [false, ["Invalid URI: #{current_uri}",
  453. "Expected: #{uri}",
  454. "PlugClean required."].join($/)]
  455. else
  456. if pull
  457. bt.call "#{cd} #{dir} && git checkout -q #{branch} 2>&1 && git pull origin #{branch} 2>&1"
  458. else
  459. [true, skip]
  460. end
  461. end
  462. else
  463. FileUtils.mkdir_p(base)
  464. d = dir.sub(%r{[\\/]+$}, '')
  465. bt.call "#{cd} #{base} && git clone --recursive #{uri} -b #{branch} #{d} 2>&1"
  466. end
  467. log.call name, result, ok
  468. end
  469. } if running
  470. end
  471. end
  472. threads.each(&:join)
  473. mtx.synchronize { threads.clear }
  474. all.merge!(VIM::evaluate("s:extend(#{names.inspect})") || {})
  475. logh.call
  476. end
  477. watcher.kill
  478. $curbuf[1] = "Updated. Elapsed time: #{"%.6f" % (Time.now - st)} sec."
  479. EOF
  480. endfunction
  481. function! s:path(path)
  482. return substitute(s:is_win ? substitute(a:path, '/', '\', 'g') : a:path,
  483. \ '[/\\]*$', '', '')
  484. endfunction
  485. function! s:dirpath(path)
  486. let path = s:path(a:path)
  487. if s:is_win
  488. return path !~ '\\$' ? path.'\' : path
  489. else
  490. return path !~ '/$' ? path.'/' : path
  491. endif
  492. endfunction
  493. function! s:glob_dir(path)
  494. return map(filter(split(globpath(a:path, '**'), '\n'), 'isdirectory(v:val)'), 's:dirpath(v:val)')
  495. endfunction
  496. function! s:progress_bar(line, bar, total)
  497. call setline(a:line, '[' . s:lpad(a:bar, a:total) . ']')
  498. endfunction
  499. function! s:compare_git_uri(a, b)
  500. let a = substitute(a:a, 'git:@', '', '')
  501. let b = substitute(a:b, 'git:@', '', '')
  502. return a ==# b
  503. endfunction
  504. function! s:format_message(ok, name, message)
  505. if a:ok
  506. return [printf('- %s: %s', a:name, s:lastline(a:message))]
  507. else
  508. let lines = map(split(a:message, '\n'), '" ".v:val')
  509. return extend([printf('x %s:', a:name)], lines)
  510. endif
  511. endfunction
  512. function! s:git_valid(spec, check_branch, cd)
  513. let ret = 1
  514. let msg = 'OK'
  515. if isdirectory(a:spec.dir)
  516. if a:cd | execute "cd " . a:spec.dir | endif
  517. let result = split(system("git rev-parse --abbrev-ref HEAD 2>&1 && git config remote.origin.url"), '\n')
  518. let remote = result[-1]
  519. if v:shell_error != 0
  520. let msg = join([remote, "PlugClean required."], "\n")
  521. let ret = 0
  522. elseif !s:compare_git_uri(remote, a:spec.uri)
  523. let msg = join(['Invalid URI: '.remote,
  524. \ 'Expected: '.a:spec.uri,
  525. \ "PlugClean required."], "\n")
  526. let ret = 0
  527. elseif a:check_branch
  528. let branch = result[0]
  529. if a:spec.branch != branch
  530. let msg = 'Invalid branch: '.branch.'. Try PlugUpdate.'
  531. let ret = 0
  532. endif
  533. endif
  534. if a:cd | cd - | endif
  535. else
  536. let msg = 'Not found'
  537. let ret = 0
  538. endif
  539. return [ret, msg]
  540. endfunction
  541. function! s:clean(force)
  542. call s:prepare()
  543. call append(0, 'Searching for unused plugins in '.g:plug_home)
  544. call append(1, '')
  545. " List of valid directories
  546. let dirs = []
  547. let [cnt, total] = [0, len(g:plugs)]
  548. for spec in values(g:plugs)
  549. if s:git_valid(spec, 0, 1)[0]
  550. call add(dirs, spec.dir)
  551. endif
  552. let cnt += 1
  553. call s:progress_bar(2, repeat('=', cnt), total)
  554. redraw
  555. endfor
  556. let allowed = {}
  557. for dir in dirs
  558. let allowed[dir] = 1
  559. for child in s:glob_dir(dir)
  560. let allowed[child] = 1
  561. endfor
  562. endfor
  563. let todo = []
  564. let found = sort(s:glob_dir(g:plug_home))
  565. while !empty(found)
  566. let f = remove(found, 0)
  567. if !has_key(allowed, f) && isdirectory(f)
  568. call add(todo, f)
  569. call append(line('$'), '- ' . f)
  570. let found = filter(found, 'stridx(v:val, f) != 0')
  571. end
  572. endwhile
  573. normal! G
  574. redraw
  575. if empty(todo)
  576. call append(line('$'), 'Already clean.')
  577. else
  578. call inputsave()
  579. let yes = a:force || (input("Proceed? (Y/N) ") =~? '^y')
  580. call inputrestore()
  581. if yes
  582. for dir in todo
  583. if isdirectory(dir)
  584. call system((s:is_win ? 'rmdir /S /Q ' : 'rm -rf ') . dir)
  585. endif
  586. endfor
  587. call append(line('$'), 'Removed.')
  588. else
  589. call append(line('$'), 'Cancelled.')
  590. endif
  591. endif
  592. normal! G
  593. endfunction
  594. function! s:upgrade()
  595. if executable('curl')
  596. let mee = shellescape(s:me)
  597. let new = shellescape(s:me . '.new')
  598. echo "Downloading ". s:plug_source
  599. redraw
  600. let mv = s:is_win ? 'move /Y' : 'mv -f'
  601. let cp = s:is_win ? 'copy /Y' : 'cp -f'
  602. call system(printf(
  603. \ "curl -fLo %s %s && ".cp." %s %s.old && ".mv." %s %s",
  604. \ new, s:plug_source, mee, mee, new, mee))
  605. if v:shell_error == 0
  606. unlet g:loaded_plug
  607. echo "Downloaded ". s:plug_source
  608. return 1
  609. else
  610. echoerr "Error upgrading vim-plug"
  611. return 0
  612. endif
  613. elseif has('ruby')
  614. echo "Downloading ". s:plug_source
  615. ruby << EOF
  616. require 'open-uri'
  617. require 'fileutils'
  618. me = VIM::evaluate('s:me')
  619. old = me + '.old'
  620. new = me + '.new'
  621. File.open(new, 'w') do |f|
  622. f << open(VIM::evaluate('s:plug_source')).read
  623. end
  624. FileUtils.cp me, old
  625. File.rename new, me
  626. EOF
  627. unlet g:loaded_plug
  628. echo "Downloaded ". s:plug_source
  629. return 1
  630. else
  631. echoerr "curl executable or ruby support not found"
  632. return 0
  633. endif
  634. endfunction
  635. function! s:status()
  636. call s:prepare()
  637. call append(0, 'Checking plugins')
  638. let ecnt = 0
  639. for [name, spec] in items(g:plugs)
  640. if isdirectory(spec.dir)
  641. execute 'cd '.spec.dir
  642. let [valid, msg] = s:git_valid(spec, 1, 0)
  643. cd -
  644. else
  645. let [valid, msg] = [0, 'Not found. Try PlugInstall.']
  646. endif
  647. let ecnt += !valid
  648. call append(2, s:format_message(valid, name, msg))
  649. call cursor(3, 1)
  650. redraw
  651. endfor
  652. call setline(1, 'Finished. '.ecnt.' error(s).')
  653. normal! gg
  654. endfunction
  655. let &cpo = s:cpo_save
  656. unlet s:cpo_save