this repo has no description
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Use vim-plug instead of Pathogen

+2091 -463
+1 -2
.gitignore
··· 4 4 /nvim/spell 5 5 /nvim/.netrwhist 6 6 7 - /nvim/bundle/*/ 8 - !/nvim/bundle/.keep 7 + /nvim/plugged 9 8 10 9 /nvim/tags/*/ 11 10 !/nvim/tags/.keep
-69
install
··· 1 - #!/bin/bash 2 - 3 - TMP="$(pwd)/.tmp" 4 - 5 - if [ ! -d "$TMP" ]; then 6 - mkdir "$TMP" 7 - fi 8 - 9 - fetch() { 10 - config="$1" 11 - out="$2" 12 - 13 - typ=$($JQ -r ".type" <<< "$config") 14 - url=$($JQ -r ".url" <<< "$config") 15 - build=$($JQ -r ".build // \"\"" <<< "$config") 16 - echo -e "\t$out\t\t$typ" 17 - "${typ}-fetch" "$out" "$url" > /dev/null 18 - if [ -n "$build" ]; then 19 - if [ -d "$out" ]; then 20 - pushd "$out" 21 - sh -c "$build" 22 - popd 23 - else 24 - sh -c "$build" -- "$out" 25 - fi 26 - fi 27 - } 28 - 29 - curl-fetch() { 30 - curl -Lo "$1" "$2" 31 - } 32 - 33 - git-fetch() { 34 - out="$1" 35 - tmp_path="$TMP/git/$out" 36 - mkdir -p "$(dirname "$tmp_path")" 37 - if [ -d "$out" ]; then 38 - pushd "$out" 39 - git pull 40 - popd 41 - else 42 - git clone --separate-git-dir="$tmp_path" "$2" "$out" 43 - fi 44 - } 45 - 46 - JQ="$(which jq)" 47 - PACKAGES="$(cat packages.json)" 48 - 49 - if [ ! -x "$JQ" ]; then 50 - echo 'Install jq before running' 51 - echo 'http://stedolan.github.io/jq/' 52 - echo '' 53 - echo 'In future installer will fetch it for you, but for now it is only requirement' 54 - exit 1 55 - fi 56 - 57 - for path in $($JQ -r '. | keys[]' <<< "$PACKAGES") 58 - do 59 - current=$($JQ ".[\"$path\"]" <<< "$PACKAGES") 60 - for repo in $($JQ -r ". | keys[]" <<< "$current") 61 - do 62 - fetch "$($JQ ".[\"$repo\"]" <<< "$current")" "$path/$repo" & 63 - done 64 - done 65 - 66 - for job in $(jobs -p) 67 - do 68 - wait $job 69 - done
-347
nvim/autoload/pathogen.vim
··· 1 - " pathogen.vim - path option manipulation 2 - " Maintainer: Tim Pope <http://tpo.pe/> 3 - " Version: 2.3 4 - 5 - " Install in ~/.vim/autoload (or ~\vimfiles\autoload). 6 - " 7 - " For management of individually installed plugins in ~/.vim/bundle (or 8 - " ~\vimfiles\bundle), adding `execute pathogen#infect()` to the top of your 9 - " .vimrc is the only other setup necessary. 10 - " 11 - " The API is documented inline below. 12 - 13 - if exists("g:loaded_pathogen") || &cp 14 - finish 15 - endif 16 - let g:loaded_pathogen = 1 17 - 18 - " Point of entry for basic default usage. Give a relative path to invoke 19 - " pathogen#interpose() (defaults to "bundle/{}"), or an absolute path to invoke 20 - " pathogen#surround(). Curly braces are expanded with pathogen#expand(): 21 - " "bundle/{}" finds all subdirectories inside "bundle" inside all directories 22 - " in the runtime path. 23 - function! pathogen#infect(...) abort 24 - for path in a:0 ? filter(reverse(copy(a:000)), 'type(v:val) == type("")') : ['bundle/{}'] 25 - if path =~# '^\%({\=[$~\\/]\|{\=\w:[\\/]\).*[{}*]' 26 - call pathogen#surround(path) 27 - elseif path =~# '^\%([$~\\/]\|\w:[\\/]\)' 28 - call s:warn('Change pathogen#infect('.string(path).') to pathogen#infect('.string(path.'/{}').')') 29 - call pathogen#surround(path . '/{}') 30 - elseif path =~# '[{}*]' 31 - call pathogen#interpose(path) 32 - else 33 - call s:warn('Change pathogen#infect('.string(path).') to pathogen#infect('.string(path.'/{}').')') 34 - call pathogen#interpose(path . '/{}') 35 - endif 36 - endfor 37 - call pathogen#cycle_filetype() 38 - if pathogen#is_disabled($MYVIMRC) 39 - return 'finish' 40 - endif 41 - return '' 42 - endfunction 43 - 44 - " Split a path into a list. 45 - function! pathogen#split(path) abort 46 - if type(a:path) == type([]) | return a:path | endif 47 - if empty(a:path) | return [] | endif 48 - let split = split(a:path,'\\\@<!\%(\\\\\)*\zs,') 49 - return map(split,'substitute(v:val,''\\\([\\,]\)'',''\1'',"g")') 50 - endfunction 51 - 52 - " Convert a list to a path. 53 - function! pathogen#join(...) abort 54 - if type(a:1) == type(1) && a:1 55 - let i = 1 56 - let space = ' ' 57 - else 58 - let i = 0 59 - let space = '' 60 - endif 61 - let path = "" 62 - while i < a:0 63 - if type(a:000[i]) == type([]) 64 - let list = a:000[i] 65 - let j = 0 66 - while j < len(list) 67 - let escaped = substitute(list[j],'[,'.space.']\|\\[\,'.space.']\@=','\\&','g') 68 - let path .= ',' . escaped 69 - let j += 1 70 - endwhile 71 - else 72 - let path .= "," . a:000[i] 73 - endif 74 - let i += 1 75 - endwhile 76 - return substitute(path,'^,','','') 77 - endfunction 78 - 79 - " Convert a list to a path with escaped spaces for 'path', 'tag', etc. 80 - function! pathogen#legacyjoin(...) abort 81 - return call('pathogen#join',[1] + a:000) 82 - endfunction 83 - 84 - " Turn filetype detection off and back on again if it was already enabled. 85 - function! pathogen#cycle_filetype() abort 86 - if exists('g:did_load_filetypes') 87 - filetype off 88 - filetype on 89 - endif 90 - endfunction 91 - 92 - " Check if a bundle is disabled. A bundle is considered disabled if its 93 - " basename or full name is included in the list g:pathogen_disabled. 94 - function! pathogen#is_disabled(path) abort 95 - if a:path =~# '\~$' 96 - return 1 97 - endif 98 - let sep = pathogen#slash() 99 - let blacklist = map( 100 - \ get(g:, 'pathogen_blacklist', get(g:, 'pathogen_disabled', [])) + 101 - \ pathogen#split($VIMBLACKLIST), 102 - \ 'substitute(v:val, "[\\/]$", "", "")') 103 - return index(blacklist, fnamemodify(a:path, ':t')) != -1 || index(blacklist, a:path) != -1 104 - endfunction "}}}1 105 - 106 - " Prepend the given directory to the runtime path and append its corresponding 107 - " after directory. Curly braces are expanded with pathogen#expand(). 108 - function! pathogen#surround(path) abort 109 - let sep = pathogen#slash() 110 - let rtp = pathogen#split(&rtp) 111 - let path = fnamemodify(a:path, ':p:s?[\\/]\=$??') 112 - let before = filter(pathogen#expand(path), '!pathogen#is_disabled(v:val)') 113 - let after = filter(reverse(pathogen#expand(path.sep.'after')), '!pathogen#is_disabled(v:val[0:-7])') 114 - call filter(rtp, 'index(before + after, v:val) == -1') 115 - let &rtp = pathogen#join(before, rtp, after) 116 - return &rtp 117 - endfunction 118 - 119 - " For each directory in the runtime path, add a second entry with the given 120 - " argument appended. Curly braces are expanded with pathogen#expand(). 121 - function! pathogen#interpose(name) abort 122 - let sep = pathogen#slash() 123 - let name = a:name 124 - if has_key(s:done_bundles, name) 125 - return "" 126 - endif 127 - let s:done_bundles[name] = 1 128 - let list = [] 129 - for dir in pathogen#split(&rtp) 130 - if dir =~# '\<after$' 131 - let list += reverse(filter(pathogen#expand(dir[0:-6].name.sep.'after'), '!pathogen#is_disabled(v:val[0:-7])')) + [dir] 132 - else 133 - let list += [dir] + filter(pathogen#expand(dir.sep.name), '!pathogen#is_disabled(v:val)') 134 - endif 135 - endfor 136 - let &rtp = pathogen#join(pathogen#uniq(list)) 137 - return 1 138 - endfunction 139 - 140 - let s:done_bundles = {} 141 - 142 - " Invoke :helptags on all non-$VIM doc directories in runtimepath. 143 - function! pathogen#helptags() abort 144 - let sep = pathogen#slash() 145 - for glob in pathogen#split(&rtp) 146 - for dir in map(split(glob(glob), "\n"), 'v:val.sep."/doc/".sep') 147 - if (dir)[0 : strlen($VIMRUNTIME)] !=# $VIMRUNTIME.sep && filewritable(dir) == 2 && !empty(split(glob(dir.'*.txt'))) && (!filereadable(dir.'tags') || filewritable(dir.'tags')) 148 - silent! execute 'helptags' pathogen#fnameescape(dir) 149 - endif 150 - endfor 151 - endfor 152 - endfunction 153 - 154 - command! -bar Helptags :call pathogen#helptags() 155 - 156 - " Execute the given command. This is basically a backdoor for --remote-expr. 157 - function! pathogen#execute(...) abort 158 - for command in a:000 159 - execute command 160 - endfor 161 - return '' 162 - endfunction 163 - 164 - " Section: Unofficial 165 - 166 - function! pathogen#is_absolute(path) abort 167 - return a:path =~# (has('win32') ? '^\%([\\/]\|\w:\)[\\/]\|^[~$]' : '^[/~$]') 168 - endfunction 169 - 170 - " Given a string, returns all possible permutations of comma delimited braced 171 - " alternatives of that string. pathogen#expand('/{a,b}/{c,d}') yields 172 - " ['/a/c', '/a/d', '/b/c', '/b/d']. Empty braces are treated as a wildcard 173 - " and globbed. Actual globs are preserved. 174 - function! pathogen#expand(pattern) abort 175 - if a:pattern =~# '{[^{}]\+}' 176 - let [pre, pat, post] = split(substitute(a:pattern, '\(.\{-\}\){\([^{}]\+\)}\(.*\)', "\\1\001\\2\001\\3", ''), "\001", 1) 177 - let found = map(split(pat, ',', 1), 'pre.v:val.post') 178 - let results = [] 179 - for pattern in found 180 - call extend(results, pathogen#expand(pattern)) 181 - endfor 182 - return results 183 - elseif a:pattern =~# '{}' 184 - let pat = matchstr(a:pattern, '^.*{}[^*]*\%($\|[\\/]\)') 185 - let post = a:pattern[strlen(pat) : -1] 186 - return map(split(glob(substitute(pat, '{}', '*', 'g')), "\n"), 'v:val.post') 187 - else 188 - return [a:pattern] 189 - endif 190 - endfunction 191 - 192 - " \ on Windows unless shellslash is set, / everywhere else. 193 - function! pathogen#slash() abort 194 - return !exists("+shellslash") || &shellslash ? '/' : '\' 195 - endfunction 196 - 197 - function! pathogen#separator() abort 198 - return pathogen#slash() 199 - endfunction 200 - 201 - " Convenience wrapper around glob() which returns a list. 202 - function! pathogen#glob(pattern) abort 203 - let files = split(glob(a:pattern),"\n") 204 - return map(files,'substitute(v:val,"[".pathogen#slash()."/]$","","")') 205 - endfunction "}}}1 206 - 207 - " Like pathogen#glob(), only limit the results to directories. 208 - function! pathogen#glob_directories(pattern) abort 209 - return filter(pathogen#glob(a:pattern),'isdirectory(v:val)') 210 - endfunction "}}}1 211 - 212 - " Remove duplicates from a list. 213 - function! pathogen#uniq(list) abort 214 - let i = 0 215 - let seen = {} 216 - while i < len(a:list) 217 - if (a:list[i] ==# '' && exists('empty')) || has_key(seen,a:list[i]) 218 - call remove(a:list,i) 219 - elseif a:list[i] ==# '' 220 - let i += 1 221 - let empty = 1 222 - else 223 - let seen[a:list[i]] = 1 224 - let i += 1 225 - endif 226 - endwhile 227 - return a:list 228 - endfunction 229 - 230 - " Backport of fnameescape(). 231 - function! pathogen#fnameescape(string) abort 232 - if exists('*fnameescape') 233 - return fnameescape(a:string) 234 - elseif a:string ==# '-' 235 - return '\-' 236 - else 237 - return substitute(escape(a:string," \t\n*?[{`$\\%#'\"|!<"),'^[+>]','\\&','') 238 - endif 239 - endfunction 240 - 241 - " Like findfile(), but hardcoded to use the runtimepath. 242 - function! pathogen#runtime_findfile(file,count) abort "{{{1 243 - let rtp = pathogen#join(1,pathogen#split(&rtp)) 244 - let file = findfile(a:file,rtp,a:count) 245 - if file ==# '' 246 - return '' 247 - else 248 - return fnamemodify(file,':p') 249 - endif 250 - endfunction 251 - 252 - " Section: Deprecated 253 - 254 - function! s:warn(msg) abort 255 - echohl WarningMsg 256 - echomsg a:msg 257 - echohl NONE 258 - endfunction 259 - 260 - " Prepend all subdirectories of path to the rtp, and append all 'after' 261 - " directories in those subdirectories. Deprecated. 262 - function! pathogen#runtime_prepend_subdirectories(path) abort 263 - call s:warn('Change pathogen#runtime_prepend_subdirectories('.string(a:path).') to pathogen#infect('.string(a:path.'/{}').')') 264 - return pathogen#surround(a:path . pathogen#slash() . '{}') 265 - endfunction 266 - 267 - function! pathogen#incubate(...) abort 268 - let name = a:0 ? a:1 : 'bundle/{}' 269 - call s:warn('Change pathogen#incubate('.(a:0 ? string(a:1) : '').') to pathogen#infect('.string(name).')') 270 - return pathogen#interpose(name) 271 - endfunction 272 - 273 - " Deprecated alias for pathogen#interpose(). 274 - function! pathogen#runtime_append_all_bundles(...) abort 275 - if a:0 276 - call s:warn('Change pathogen#runtime_append_all_bundles('.string(a:1).') to pathogen#infect('.string(a:1.'/{}').')') 277 - else 278 - call s:warn('Change pathogen#runtime_append_all_bundles() to pathogen#infect()') 279 - endif 280 - return pathogen#interpose(a:0 ? a:1 . '/{}' : 'bundle/{}') 281 - endfunction 282 - 283 - if exists(':Vedit') 284 - finish 285 - endif 286 - 287 - let s:vopen_warning = 0 288 - 289 - function! s:find(count,cmd,file,lcd) 290 - let rtp = pathogen#join(1,pathogen#split(&runtimepath)) 291 - let file = pathogen#runtime_findfile(a:file,a:count) 292 - if file ==# '' 293 - return "echoerr 'E345: Can''t find file \"".a:file."\" in runtimepath'" 294 - endif 295 - if !s:vopen_warning 296 - let s:vopen_warning = 1 297 - let warning = '|echohl WarningMsg|echo "Install scriptease.vim to continue using :V'.a:cmd.'"|echohl NONE' 298 - else 299 - let warning = '' 300 - endif 301 - if a:lcd 302 - let path = file[0:-strlen(a:file)-2] 303 - execute 'lcd `=path`' 304 - return a:cmd.' '.pathogen#fnameescape(a:file) . warning 305 - else 306 - return a:cmd.' '.pathogen#fnameescape(file) . warning 307 - endif 308 - endfunction 309 - 310 - function! s:Findcomplete(A,L,P) 311 - let sep = pathogen#slash() 312 - let cheats = { 313 - \'a': 'autoload', 314 - \'d': 'doc', 315 - \'f': 'ftplugin', 316 - \'i': 'indent', 317 - \'p': 'plugin', 318 - \'s': 'syntax'} 319 - if a:A =~# '^\w[\\/]' && has_key(cheats,a:A[0]) 320 - let request = cheats[a:A[0]].a:A[1:-1] 321 - else 322 - let request = a:A 323 - endif 324 - let pattern = substitute(request,'/\|\'.sep,'*'.sep,'g').'*' 325 - let found = {} 326 - for path in pathogen#split(&runtimepath) 327 - let path = expand(path, ':p') 328 - let matches = split(glob(path.sep.pattern),"\n") 329 - call map(matches,'isdirectory(v:val) ? v:val.sep : v:val') 330 - call map(matches,'expand(v:val, ":p")[strlen(path)+1:-1]') 331 - for match in matches 332 - let found[match] = 1 333 - endfor 334 - endfor 335 - return sort(keys(found)) 336 - endfunction 337 - 338 - command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Ve :execute s:find(<count>,'edit<bang>',<q-args>,0) 339 - command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Vedit :execute s:find(<count>,'edit<bang>',<q-args>,0) 340 - command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Vopen :execute s:find(<count>,'edit<bang>',<q-args>,1) 341 - command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Vsplit :execute s:find(<count>,'split',<q-args>,<bang>1) 342 - command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Vvsplit :execute s:find(<count>,'vsplit',<q-args>,<bang>1) 343 - command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Vtabedit :execute s:find(<count>,'tabedit',<q-args>,<bang>1) 344 - command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Vpedit :execute s:find(<count>,'pedit',<q-args>,<bang>1) 345 - command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Vread :execute s:find(<count>,'read',<q-args>,<bang>1) 346 - 347 - " vim:set et sw=2 foldmethod=expr foldexpr=getline(v\:lnum)=~'^\"\ Section\:'?'>1'\:getline(v\:lnum)=~#'^fu'?'a1'\:getline(v\:lnum)=~#'^endf'?'s1'\:'=':
+2037
nvim/autoload/plug.vim
··· 1 + " vim-plug: Vim plugin manager 2 + " ============================ 3 + " 4 + " Download plug.vim and put it in ~/.vim/autoload 5 + " 6 + " curl -fLo ~/.vim/autoload/plug.vim --create-dirs \ 7 + " https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim 8 + " 9 + " Edit your .vimrc 10 + " 11 + " call plug#begin('~/.vim/plugged') 12 + " 13 + " " Make sure you use single quotes 14 + " Plug 'junegunn/seoul256.vim' 15 + " Plug 'junegunn/vim-easy-align' 16 + " 17 + " " Group dependencies, vim-snippets depends on ultisnips 18 + " Plug 'SirVer/ultisnips' | Plug 'honza/vim-snippets' 19 + " 20 + " " On-demand loading 21 + " Plug 'scrooloose/nerdtree', { 'on': 'NERDTreeToggle' } 22 + " Plug 'tpope/vim-fireplace', { 'for': 'clojure' } 23 + " 24 + " " Using git URL 25 + " Plug 'https://github.com/junegunn/vim-github-dashboard.git' 26 + " 27 + " " Plugin options 28 + " Plug 'nsf/gocode', { 'tag': 'v.20150303', 'rtp': 'vim' } 29 + " 30 + " " Plugin outside ~/.vim/plugged with post-update hook 31 + " Plug 'junegunn/fzf', { 'dir': '~/.fzf', 'do': 'yes \| ./install' } 32 + " 33 + " " Unmanaged plugin (manually installed and updated) 34 + " Plug '~/my-prototype-plugin' 35 + " 36 + " " Add plugins to &runtimepath 37 + " call plug#end() 38 + " 39 + " Then reload .vimrc and :PlugInstall to install plugins. 40 + " Visit https://github.com/junegunn/vim-plug for more information. 41 + " 42 + " 43 + " Copyright (c) 2015 Junegunn Choi 44 + " 45 + " MIT License 46 + " 47 + " Permission is hereby granted, free of charge, to any person obtaining 48 + " a copy of this software and associated documentation files (the 49 + " "Software"), to deal in the Software without restriction, including 50 + " without limitation the rights to use, copy, modify, merge, publish, 51 + " distribute, sublicense, and/or sell copies of the Software, and to 52 + " permit persons to whom the Software is furnished to do so, subject to 53 + " the following conditions: 54 + " 55 + " The above copyright notice and this permission notice shall be 56 + " included in all copies or substantial portions of the Software. 57 + " 58 + " THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 59 + " EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 60 + " MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 61 + " NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 62 + " LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 63 + " OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 64 + " WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 65 + 66 + if exists('g:loaded_plug') 67 + finish 68 + endif 69 + let g:loaded_plug = 1 70 + 71 + let s:cpo_save = &cpo 72 + set cpo&vim 73 + 74 + let s:plug_src = 'https://github.com/junegunn/vim-plug.git' 75 + let s:plug_tab = get(s:, 'plug_tab', -1) 76 + let s:plug_buf = get(s:, 'plug_buf', -1) 77 + let s:mac_gui = has('gui_macvim') && has('gui_running') 78 + let s:is_win = has('win32') || has('win64') 79 + let s:nvim = has('nvim') && exists('*jobwait') && !s:is_win 80 + let s:me = resolve(expand('<sfile>:p')) 81 + let s:base_spec = { 'branch': 'master', 'frozen': 0 } 82 + let s:TYPE = { 83 + \ 'string': type(''), 84 + \ 'list': type([]), 85 + \ 'dict': type({}), 86 + \ 'funcref': type(function('call')) 87 + \ } 88 + let s:loaded = get(s:, 'loaded', {}) 89 + let s:triggers = get(s:, 'triggers', {}) 90 + 91 + function! plug#begin(...) 92 + if a:0 > 0 93 + let s:plug_home_org = a:1 94 + let home = s:path(fnamemodify(expand(a:1), ':p')) 95 + elseif exists('g:plug_home') 96 + let home = s:path(g:plug_home) 97 + elseif !empty(&rtp) 98 + let home = s:path(split(&rtp, ',')[0]) . '/plugged' 99 + else 100 + return s:err('Unable to determine plug home. Try calling plug#begin() with a path argument.') 101 + endif 102 + 103 + let g:plug_home = home 104 + let g:plugs = {} 105 + let g:plugs_order = [] 106 + let s:triggers = {} 107 + 108 + call s:define_commands() 109 + return 1 110 + endfunction 111 + 112 + function! s:define_commands() 113 + command! -nargs=+ -bar Plug call s:add(<args>) 114 + if !executable('git') 115 + return s:err('`git` executable not found. vim-plug requires git.') 116 + endif 117 + command! -nargs=* -bar -bang -complete=customlist,s:names PlugInstall call s:install('<bang>' == '!', [<f-args>]) 118 + command! -nargs=* -bar -bang -complete=customlist,s:names PlugUpdate call s:update('<bang>' == '!', [<f-args>]) 119 + command! -nargs=0 -bar -bang PlugClean call s:clean('<bang>' == '!') 120 + command! -nargs=0 -bar PlugUpgrade if s:upgrade() | execute 'source' s:esc(s:me) | endif 121 + command! -nargs=0 -bar PlugStatus call s:status() 122 + command! -nargs=0 -bar PlugDiff call s:diff() 123 + command! -nargs=? -bar PlugSnapshot call s:snapshot(<f-args>) 124 + endfunction 125 + 126 + function! s:to_a(v) 127 + return type(a:v) == s:TYPE.list ? a:v : [a:v] 128 + endfunction 129 + 130 + function! s:to_s(v) 131 + return type(a:v) == s:TYPE.string ? a:v : join(a:v, "\n") . "\n" 132 + endfunction 133 + 134 + function! s:source(from, ...) 135 + for pattern in a:000 136 + for vim in s:lines(globpath(a:from, pattern)) 137 + execute 'source' s:esc(vim) 138 + endfor 139 + endfor 140 + endfunction 141 + 142 + function! s:assoc(dict, key, val) 143 + let a:dict[a:key] = add(get(a:dict, a:key, []), a:val) 144 + endfunction 145 + 146 + function! plug#end() 147 + if !exists('g:plugs') 148 + return s:err('Call plug#begin() first') 149 + endif 150 + 151 + if exists('#PlugLOD') 152 + augroup PlugLOD 153 + autocmd! 154 + augroup END 155 + augroup! PlugLOD 156 + endif 157 + let lod = { 'ft': {}, 'map': {}, 'cmd': {} } 158 + 159 + filetype off 160 + for name in g:plugs_order 161 + let plug = g:plugs[name] 162 + if get(s:loaded, name, 0) || !has_key(plug, 'on') && !has_key(plug, 'for') 163 + let s:loaded[name] = 1 164 + continue 165 + endif 166 + 167 + if has_key(plug, 'on') 168 + let s:triggers[name] = { 'map': [], 'cmd': [] } 169 + for cmd in s:to_a(plug.on) 170 + if cmd =~? '^<Plug>.\+' 171 + if empty(mapcheck(cmd)) && empty(mapcheck(cmd, 'i')) 172 + call s:assoc(lod.map, cmd, name) 173 + endif 174 + call add(s:triggers[name].map, cmd) 175 + elseif cmd =~ '^[A-Z]' 176 + if exists(':'.cmd) != 2 177 + call s:assoc(lod.cmd, cmd, name) 178 + endif 179 + call add(s:triggers[name].cmd, cmd) 180 + endif 181 + endfor 182 + endif 183 + 184 + if has_key(plug, 'for') 185 + let types = s:to_a(plug.for) 186 + if !empty(types) 187 + call s:source(s:rtp(plug), 'ftdetect/**/*.vim', 'after/ftdetect/**/*.vim') 188 + endif 189 + for type in types 190 + call s:assoc(lod.ft, type, name) 191 + endfor 192 + endif 193 + endfor 194 + 195 + for [cmd, names] in items(lod.cmd) 196 + execute printf( 197 + \ 'command! -nargs=* -range -bang %s call s:lod_cmd(%s, "<bang>", <line1>, <line2>, <q-args>, %s)', 198 + \ cmd, string(cmd), string(names)) 199 + endfor 200 + 201 + for [map, names] in items(lod.map) 202 + for [mode, map_prefix, key_prefix] in 203 + \ [['i', '<C-O>', ''], ['n', '', ''], ['v', '', 'gv'], ['o', '', '']] 204 + execute printf( 205 + \ '%snoremap <silent> %s %s:<C-U>call <SID>lod_map(%s, %s, "%s")<CR>', 206 + \ mode, map, map_prefix, string(map), string(names), key_prefix) 207 + endfor 208 + endfor 209 + 210 + for [ft, names] in items(lod.ft) 211 + augroup PlugLOD 212 + execute printf('autocmd FileType %s call <SID>lod_ft(%s, %s)', 213 + \ ft, string(ft), string(names)) 214 + augroup END 215 + endfor 216 + 217 + call s:reorg_rtp() 218 + filetype plugin indent on 219 + if has('vim_starting') 220 + syntax enable 221 + else 222 + call s:reload() 223 + endif 224 + endfunction 225 + 226 + function! s:loaded_names() 227 + return filter(copy(g:plugs_order), 'get(s:loaded, v:val, 0)') 228 + endfunction 229 + 230 + function! s:reload() 231 + for name in s:loaded_names() 232 + call s:source(s:rtp(g:plugs[name]), 'plugin/**/*.vim', 'after/plugin/**/*.vim') 233 + endfor 234 + endfunction 235 + 236 + function! s:trim(str) 237 + return substitute(a:str, '[\/]\+$', '', '') 238 + endfunction 239 + 240 + function! s:version_requirement(val, min) 241 + for idx in range(0, len(a:min) - 1) 242 + let v = get(a:val, idx, 0) 243 + if v < a:min[idx] | return 0 244 + elseif v > a:min[idx] | return 1 245 + endif 246 + endfor 247 + return 1 248 + endfunction 249 + 250 + function! s:git_version_requirement(...) 251 + let s:git_version = get(s:, 'git_version', 252 + \ map(split(split(s:system('git --version'))[-1], '\.'), 'str2nr(v:val)')) 253 + return s:version_requirement(s:git_version, a:000) 254 + endfunction 255 + 256 + function! s:progress_opt(base) 257 + return a:base && !s:is_win && 258 + \ s:git_version_requirement(1, 7, 1) ? '--progress' : '' 259 + endfunction 260 + 261 + if s:is_win 262 + function! s:rtp(spec) 263 + return s:path(a:spec.dir . get(a:spec, 'rtp', '')) 264 + endfunction 265 + 266 + function! s:path(path) 267 + return s:trim(substitute(a:path, '/', '\', 'g')) 268 + endfunction 269 + 270 + function! s:dirpath(path) 271 + return s:path(a:path) . '\' 272 + endfunction 273 + 274 + function! s:is_local_plug(repo) 275 + return a:repo =~? '^[a-z]:\|^[%~]' 276 + endfunction 277 + else 278 + function! s:rtp(spec) 279 + return s:dirpath(a:spec.dir . get(a:spec, 'rtp', '')) 280 + endfunction 281 + 282 + function! s:path(path) 283 + return s:trim(a:path) 284 + endfunction 285 + 286 + function! s:dirpath(path) 287 + return substitute(a:path, '[/\\]*$', '/', '') 288 + endfunction 289 + 290 + function! s:is_local_plug(repo) 291 + return a:repo[0] =~ '[/$~]' 292 + endfunction 293 + endif 294 + 295 + function! s:err(msg) 296 + echohl ErrorMsg 297 + echom a:msg 298 + echohl None 299 + return 0 300 + endfunction 301 + 302 + function! s:esc(path) 303 + return escape(a:path, ' ') 304 + endfunction 305 + 306 + function! s:escrtp(path) 307 + return escape(a:path, ' ,') 308 + endfunction 309 + 310 + function! s:remove_rtp() 311 + for name in s:loaded_names() 312 + let rtp = s:rtp(g:plugs[name]) 313 + execute 'set rtp-='.s:escrtp(rtp) 314 + let after = globpath(rtp, 'after') 315 + if isdirectory(after) 316 + execute 'set rtp-='.s:escrtp(after) 317 + endif 318 + endfor 319 + endfunction 320 + 321 + function! s:reorg_rtp() 322 + if !empty(s:first_rtp) 323 + execute 'set rtp-='.s:first_rtp 324 + execute 'set rtp-='.s:last_rtp 325 + endif 326 + 327 + " &rtp is modified from outside 328 + if exists('s:prtp') && s:prtp !=# &rtp 329 + call s:remove_rtp() 330 + unlet! s:middle 331 + endif 332 + 333 + let s:middle = get(s:, 'middle', &rtp) 334 + let rtps = map(s:loaded_names(), 's:rtp(g:plugs[v:val])') 335 + let afters = filter(map(copy(rtps), 'globpath(v:val, "after")'), 'isdirectory(v:val)') 336 + let rtp = join(map(rtps, 'escape(v:val, ",")'), ',') 337 + \ . ','.s:middle.',' 338 + \ . join(map(afters, 'escape(v:val, ",")'), ',') 339 + let &rtp = substitute(substitute(rtp, ',,*', ',', 'g'), '^,\|,$', '', 'g') 340 + let s:prtp = &rtp 341 + 342 + if !empty(s:first_rtp) 343 + execute 'set rtp^='.s:first_rtp 344 + execute 'set rtp+='.s:last_rtp 345 + endif 346 + endfunction 347 + 348 + function! plug#load(...) 349 + if a:0 == 0 350 + return s:err('Argument missing: plugin name(s) required') 351 + endif 352 + if !exists('g:plugs') 353 + return s:err('plug#begin was not called') 354 + endif 355 + let unknowns = filter(copy(a:000), '!has_key(g:plugs, v:val)') 356 + if !empty(unknowns) 357 + let s = len(unknowns) > 1 ? 's' : '' 358 + return s:err(printf('Unknown plugin%s: %s', s, join(unknowns, ', '))) 359 + end 360 + for name in a:000 361 + call s:lod([name], ['ftdetect', 'after/ftdetect', 'plugin', 'after/plugin']) 362 + endfor 363 + if exists('#BufRead') 364 + doautocmd BufRead 365 + endif 366 + return 1 367 + endfunction 368 + 369 + function! s:remove_triggers(name) 370 + if !has_key(s:triggers, a:name) 371 + return 372 + endif 373 + for cmd in s:triggers[a:name].cmd 374 + execute 'silent! delc' cmd 375 + endfor 376 + for map in s:triggers[a:name].map 377 + execute 'silent! unmap' map 378 + execute 'silent! iunmap' map 379 + endfor 380 + call remove(s:triggers, a:name) 381 + endfunction 382 + 383 + function! s:lod(names, types) 384 + for name in a:names 385 + call s:remove_triggers(name) 386 + let s:loaded[name] = 1 387 + endfor 388 + call s:reorg_rtp() 389 + 390 + for name in a:names 391 + let rtp = s:rtp(g:plugs[name]) 392 + for dir in a:types 393 + call s:source(rtp, dir.'/**/*.vim') 394 + endfor 395 + if exists('#User#'.name) 396 + execute 'doautocmd User' name 397 + endif 398 + endfor 399 + endfunction 400 + 401 + function! s:lod_ft(pat, names) 402 + call s:lod(a:names, ['plugin', 'after/plugin', 'syntax', 'after/syntax']) 403 + execute 'autocmd! PlugLOD FileType' a:pat 404 + if exists('#filetypeplugin#FileType') 405 + doautocmd filetypeplugin FileType 406 + endif 407 + if exists('#filetypeindent#FileType') 408 + doautocmd filetypeindent FileType 409 + endif 410 + endfunction 411 + 412 + function! s:lod_cmd(cmd, bang, l1, l2, args, names) 413 + call s:lod(a:names, ['ftdetect', 'after/ftdetect', 'plugin', 'after/plugin']) 414 + execute printf('%s%s%s %s', (a:l1 == a:l2 ? '' : (a:l1.','.a:l2)), a:cmd, a:bang, a:args) 415 + endfunction 416 + 417 + function! s:lod_map(map, names, prefix) 418 + call s:lod(a:names, ['ftdetect', 'after/ftdetect', 'plugin', 'after/plugin']) 419 + let extra = '' 420 + while 1 421 + let c = getchar(0) 422 + if c == 0 423 + break 424 + endif 425 + let extra .= nr2char(c) 426 + endwhile 427 + call feedkeys(a:prefix . substitute(a:map, '^<Plug>', "\<Plug>", '') . extra) 428 + endfunction 429 + 430 + function! s:add(repo, ...) 431 + if a:0 > 1 432 + return s:err('Invalid number of arguments (1..2)') 433 + endif 434 + 435 + try 436 + let repo = s:trim(a:repo) 437 + let name = fnamemodify(repo, ':t:s?\.git$??') 438 + let spec = extend(s:infer_properties(name, repo), 439 + \ a:0 == 1 ? s:parse_options(a:1) : s:base_spec) 440 + if !has_key(g:plugs, name) 441 + call add(g:plugs_order, name) 442 + endif 443 + let g:plugs[name] = spec 444 + let s:loaded[name] = get(s:loaded, name, 0) 445 + catch 446 + return s:err(v:exception) 447 + endtry 448 + endfunction 449 + 450 + function! s:parse_options(arg) 451 + let opts = copy(s:base_spec) 452 + let type = type(a:arg) 453 + if type == s:TYPE.string 454 + let opts.tag = a:arg 455 + elseif type == s:TYPE.dict 456 + call extend(opts, a:arg) 457 + if has_key(opts, 'dir') 458 + let opts.dir = s:dirpath(expand(opts.dir)) 459 + endif 460 + else 461 + throw 'Invalid argument type (expected: string or dictionary)' 462 + endif 463 + return opts 464 + endfunction 465 + 466 + function! s:infer_properties(name, repo) 467 + let repo = a:repo 468 + if s:is_local_plug(repo) 469 + return { 'dir': s:dirpath(expand(repo)) } 470 + else 471 + if repo =~ ':' 472 + let uri = repo 473 + else 474 + if repo !~ '/' 475 + let repo = 'vim-scripts/'. repo 476 + endif 477 + let fmt = get(g:, 'plug_url_format', 'https://git::@github.com/%s.git') 478 + let uri = printf(fmt, repo) 479 + endif 480 + let dir = s:dirpath( fnamemodify(join([g:plug_home, a:name], '/'), ':p') ) 481 + return { 'dir': dir, 'uri': uri } 482 + endif 483 + endfunction 484 + 485 + function! s:install(force, names) 486 + call s:update_impl(0, a:force, a:names) 487 + endfunction 488 + 489 + function! s:update(force, names) 490 + call s:update_impl(1, a:force, a:names) 491 + endfunction 492 + 493 + function! plug#helptags() 494 + if !exists('g:plugs') 495 + return s:err('plug#begin was not called') 496 + endif 497 + for spec in values(g:plugs) 498 + let docd = join([spec.dir, 'doc'], '/') 499 + if isdirectory(docd) 500 + silent! execute 'helptags' s:esc(docd) 501 + endif 502 + endfor 503 + return 1 504 + endfunction 505 + 506 + function! s:syntax() 507 + syntax clear 508 + syntax region plug1 start=/\%1l/ end=/\%2l/ contains=plugNumber 509 + syntax region plug2 start=/\%2l/ end=/\%3l/ contains=plugBracket,plugX 510 + syn match plugNumber /[0-9]\+[0-9.]*/ contained 511 + syn match plugBracket /[[\]]/ contained 512 + syn match plugX /x/ contained 513 + syn match plugDash /^-/ 514 + syn match plugPlus /^+/ 515 + syn match plugStar /^*/ 516 + syn match plugMessage /\(^- \)\@<=.*/ 517 + syn match plugName /\(^- \)\@<=[^ ]*:/ 518 + syn match plugInstall /\(^+ \)\@<=[^:]*/ 519 + syn match plugUpdate /\(^* \)\@<=[^:]*/ 520 + syn match plugCommit /^ [0-9a-z]\{7} .*/ contains=plugRelDate,plugSha 521 + syn match plugSha /\(^ \)\@<=[0-9a-z]\{7}/ contained 522 + syn match plugRelDate /([^)]*)$/ contained 523 + syn match plugNotLoaded /(not loaded)$/ 524 + syn match plugError /^x.*/ 525 + syn keyword Function PlugInstall PlugStatus PlugUpdate PlugClean 526 + hi def link plug1 Title 527 + hi def link plug2 Repeat 528 + hi def link plugX Exception 529 + hi def link plugBracket Structure 530 + hi def link plugNumber Number 531 + 532 + hi def link plugDash Special 533 + hi def link plugPlus Constant 534 + hi def link plugStar Boolean 535 + 536 + hi def link plugMessage Function 537 + hi def link plugName Label 538 + hi def link plugInstall Function 539 + hi def link plugUpdate Type 540 + 541 + hi def link plugError Error 542 + hi def link plugRelDate Comment 543 + hi def link plugSha Identifier 544 + 545 + hi def link plugNotLoaded Comment 546 + endfunction 547 + 548 + function! s:lpad(str, len) 549 + return a:str . repeat(' ', a:len - len(a:str)) 550 + endfunction 551 + 552 + function! s:lines(msg) 553 + return split(a:msg, "[\r\n]") 554 + endfunction 555 + 556 + function! s:lastline(msg) 557 + return get(s:lines(a:msg), -1, '') 558 + endfunction 559 + 560 + function! s:new_window() 561 + execute get(g:, 'plug_window', 'vertical topleft new') 562 + endfunction 563 + 564 + function! s:plug_window_exists() 565 + let buflist = tabpagebuflist(s:plug_tab) 566 + return !empty(buflist) && index(buflist, s:plug_buf) >= 0 567 + endfunction 568 + 569 + function! s:switch_in() 570 + if !s:plug_window_exists() 571 + return 0 572 + endif 573 + 574 + if winbufnr(0) != s:plug_buf 575 + let s:pos = [tabpagenr(), winnr(), winsaveview()] 576 + execute 'normal!' s:plug_tab.'gt' 577 + let winnr = bufwinnr(s:plug_buf) 578 + execute winnr.'wincmd w' 579 + call add(s:pos, winsaveview()) 580 + else 581 + let s:pos = [winsaveview()] 582 + endif 583 + 584 + setlocal modifiable 585 + return 1 586 + endfunction 587 + 588 + function! s:switch_out(...) 589 + call winrestview(s:pos[-1]) 590 + setlocal nomodifiable 591 + if a:0 > 0 592 + execute a:1 593 + endif 594 + 595 + if len(s:pos) > 1 596 + execute 'normal!' s:pos[0].'gt' 597 + execute s:pos[1] 'wincmd w' 598 + call winrestview(s:pos[2]) 599 + endif 600 + endfunction 601 + 602 + function! s:prepare() 603 + call s:job_abort() 604 + if s:switch_in() 605 + silent %d _ 606 + else 607 + call s:new_window() 608 + nnoremap <silent> <buffer> q :if b:plug_preview==1<bar>pc<bar>endif<bar>echo<bar>q<cr> 609 + nnoremap <silent> <buffer> R :silent! call <SID>retry()<cr> 610 + nnoremap <silent> <buffer> D :PlugDiff<cr> 611 + nnoremap <silent> <buffer> S :PlugStatus<cr> 612 + nnoremap <silent> <buffer> U :call <SID>status_update()<cr> 613 + xnoremap <silent> <buffer> U :call <SID>status_update()<cr> 614 + nnoremap <silent> <buffer> ]] :silent! call <SID>section('')<cr> 615 + nnoremap <silent> <buffer> [[ :silent! call <SID>section('b')<cr> 616 + let b:plug_preview = -1 617 + let s:plug_tab = tabpagenr() 618 + let s:plug_buf = winbufnr(0) 619 + call s:assign_name() 620 + endif 621 + silent! unmap <buffer> <cr> 622 + silent! unmap <buffer> L 623 + silent! unmap <buffer> o 624 + silent! unmap <buffer> X 625 + setlocal buftype=nofile bufhidden=wipe nobuflisted noswapfile nowrap cursorline modifiable 626 + setf vim-plug 627 + call s:syntax() 628 + endfunction 629 + 630 + function! s:assign_name() 631 + " Assign buffer name 632 + let prefix = '[Plugins]' 633 + let name = prefix 634 + let idx = 2 635 + while bufexists(name) 636 + let name = printf('%s (%s)', prefix, idx) 637 + let idx = idx + 1 638 + endwhile 639 + silent! execute 'f' fnameescape(name) 640 + endfunction 641 + 642 + function! s:do(pull, force, todo) 643 + for [name, spec] in items(a:todo) 644 + if !isdirectory(spec.dir) 645 + continue 646 + endif 647 + let installed = has_key(s:update.new, name) 648 + let updated = installed ? 0 : 649 + \ (a:pull && index(s:update.errors, name) < 0 && !empty(s:system_chomp('git log --pretty=format:"%h" "HEAD...HEAD@{1}"', spec.dir))) 650 + if a:force || installed || updated 651 + execute 'cd' s:esc(spec.dir) 652 + call append(3, '- Post-update hook for '. name .' ... ') 653 + let type = type(spec.do) 654 + if type == s:TYPE.string 655 + try 656 + " FIXME: Escaping is incomplete. We could use shellescape with eval, 657 + " but it won't work on Windows. 658 + let g:_plug_do = '!'.escape(spec.do, '#!%') 659 + execute "normal! :execute g:_plug_do\<cr>\<cr>" 660 + finally 661 + let result = v:shell_error ? ('Exit status: '.v:shell_error) : 'Done!' 662 + unlet g:_plug_do 663 + endtry 664 + elseif type == s:TYPE.funcref 665 + try 666 + let status = installed ? 'installed' : (updated ? 'updated' : 'unchanged') 667 + call spec.do({ 'name': name, 'status': status, 'force': a:force }) 668 + let result = 'Done!' 669 + catch 670 + let result = 'Error: ' . v:exception 671 + endtry 672 + else 673 + let result = 'Error: Invalid type!' 674 + endif 675 + call setline(4, getline(4) . result) 676 + cd - 677 + endif 678 + endfor 679 + endfunction 680 + 681 + function! s:finish(pull) 682 + let new_frozen = len(filter(keys(s:update.new), 'g:plugs[v:val].frozen')) 683 + if new_frozen 684 + let s = new_frozen > 1 ? 's' : '' 685 + call append(3, printf('- Installed %d frozen plugin%s', new_frozen, s)) 686 + endif 687 + call append(3, '- Finishing ... ') 688 + redraw 689 + call plug#helptags() 690 + call plug#end() 691 + call setline(4, getline(4) . 'Done!') 692 + redraw 693 + let msgs = [] 694 + if !empty(s:update.errors) 695 + call add(msgs, "Press 'R' to retry.") 696 + endif 697 + if a:pull && len(s:update.new) < len(filter(getline(5, '$'), 698 + \ "v:val =~ '^- ' && stridx(v:val, 'Already up-to-date') < 0")) 699 + call add(msgs, "Press 'D' to see the updated changes.") 700 + endif 701 + echo join(msgs, ' ') 702 + endfunction 703 + 704 + function! s:retry() 705 + if empty(s:update.errors) 706 + return 707 + endif 708 + call s:update_impl(s:update.pull, s:update.force, 709 + \ extend(copy(s:update.errors), [s:update.threads])) 710 + endfunction 711 + 712 + function! s:is_managed(name) 713 + return has_key(g:plugs[a:name], 'uri') 714 + endfunction 715 + 716 + function! s:names(...) 717 + return sort(filter(keys(g:plugs), 'stridx(v:val, a:1) == 0 && s:is_managed(v:val)')) 718 + endfunction 719 + 720 + function! s:update_impl(pull, force, args) abort 721 + let args = copy(a:args) 722 + let threads = (len(args) > 0 && args[-1] =~ '^[1-9][0-9]*$') ? 723 + \ remove(args, -1) : get(g:, 'plug_threads', s:is_win ? 1 : 16) 724 + 725 + let managed = filter(copy(g:plugs), 's:is_managed(v:key)') 726 + let todo = empty(args) ? filter(managed, '!v:val.frozen || !isdirectory(v:val.dir)') : 727 + \ filter(managed, 'index(args, v:key) >= 0') 728 + 729 + if empty(todo) 730 + echohl WarningMsg 731 + echo 'No plugin to '. (a:pull ? 'update' : 'install') . '.' 732 + echohl None 733 + return 734 + endif 735 + 736 + if !s:is_win && s:git_version_requirement(2, 3) 737 + let s:git_terminal_prompt = exists('$GIT_TERMINAL_PROMPT') ? $GIT_TERMINAL_PROMPT : '' 738 + let $GIT_TERMINAL_PROMPT = 0 739 + for plug in values(todo) 740 + let plug.uri = substitute(plug.uri, 741 + \ '^https://git::@github\.com', 'https://github.com', '') 742 + endfor 743 + endif 744 + 745 + if !isdirectory(g:plug_home) 746 + try 747 + call mkdir(g:plug_home, 'p') 748 + catch 749 + return s:err(printf('Invalid plug directory: %s. '. 750 + \ 'Try to call plug#begin with a valid directory', g:plug_home)) 751 + endtry 752 + endif 753 + 754 + if has('nvim') && !exists('*jobwait') && threads > 1 755 + echohl WarningMsg 756 + echomsg 'vim-plug: update Neovim for parallel installer' 757 + echohl None 758 + endif 759 + 760 + let python = (has('python') || has('python3')) && !s:is_win && !has('win32unix') 761 + \ && (!s:nvim || has('vim_starting')) 762 + let ruby = has('ruby') && !s:nvim && (v:version >= 703 || v:version == 702 && has('patch374')) 763 + 764 + let s:update = { 765 + \ 'start': reltime(), 766 + \ 'all': todo, 767 + \ 'todo': copy(todo), 768 + \ 'errors': [], 769 + \ 'pull': a:pull, 770 + \ 'force': a:force, 771 + \ 'new': {}, 772 + \ 'threads': (python || ruby || s:nvim) ? min([len(todo), threads]) : 1, 773 + \ 'bar': '', 774 + \ 'fin': 0 775 + \ } 776 + 777 + call s:prepare() 778 + call append(0, ['', '']) 779 + normal! 2G 780 + silent! redraw 781 + 782 + let s:clone_opt = get(g:, 'plug_shallow', 1) ? 783 + \ '--depth 1' . (s:git_version_requirement(1, 7, 10) ? ' --no-single-branch' : '') : '' 784 + 785 + " Python version requirement (>= 2.7) 786 + if python && !has('python3') && !ruby && !s:nvim && s:update.threads > 1 787 + redir => pyv 788 + silent python import platform; print(platform.python_version()) 789 + redir END 790 + let python = s:version_requirement( 791 + \ map(split(split(pyv)[0], '\.'), 'str2nr(v:val)'), [2, 6]) 792 + endif 793 + 794 + if (python || ruby) && s:update.threads > 1 795 + try 796 + let imd = &imd 797 + if s:mac_gui 798 + set noimd 799 + endif 800 + if ruby 801 + call s:update_ruby() 802 + else 803 + call s:update_python() 804 + endif 805 + catch 806 + let lines = getline(4, '$') 807 + let printed = {} 808 + silent! 4,$d _ 809 + for line in lines 810 + let name = s:extract_name(line, '.', '') 811 + if empty(name) || !has_key(printed, name) 812 + call append('$', line) 813 + if !empty(name) 814 + let printed[name] = 1 815 + if line[0] == 'x' && index(s:update.errors, name) < 0 816 + call add(s:update.errors, name) 817 + end 818 + endif 819 + endif 820 + endfor 821 + finally 822 + let &imd = imd 823 + call s:update_finish() 824 + endtry 825 + else 826 + call s:update_vim() 827 + endif 828 + endfunction 829 + 830 + function! s:update_finish() 831 + if exists('s:git_terminal_prompt') 832 + let $GIT_TERMINAL_PROMPT = s:git_terminal_prompt 833 + endif 834 + if s:switch_in() 835 + call s:do(s:update.pull, s:update.force, filter(copy(s:update.all), 'has_key(v:val, "do")')) 836 + call s:finish(s:update.pull) 837 + call setline(1, 'Updated. Elapsed time: ' . split(reltimestr(reltime(s:update.start)))[0] . ' sec.') 838 + call s:switch_out('normal! gg') 839 + endif 840 + endfunction 841 + 842 + function! s:job_abort() 843 + if !s:nvim || !exists('s:jobs') 844 + return 845 + endif 846 + 847 + for [name, j] in items(s:jobs) 848 + silent! call jobstop(j.jobid) 849 + if j.new 850 + call s:system('rm -rf ' . s:shellesc(g:plugs[name].dir)) 851 + endif 852 + endfor 853 + let s:jobs = {} 854 + endfunction 855 + 856 + " When a:event == 'stdout', data = list of strings 857 + " When a:event == 'exit', data = returncode 858 + function! s:job_handler(job_id, data, event) abort 859 + if !s:plug_window_exists() " plug window closed 860 + return s:job_abort() 861 + endif 862 + 863 + if a:event == 'stdout' 864 + let self.result .= substitute(s:to_s(a:data), '[\r\n]', '', 'g') . "\n" 865 + " To reduce the number of buffer updates 866 + let self.tick = get(self, 'tick', -1) + 1 867 + if self.tick % len(s:jobs) == 0 868 + call s:log(self.new ? '+' : '*', self.name, self.result) 869 + endif 870 + elseif a:event == 'exit' 871 + let self.running = 0 872 + if a:data != 0 873 + let self.error = 1 874 + endif 875 + call s:reap(self.name) 876 + call s:tick() 877 + endif 878 + endfunction 879 + 880 + function! s:spawn(name, cmd, opts) 881 + let job = { 'name': a:name, 'running': 1, 'error': 0, 'result': '', 882 + \ 'new': get(a:opts, 'new', 0), 883 + \ 'on_stdout': function('s:job_handler'), 884 + \ 'on_exit' : function('s:job_handler'), 885 + \ } 886 + let s:jobs[a:name] = job 887 + 888 + if s:nvim 889 + let argv = [ 'sh', '-c', 890 + \ (has_key(a:opts, 'dir') ? s:with_cd(a:cmd, a:opts.dir) : a:cmd) ] 891 + let jid = jobstart(argv, job) 892 + if jid > 0 893 + let job.jobid = jid 894 + else 895 + let job.running = 0 896 + let job.error = 1 897 + let job.result = jid < 0 ? 'sh is not executable' : 898 + \ 'Invalid arguments (or job table is full)' 899 + endif 900 + else 901 + let params = has_key(a:opts, 'dir') ? [a:cmd, a:opts.dir] : [a:cmd] 902 + let job.result = call('s:system', params) 903 + let job.error = v:shell_error != 0 904 + let job.running = 0 905 + endif 906 + endfunction 907 + 908 + function! s:reap(name) 909 + let job = s:jobs[a:name] 910 + if job.error 911 + call add(s:update.errors, a:name) 912 + elseif get(job, 'new', 0) 913 + let s:update.new[a:name] = 1 914 + endif 915 + let s:update.bar .= job.error ? 'x' : '=' 916 + 917 + call s:log(job.error ? 'x' : '-', a:name, job.result) 918 + call s:bar() 919 + 920 + call remove(s:jobs, a:name) 921 + endfunction 922 + 923 + function! s:bar() 924 + if s:switch_in() 925 + let total = len(s:update.all) 926 + call setline(1, (s:update.pull ? 'Updating' : 'Installing'). 927 + \ ' plugins ('.len(s:update.bar).'/'.total.')') 928 + call s:progress_bar(2, s:update.bar, total) 929 + call s:switch_out() 930 + endif 931 + endfunction 932 + 933 + function! s:logpos(name) 934 + for i in range(1, line('$')) 935 + if getline(i) =~# '^[-+x*] '.a:name.':' 936 + return i 937 + endif 938 + endfor 939 + return 0 940 + endfunction 941 + 942 + function! s:log(bullet, name, lines) 943 + if s:switch_in() 944 + let pos = s:logpos(a:name) 945 + if pos > 0 946 + execute pos 'd _' 947 + if pos > winheight('.') 948 + let pos = 4 949 + endif 950 + else 951 + let pos = 4 952 + endif 953 + call append(pos - 1, s:format_message(a:bullet, a:name, a:lines)) 954 + call s:switch_out() 955 + endif 956 + endfunction 957 + 958 + function! s:update_vim() 959 + let s:jobs = {} 960 + 961 + call s:bar() 962 + call s:tick() 963 + endfunction 964 + 965 + function! s:tick() 966 + let pull = s:update.pull 967 + let prog = s:progress_opt(s:nvim) 968 + while 1 " Without TCO, Vim stack is bound to explode 969 + if empty(s:update.todo) 970 + if empty(s:jobs) && !s:update.fin 971 + let s:update.fin = 1 972 + call s:update_finish() 973 + endif 974 + return 975 + endif 976 + 977 + let name = keys(s:update.todo)[0] 978 + let spec = remove(s:update.todo, name) 979 + let new = !isdirectory(spec.dir) 980 + 981 + call s:log(new ? '+' : '*', name, pull ? 'Updating ...' : 'Installing ...') 982 + redraw 983 + 984 + let has_tag = has_key(spec, 'tag') 985 + let checkout = s:shellesc(has_tag ? spec.tag : spec.branch) 986 + let merge = s:shellesc(has_tag ? spec.tag : 'origin/'.spec.branch) 987 + 988 + if !new 989 + let [valid, msg] = s:git_valid(spec, 0) 990 + if valid 991 + if pull 992 + let fetch_opt = (has_tag && !empty(globpath(spec.dir, '.git/shallow'))) ? '--depth 99999999' : '' 993 + call s:spawn(name, 994 + \ printf('(git fetch %s %s 2>&1 && git checkout -q %s 2>&1 && git merge --ff-only %s 2>&1 && git submodule update --init --recursive 2>&1)', 995 + \ fetch_opt, prog, checkout, merge), { 'dir': spec.dir }) 996 + else 997 + let s:jobs[name] = { 'running': 0, 'result': 'Already installed', 'error': 0 } 998 + endif 999 + else 1000 + let s:jobs[name] = { 'running': 0, 'result': msg, 'error': 1 } 1001 + endif 1002 + else 1003 + call s:spawn(name, 1004 + \ printf('git clone %s %s --recursive %s -b %s %s 2>&1', 1005 + \ has_tag ? '' : s:clone_opt, 1006 + \ prog, 1007 + \ s:shellesc(spec.uri), 1008 + \ checkout, 1009 + \ s:shellesc(s:trim(spec.dir))), { 'new': 1 }) 1010 + endif 1011 + 1012 + if !s:jobs[name].running 1013 + call s:reap(name) 1014 + endif 1015 + if len(s:jobs) >= s:update.threads 1016 + break 1017 + endif 1018 + endwhile 1019 + endfunction 1020 + 1021 + function! s:update_python() 1022 + let py_exe = has('python3') ? 'python3' : 'python' 1023 + execute py_exe "<< EOF" 1024 + """ Due to use of signals this function is POSIX only. """ 1025 + import datetime 1026 + import functools 1027 + import os 1028 + try: 1029 + import queue 1030 + except ImportError: 1031 + import Queue as queue 1032 + import random 1033 + import re 1034 + import shutil 1035 + import signal 1036 + import subprocess 1037 + import tempfile 1038 + import threading as thr 1039 + import time 1040 + import traceback 1041 + import vim 1042 + 1043 + G_NVIM = vim.eval("has('nvim')") == '1' 1044 + G_PULL = vim.eval('s:update.pull') == '1' 1045 + G_RETRIES = int(vim.eval('get(g:, "plug_retries", 2)')) + 1 1046 + G_TIMEOUT = int(vim.eval('get(g:, "plug_timeout", 60)')) 1047 + G_CLONE_OPT = vim.eval('s:clone_opt') 1048 + G_PROGRESS = vim.eval('s:progress_opt(1)') 1049 + G_LOG_PROB = 1.0 / int(vim.eval('s:update.threads')) 1050 + G_STOP = thr.Event() 1051 + G_THREADS = {} 1052 + 1053 + class PlugError(Exception): 1054 + def __init__(self, msg): 1055 + self._msg = msg 1056 + @property 1057 + def msg(self): 1058 + return self._msg 1059 + class CmdTimedOut(PlugError): 1060 + pass 1061 + class CmdFailed(PlugError): 1062 + pass 1063 + class InvalidURI(PlugError): 1064 + pass 1065 + class Action(object): 1066 + INSTALL, UPDATE, ERROR, DONE = ['+', '*', 'x', '-'] 1067 + 1068 + class Buffer(object): 1069 + def __init__(self, lock, num_plugs, is_pull, is_win): 1070 + self.bar = '' 1071 + self.event = 'Updating' if is_pull else 'Installing' 1072 + self.is_win = is_win 1073 + self.lock = lock 1074 + self.maxy = int(vim.eval('winheight(".")')) 1075 + self.num_plugs = num_plugs 1076 + 1077 + def __where(self, name): 1078 + """ Find first line with name in current buffer. Return line num. """ 1079 + found, lnum = False, 0 1080 + matcher = re.compile('^[-+x*] {0}:'.format(name)) 1081 + for line in vim.current.buffer: 1082 + if matcher.search(line) is not None: 1083 + found = True 1084 + break 1085 + lnum += 1 1086 + 1087 + if not found: 1088 + lnum = -1 1089 + return lnum 1090 + 1091 + def header(self): 1092 + curbuf = vim.current.buffer 1093 + curbuf[0] = self.event + ' plugins ({0}/{1})'.format(len(self.bar), self.num_plugs) 1094 + 1095 + num_spaces = self.num_plugs - len(self.bar) 1096 + curbuf[1] = '[{0}{1}]'.format(self.bar, num_spaces * ' ') 1097 + 1098 + with self.lock: 1099 + vim.command('normal! 2G') 1100 + if not self.is_win: 1101 + vim.command('redraw') 1102 + 1103 + def write(self, action, name, lines): 1104 + first, rest = lines[0], lines[1:] 1105 + msg = ['{0} {1}{2}{3}'.format(action, name, ': ' if first else '', first)] 1106 + msg.extend([' ' + line for line in rest]) 1107 + 1108 + try: 1109 + if action == Action.ERROR: 1110 + self.bar += 'x' 1111 + vim.command("call add(s:update.errors, '{0}')".format(name)) 1112 + elif action == Action.DONE: 1113 + self.bar += '=' 1114 + 1115 + curbuf = vim.current.buffer 1116 + lnum = self.__where(name) 1117 + if lnum != -1: # Found matching line num 1118 + del curbuf[lnum] 1119 + if lnum > self.maxy and action in set([Action.INSTALL, Action.UPDATE]): 1120 + lnum = 3 1121 + else: 1122 + lnum = 3 1123 + curbuf.append(msg, lnum) 1124 + 1125 + self.header() 1126 + except vim.error: 1127 + pass 1128 + 1129 + class Command(object): 1130 + def __init__(self, cmd, cmd_dir=None, timeout=60, cb=None, clean=None): 1131 + self.cmd = cmd 1132 + self.cmd_dir = cmd_dir 1133 + self.timeout = timeout 1134 + self.callback = cb if cb else (lambda msg: None) 1135 + self.clean = clean if clean else (lambda: None) 1136 + self.proc = None 1137 + 1138 + @property 1139 + def alive(self): 1140 + """ Returns true only if command still running. """ 1141 + return self.proc and self.proc.poll() is None 1142 + 1143 + def execute(self, ntries=3): 1144 + """ Execute the command with ntries if CmdTimedOut. 1145 + Returns the output of the command if no Exception. 1146 + """ 1147 + attempt, finished, limit = 0, False, self.timeout 1148 + 1149 + while not finished: 1150 + try: 1151 + attempt += 1 1152 + result = self.try_command() 1153 + finished = True 1154 + return result 1155 + except CmdTimedOut: 1156 + if attempt != ntries: 1157 + self.notify_retry() 1158 + self.timeout += limit 1159 + else: 1160 + raise 1161 + 1162 + def notify_retry(self): 1163 + """ Retry required for command, notify user. """ 1164 + for count in range(3, 0, -1): 1165 + if G_STOP.is_set(): 1166 + raise KeyboardInterrupt 1167 + msg = 'Timeout. Will retry in {0} second{1} ...'.format( 1168 + count, 's' if count != 1 else '') 1169 + self.callback([msg]) 1170 + time.sleep(1) 1171 + self.callback(['Retrying ...']) 1172 + 1173 + def try_command(self): 1174 + """ Execute a cmd & poll for callback. Returns list of output. 1175 + Raises CmdFailed -> return code for Popen isn't 0 1176 + Raises CmdTimedOut -> command exceeded timeout without new output 1177 + """ 1178 + first_line = True 1179 + 1180 + try: 1181 + tfile = tempfile.NamedTemporaryFile(mode='w+b') 1182 + self.proc = subprocess.Popen(self.cmd, cwd=self.cmd_dir, stdout=tfile, 1183 + stderr=subprocess.STDOUT, shell=True, 1184 + preexec_fn=os.setsid) 1185 + thrd = thr.Thread(target=(lambda proc: proc.wait()), args=(self.proc,)) 1186 + thrd.start() 1187 + 1188 + thread_not_started = True 1189 + while thread_not_started: 1190 + try: 1191 + thrd.join(0.1) 1192 + thread_not_started = False 1193 + except RuntimeError: 1194 + pass 1195 + 1196 + while self.alive: 1197 + if G_STOP.is_set(): 1198 + raise KeyboardInterrupt 1199 + 1200 + if first_line or random.random() < G_LOG_PROB: 1201 + first_line = False 1202 + line = nonblock_read(tfile.name) 1203 + if line: 1204 + self.callback([line]) 1205 + 1206 + time_diff = time.time() - os.path.getmtime(tfile.name) 1207 + if time_diff > self.timeout: 1208 + raise CmdTimedOut(['Timeout!']) 1209 + 1210 + thrd.join(0.5) 1211 + 1212 + tfile.seek(0) 1213 + result = [line.decode('utf-8', 'replace').rstrip() for line in tfile] 1214 + 1215 + if self.proc.returncode != 0: 1216 + raise CmdFailed([''] + result) 1217 + 1218 + return result 1219 + except: 1220 + self.terminate() 1221 + raise 1222 + 1223 + def terminate(self): 1224 + """ Terminate process and cleanup. """ 1225 + if self.alive: 1226 + os.killpg(self.proc.pid, signal.SIGTERM) 1227 + self.clean() 1228 + 1229 + class Plugin(object): 1230 + def __init__(self, name, args, buf_q, lock): 1231 + self.name = name 1232 + self.args = args 1233 + self.buf_q = buf_q 1234 + self.lock = lock 1235 + tag = args.get('tag', 0) 1236 + self.checkout = esc(tag if tag else args['branch']) 1237 + self.merge = esc(tag if tag else 'origin/' + args['branch']) 1238 + self.tag = tag 1239 + 1240 + def manage(self): 1241 + try: 1242 + if os.path.exists(self.args['dir']): 1243 + self.update() 1244 + else: 1245 + self.install() 1246 + with self.lock: 1247 + thread_vim_command("let s:update.new['{0}'] = 1".format(self.name)) 1248 + except PlugError as exc: 1249 + self.write(Action.ERROR, self.name, exc.msg) 1250 + except KeyboardInterrupt: 1251 + G_STOP.set() 1252 + self.write(Action.ERROR, self.name, ['Interrupted!']) 1253 + except: 1254 + # Any exception except those above print stack trace 1255 + msg = 'Trace:\n{0}'.format(traceback.format_exc().rstrip()) 1256 + self.write(Action.ERROR, self.name, msg.split('\n')) 1257 + raise 1258 + 1259 + def install(self): 1260 + target = self.args['dir'] 1261 + 1262 + def clean(target): 1263 + def _clean(): 1264 + try: 1265 + shutil.rmtree(target) 1266 + except OSError: 1267 + pass 1268 + return _clean 1269 + 1270 + self.write(Action.INSTALL, self.name, ['Installing ...']) 1271 + callback = functools.partial(self.write, Action.INSTALL, self.name) 1272 + cmd = 'git clone {0} {1} --recursive {2} -b {3} {4} 2>&1'.format( 1273 + '' if self.tag else G_CLONE_OPT, G_PROGRESS, self.args['uri'], 1274 + self.checkout, esc(target)) 1275 + com = Command(cmd, None, G_TIMEOUT, callback, clean(target)) 1276 + result = com.execute(G_RETRIES) 1277 + self.write(Action.DONE, self.name, result[-1:]) 1278 + 1279 + def repo_uri(self): 1280 + cmd = 'git rev-parse --abbrev-ref HEAD 2>&1 && git config remote.origin.url' 1281 + command = Command(cmd, self.args['dir'], G_TIMEOUT,) 1282 + result = command.execute(G_RETRIES) 1283 + return result[-1] 1284 + 1285 + def update(self): 1286 + match = re.compile(r'git::?@') 1287 + actual_uri = re.sub(match, '', self.repo_uri()) 1288 + expect_uri = re.sub(match, '', self.args['uri']) 1289 + if actual_uri != expect_uri: 1290 + msg = ['', 1291 + 'Invalid URI: {0}'.format(actual_uri), 1292 + 'Expected {0}'.format(expect_uri), 1293 + 'PlugClean required.'] 1294 + raise InvalidURI(msg) 1295 + 1296 + if G_PULL: 1297 + self.write(Action.UPDATE, self.name, ['Updating ...']) 1298 + callback = functools.partial(self.write, Action.UPDATE, self.name) 1299 + fetch_opt = '--depth 99999999' if self.tag and os.path.isfile(os.path.join(self.args['dir'], '.git/shallow')) else '' 1300 + cmds = ['git fetch {0} {1}'.format(fetch_opt, G_PROGRESS), 1301 + 'git checkout -q {0}'.format(self.checkout), 1302 + 'git merge --ff-only {0}'.format(self.merge), 1303 + 'git submodule update --init --recursive'] 1304 + cmd = ' 2>&1 && '.join(cmds) 1305 + com = Command(cmd, self.args['dir'], G_TIMEOUT, callback) 1306 + result = com.execute(G_RETRIES) 1307 + self.write(Action.DONE, self.name, result[-1:]) 1308 + else: 1309 + self.write(Action.DONE, self.name, ['Already installed']) 1310 + 1311 + def write(self, action, name, msg): 1312 + self.buf_q.put((action, name, msg)) 1313 + 1314 + class PlugThread(thr.Thread): 1315 + def __init__(self, tname, args): 1316 + super(PlugThread, self).__init__() 1317 + self.tname = tname 1318 + self.args = args 1319 + 1320 + def run(self): 1321 + thr.current_thread().name = self.tname 1322 + buf_q, work_q, lock = self.args 1323 + 1324 + try: 1325 + while not G_STOP.is_set(): 1326 + name, args = work_q.get_nowait() 1327 + plug = Plugin(name, args, buf_q, lock) 1328 + plug.manage() 1329 + work_q.task_done() 1330 + except queue.Empty: 1331 + pass 1332 + finally: 1333 + global G_THREADS 1334 + with lock: 1335 + del G_THREADS[thr.current_thread().name] 1336 + 1337 + class RefreshThread(thr.Thread): 1338 + def __init__(self, lock): 1339 + super(RefreshThread, self).__init__() 1340 + self.lock = lock 1341 + self.running = True 1342 + 1343 + def run(self): 1344 + while self.running: 1345 + with self.lock: 1346 + thread_vim_command('noautocmd normal! a') 1347 + time.sleep(0.33) 1348 + 1349 + def stop(self): 1350 + self.running = False 1351 + 1352 + if G_NVIM: 1353 + def thread_vim_command(cmd): 1354 + vim.session.threadsafe_call(lambda: vim.command(cmd)) 1355 + else: 1356 + def thread_vim_command(cmd): 1357 + vim.command(cmd) 1358 + 1359 + def esc(name): 1360 + return '"' + name.replace('"', '\"') + '"' 1361 + 1362 + def nonblock_read(fname): 1363 + """ Read a file with nonblock flag. Return the last line. """ 1364 + fread = os.open(fname, os.O_RDONLY | os.O_NONBLOCK) 1365 + buf = os.read(fread, 100000).decode('utf-8', 'replace') 1366 + os.close(fread) 1367 + 1368 + line = buf.rstrip('\r\n') 1369 + left = max(line.rfind('\r'), line.rfind('\n')) 1370 + if left != -1: 1371 + left += 1 1372 + line = line[left:] 1373 + 1374 + return line 1375 + 1376 + def main(): 1377 + thr.current_thread().name = 'main' 1378 + nthreads = int(vim.eval('s:update.threads')) 1379 + plugs = vim.eval('s:update.todo') 1380 + mac_gui = vim.eval('s:mac_gui') == '1' 1381 + is_win = vim.eval('s:is_win') == '1' 1382 + 1383 + lock = thr.Lock() 1384 + buf = Buffer(lock, len(plugs), G_PULL, is_win) 1385 + buf_q, work_q = queue.Queue(), queue.Queue() 1386 + for work in plugs.items(): 1387 + work_q.put(work) 1388 + 1389 + global G_THREADS 1390 + for num in range(nthreads): 1391 + tname = 'PlugT-{0:02}'.format(num) 1392 + thread = PlugThread(tname, (buf_q, work_q, lock)) 1393 + thread.start() 1394 + G_THREADS[tname] = thread 1395 + if mac_gui: 1396 + rthread = RefreshThread(lock) 1397 + rthread.start() 1398 + 1399 + while not buf_q.empty() or len(G_THREADS) != 0: 1400 + try: 1401 + action, name, msg = buf_q.get(True, 0.25) 1402 + buf.write(action, name, msg) 1403 + buf_q.task_done() 1404 + except queue.Empty: 1405 + pass 1406 + except KeyboardInterrupt: 1407 + G_STOP.set() 1408 + 1409 + if mac_gui: 1410 + rthread.stop() 1411 + rthread.join() 1412 + 1413 + main() 1414 + EOF 1415 + endfunction 1416 + 1417 + function! s:update_ruby() 1418 + ruby << EOF 1419 + module PlugStream 1420 + SEP = ["\r", "\n", nil] 1421 + def get_line 1422 + buffer = '' 1423 + loop do 1424 + char = readchar rescue return 1425 + if SEP.include? char.chr 1426 + buffer << $/ 1427 + break 1428 + else 1429 + buffer << char 1430 + end 1431 + end 1432 + buffer 1433 + end 1434 + end unless defined?(PlugStream) 1435 + 1436 + def esc arg 1437 + %["#{arg.gsub('"', '\"')}"] 1438 + end 1439 + 1440 + def killall pid 1441 + pids = [pid] 1442 + unless `which pgrep 2> /dev/null`.empty? 1443 + children = pids 1444 + until children.empty? 1445 + children = children.map { |pid| 1446 + `pgrep -P #{pid}`.lines.map { |l| l.chomp } 1447 + }.flatten 1448 + pids += children 1449 + end 1450 + end 1451 + pids.each { |pid| Process.kill 'TERM', pid.to_i rescue nil } 1452 + end 1453 + 1454 + require 'thread' 1455 + require 'fileutils' 1456 + require 'timeout' 1457 + running = true 1458 + iswin = VIM::evaluate('s:is_win').to_i == 1 1459 + pull = VIM::evaluate('s:update.pull').to_i == 1 1460 + base = VIM::evaluate('g:plug_home') 1461 + all = VIM::evaluate('s:update.todo') 1462 + limit = VIM::evaluate('get(g:, "plug_timeout", 60)') 1463 + tries = VIM::evaluate('get(g:, "plug_retries", 2)') + 1 1464 + nthr = VIM::evaluate('s:update.threads').to_i 1465 + maxy = VIM::evaluate('winheight(".")').to_i 1466 + cd = iswin ? 'cd /d' : 'cd' 1467 + tot = VIM::evaluate('len(s:update.todo)') || 0 1468 + bar = '' 1469 + skip = 'Already installed' 1470 + mtx = Mutex.new 1471 + take1 = proc { mtx.synchronize { running && all.shift } } 1472 + logh = proc { 1473 + cnt = bar.length 1474 + $curbuf[1] = "#{pull ? 'Updating' : 'Installing'} plugins (#{cnt}/#{tot})" 1475 + $curbuf[2] = '[' + bar.ljust(tot) + ']' 1476 + VIM::command('normal! 2G') 1477 + VIM::command('redraw') unless iswin 1478 + } 1479 + where = proc { |name| (1..($curbuf.length)).find { |l| $curbuf[l] =~ /^[-+x*] #{name}:/ } } 1480 + log = proc { |name, result, type| 1481 + mtx.synchronize do 1482 + ing = ![true, false].include?(type) 1483 + bar += type ? '=' : 'x' unless ing 1484 + b = case type 1485 + when :install then '+' when :update then '*' 1486 + when true, nil then '-' else 1487 + VIM::command("call add(s:update.errors, '#{name}')") 1488 + 'x' 1489 + end 1490 + result = 1491 + if type || type.nil? 1492 + ["#{b} #{name}: #{result.lines.to_a.last}"] 1493 + elsif result =~ /^Interrupted|^Timeout/ 1494 + ["#{b} #{name}: #{result}"] 1495 + else 1496 + ["#{b} #{name}"] + result.lines.map { |l| " " << l } 1497 + end 1498 + if lnum = where.call(name) 1499 + $curbuf.delete lnum 1500 + lnum = 4 if ing && lnum > maxy 1501 + end 1502 + result.each_with_index do |line, offset| 1503 + $curbuf.append((lnum || 4) - 1 + offset, line.gsub(/\e\[./, '').chomp) 1504 + end 1505 + logh.call 1506 + end 1507 + } 1508 + bt = proc { |cmd, name, type, cleanup| 1509 + tried = timeout = 0 1510 + begin 1511 + tried += 1 1512 + timeout += limit 1513 + fd = nil 1514 + data = '' 1515 + if iswin 1516 + Timeout::timeout(timeout) do 1517 + tmp = VIM::evaluate('tempname()') 1518 + system("(#{cmd}) > #{tmp}") 1519 + data = File.read(tmp).chomp 1520 + File.unlink tmp rescue nil 1521 + end 1522 + else 1523 + fd = IO.popen(cmd).extend(PlugStream) 1524 + first_line = true 1525 + log_prob = 1.0 / nthr 1526 + while line = Timeout::timeout(timeout) { fd.get_line } 1527 + data << line 1528 + log.call name, line.chomp, type if name && (first_line || rand < log_prob) 1529 + first_line = false 1530 + end 1531 + fd.close 1532 + end 1533 + [$? == 0, data.chomp] 1534 + rescue Timeout::Error, Interrupt => e 1535 + if fd && !fd.closed? 1536 + killall fd.pid 1537 + fd.close 1538 + end 1539 + cleanup.call if cleanup 1540 + if e.is_a?(Timeout::Error) && tried < tries 1541 + 3.downto(1) do |countdown| 1542 + s = countdown > 1 ? 's' : '' 1543 + log.call name, "Timeout. Will retry in #{countdown} second#{s} ...", type 1544 + sleep 1 1545 + end 1546 + log.call name, 'Retrying ...', type 1547 + retry 1548 + end 1549 + [false, e.is_a?(Interrupt) ? "Interrupted!" : "Timeout!"] 1550 + end 1551 + } 1552 + main = Thread.current 1553 + threads = [] 1554 + watcher = Thread.new { 1555 + while VIM::evaluate('getchar(1)') 1556 + sleep 0.1 1557 + end 1558 + mtx.synchronize do 1559 + running = false 1560 + threads.each { |t| t.raise Interrupt } 1561 + end 1562 + threads.each { |t| t.join rescue nil } 1563 + main.kill 1564 + } 1565 + refresh = Thread.new { 1566 + while true 1567 + mtx.synchronize do 1568 + break unless running 1569 + VIM::command('noautocmd normal! a') 1570 + end 1571 + sleep 0.2 1572 + end 1573 + } if VIM::evaluate('s:mac_gui') == 1 1574 + 1575 + clone_opt = VIM::evaluate('s:clone_opt') 1576 + progress = VIM::evaluate('s:progress_opt(1)') 1577 + nthr.times do 1578 + mtx.synchronize do 1579 + threads << Thread.new { 1580 + while pair = take1.call 1581 + name = pair.first 1582 + dir, uri, branch, tag = pair.last.values_at *%w[dir uri branch tag] 1583 + checkout = esc(tag ? tag : branch) 1584 + merge = esc(tag ? tag : "origin/#{branch}") 1585 + subm = "git submodule update --init --recursive 2>&1" 1586 + exists = File.directory? dir 1587 + ok, result = 1588 + if exists 1589 + dir = iswin ? dir : esc(dir) 1590 + ret, data = bt.call "#{cd} #{dir} && git rev-parse --abbrev-ref HEAD 2>&1 && git config remote.origin.url", nil, nil, nil 1591 + current_uri = data.lines.to_a.last 1592 + if !ret 1593 + if data =~ /^Interrupted|^Timeout/ 1594 + [false, data] 1595 + else 1596 + [false, [data.chomp, "PlugClean required."].join($/)] 1597 + end 1598 + elsif current_uri.sub(/git::?@/, '') != uri.sub(/git::?@/, '') 1599 + [false, ["Invalid URI: #{current_uri}", 1600 + "Expected: #{uri}", 1601 + "PlugClean required."].join($/)] 1602 + else 1603 + if pull 1604 + log.call name, 'Updating ...', :update 1605 + fetch_opt = (tag && File.exist?(File.join(dir, '.git/shallow'))) ? '--depth 99999999' : '' 1606 + bt.call "#{cd} #{dir} && git fetch #{fetch_opt} #{progress} 2>&1 && git checkout -q #{checkout} 2>&1 && git merge --ff-only #{merge} 2>&1 && #{subm}", name, :update, nil 1607 + else 1608 + [true, skip] 1609 + end 1610 + end 1611 + else 1612 + d = esc dir.sub(%r{[\\/]+$}, '') 1613 + log.call name, 'Installing ...', :install 1614 + bt.call "git clone #{clone_opt unless tag} #{progress} --recursive #{uri} -b #{checkout} #{d} 2>&1", name, :install, proc { 1615 + FileUtils.rm_rf dir 1616 + } 1617 + end 1618 + mtx.synchronize { VIM::command("let s:update.new['#{name}'] = 1") } if !exists && ok 1619 + log.call name, result, ok 1620 + end 1621 + } if running 1622 + end 1623 + end 1624 + threads.each { |t| t.join rescue nil } 1625 + logh.call 1626 + refresh.kill if refresh 1627 + watcher.kill 1628 + EOF 1629 + endfunction 1630 + 1631 + function! s:shellesc(arg) 1632 + return '"'.escape(a:arg, '"').'"' 1633 + endfunction 1634 + 1635 + function! s:glob_dir(path) 1636 + return map(filter(s:lines(globpath(a:path, '**')), 'isdirectory(v:val)'), 's:dirpath(v:val)') 1637 + endfunction 1638 + 1639 + function! s:progress_bar(line, bar, total) 1640 + call setline(a:line, '[' . s:lpad(a:bar, a:total) . ']') 1641 + endfunction 1642 + 1643 + function! s:compare_git_uri(a, b) 1644 + let a = substitute(a:a, 'git:\{1,2}@', '', '') 1645 + let b = substitute(a:b, 'git:\{1,2}@', '', '') 1646 + return a ==# b 1647 + endfunction 1648 + 1649 + function! s:format_message(bullet, name, message) 1650 + if a:bullet != 'x' 1651 + return [printf('%s %s: %s', a:bullet, a:name, s:lastline(a:message))] 1652 + else 1653 + let lines = map(s:lines(a:message), '" ".v:val') 1654 + return extend([printf('x %s:', a:name)], lines) 1655 + endif 1656 + endfunction 1657 + 1658 + function! s:with_cd(cmd, dir) 1659 + return printf('cd%s %s && %s', s:is_win ? ' /d' : '', s:shellesc(a:dir), a:cmd) 1660 + endfunction 1661 + 1662 + function! s:system(cmd, ...) 1663 + try 1664 + let [sh, shrd] = [&shell, &shellredir] 1665 + if !s:is_win 1666 + set shell=sh shellredir=>%s\ 2>&1 1667 + endif 1668 + let cmd = a:0 > 0 ? s:with_cd(a:cmd, a:1) : a:cmd 1669 + return system(s:is_win ? '('.cmd.')' : cmd) 1670 + finally 1671 + let [&shell, &shellredir] = [sh, shrd] 1672 + endtry 1673 + endfunction 1674 + 1675 + function! s:system_chomp(...) 1676 + let ret = call('s:system', a:000) 1677 + return v:shell_error ? '' : substitute(ret, '\n$', '', '') 1678 + endfunction 1679 + 1680 + function! s:git_valid(spec, check_branch) 1681 + let ret = 1 1682 + let msg = 'OK' 1683 + if isdirectory(a:spec.dir) 1684 + let result = s:lines(s:system('git rev-parse --abbrev-ref HEAD 2>&1 && git config remote.origin.url', a:spec.dir)) 1685 + let remote = result[-1] 1686 + if v:shell_error 1687 + let msg = join([remote, 'PlugClean required.'], "\n") 1688 + let ret = 0 1689 + elseif !s:compare_git_uri(remote, a:spec.uri) 1690 + let msg = join(['Invalid URI: '.remote, 1691 + \ 'Expected: '.a:spec.uri, 1692 + \ 'PlugClean required.'], "\n") 1693 + let ret = 0 1694 + elseif a:check_branch 1695 + let branch = result[0] 1696 + " Check tag 1697 + if has_key(a:spec, 'tag') 1698 + let tag = s:system_chomp('git describe --exact-match --tags HEAD 2>&1', a:spec.dir) 1699 + if a:spec.tag !=# tag 1700 + let msg = printf('Invalid tag: %s (expected: %s). Try PlugUpdate.', 1701 + \ (empty(tag) ? 'N/A' : tag), a:spec.tag) 1702 + let ret = 0 1703 + endif 1704 + " Check branch 1705 + elseif a:spec.branch !=# branch 1706 + let msg = printf('Invalid branch: %s (expected: %s). Try PlugUpdate.', 1707 + \ branch, a:spec.branch) 1708 + let ret = 0 1709 + endif 1710 + endif 1711 + else 1712 + let msg = 'Not found' 1713 + let ret = 0 1714 + endif 1715 + return [ret, msg] 1716 + endfunction 1717 + 1718 + function! s:rm_rf(dir) 1719 + if isdirectory(a:dir) 1720 + call s:system((s:is_win ? 'rmdir /S /Q ' : 'rm -rf ') . s:shellesc(a:dir)) 1721 + endif 1722 + endfunction 1723 + 1724 + function! s:clean(force) 1725 + call s:prepare() 1726 + call append(0, 'Searching for unused plugins in '.g:plug_home) 1727 + call append(1, '') 1728 + 1729 + " List of valid directories 1730 + let dirs = [] 1731 + let [cnt, total] = [0, len(g:plugs)] 1732 + for [name, spec] in items(g:plugs) 1733 + if !s:is_managed(name) || s:git_valid(spec, 0)[0] 1734 + call add(dirs, spec.dir) 1735 + endif 1736 + let cnt += 1 1737 + call s:progress_bar(2, repeat('=', cnt), total) 1738 + normal! 2G 1739 + redraw 1740 + endfor 1741 + 1742 + let allowed = {} 1743 + for dir in dirs 1744 + let allowed[s:dirpath(fnamemodify(dir, ':h:h'))] = 1 1745 + let allowed[dir] = 1 1746 + for child in s:glob_dir(dir) 1747 + let allowed[child] = 1 1748 + endfor 1749 + endfor 1750 + 1751 + let todo = [] 1752 + let found = sort(s:glob_dir(g:plug_home)) 1753 + while !empty(found) 1754 + let f = remove(found, 0) 1755 + if !has_key(allowed, f) && isdirectory(f) 1756 + call add(todo, f) 1757 + call append(line('$'), '- ' . f) 1758 + let found = filter(found, 'stridx(v:val, f) != 0') 1759 + end 1760 + endwhile 1761 + 1762 + normal! G 1763 + redraw 1764 + if empty(todo) 1765 + call append(line('$'), 'Already clean.') 1766 + else 1767 + call inputsave() 1768 + let yes = a:force || (input('Proceed? (y/N) ') =~? '^y') 1769 + call inputrestore() 1770 + if yes 1771 + for dir in todo 1772 + call s:rm_rf(dir) 1773 + endfor 1774 + call append(line('$'), 'Removed.') 1775 + else 1776 + call append(line('$'), 'Cancelled.') 1777 + endif 1778 + endif 1779 + normal! G 1780 + endfunction 1781 + 1782 + function! s:upgrade() 1783 + echo 'Downloading the latest version of vim-plug' 1784 + redraw 1785 + let tmp = tempname() 1786 + let new = tmp . '/plug.vim' 1787 + 1788 + try 1789 + let out = s:system(printf('git clone --depth 1 %s %s', s:plug_src, tmp)) 1790 + if v:shell_error 1791 + return s:err('Error upgrading vim-plug: '. out) 1792 + endif 1793 + 1794 + if readfile(s:me) ==# readfile(new) 1795 + echo 'vim-plug is already up-to-date' 1796 + return 0 1797 + else 1798 + call rename(s:me, s:me . '.old') 1799 + call rename(new, s:me) 1800 + unlet g:loaded_plug 1801 + echo 'vim-plug has been upgraded' 1802 + return 1 1803 + endif 1804 + finally 1805 + silent! call s:rm_rf(tmp) 1806 + endtry 1807 + endfunction 1808 + 1809 + function! s:upgrade_specs() 1810 + for spec in values(g:plugs) 1811 + let spec.frozen = get(spec, 'frozen', 0) 1812 + endfor 1813 + endfunction 1814 + 1815 + function! s:status() 1816 + call s:prepare() 1817 + call append(0, 'Checking plugins') 1818 + call append(1, '') 1819 + 1820 + let ecnt = 0 1821 + let unloaded = 0 1822 + let [cnt, total] = [0, len(g:plugs)] 1823 + for [name, spec] in items(g:plugs) 1824 + if has_key(spec, 'uri') 1825 + if isdirectory(spec.dir) 1826 + let [valid, msg] = s:git_valid(spec, 1) 1827 + else 1828 + let [valid, msg] = [0, 'Not found. Try PlugInstall.'] 1829 + endif 1830 + else 1831 + if isdirectory(spec.dir) 1832 + let [valid, msg] = [1, 'OK'] 1833 + else 1834 + let [valid, msg] = [0, 'Not found.'] 1835 + endif 1836 + endif 1837 + let cnt += 1 1838 + let ecnt += !valid 1839 + " `s:loaded` entry can be missing if PlugUpgraded 1840 + if valid && get(s:loaded, name, -1) == 0 1841 + let unloaded = 1 1842 + let msg .= ' (not loaded)' 1843 + endif 1844 + call s:progress_bar(2, repeat('=', cnt), total) 1845 + call append(3, s:format_message(valid ? '-' : 'x', name, msg)) 1846 + normal! 2G 1847 + redraw 1848 + endfor 1849 + call setline(1, 'Finished. '.ecnt.' error(s).') 1850 + normal! gg 1851 + setlocal nomodifiable 1852 + if unloaded 1853 + echo "Press 'L' on each line to load plugin, or 'U' to update" 1854 + nnoremap <silent> <buffer> L :call <SID>status_load(line('.'))<cr> 1855 + xnoremap <silent> <buffer> L :call <SID>status_load(line('.'))<cr> 1856 + end 1857 + endfunction 1858 + 1859 + function! s:extract_name(str, prefix, suffix) 1860 + return matchstr(a:str, '^'.a:prefix.' \zs[^:]\+\ze:.*'.a:suffix.'$') 1861 + endfunction 1862 + 1863 + function! s:status_load(lnum) 1864 + let line = getline(a:lnum) 1865 + let name = s:extract_name(line, '-', '(not loaded)') 1866 + if !empty(name) 1867 + call plug#load(name) 1868 + setlocal modifiable 1869 + call setline(a:lnum, substitute(line, ' (not loaded)$', '', '')) 1870 + setlocal nomodifiable 1871 + endif 1872 + endfunction 1873 + 1874 + function! s:status_update() range 1875 + let lines = getline(a:firstline, a:lastline) 1876 + let names = filter(map(lines, 's:extract_name(v:val, "[x-]", "")'), '!empty(v:val)') 1877 + if !empty(names) 1878 + echo 1879 + execute 'PlugUpdate' join(names) 1880 + endif 1881 + endfunction 1882 + 1883 + function! s:is_preview_window_open() 1884 + silent! wincmd P 1885 + if &previewwindow 1886 + wincmd p 1887 + return 1 1888 + endif 1889 + return 0 1890 + endfunction 1891 + 1892 + function! s:find_name(lnum) 1893 + for lnum in reverse(range(1, a:lnum)) 1894 + let line = getline(lnum) 1895 + if empty(line) 1896 + return '' 1897 + endif 1898 + let name = s:extract_name(line, '-', '') 1899 + if !empty(name) 1900 + return name 1901 + endif 1902 + endfor 1903 + return '' 1904 + endfunction 1905 + 1906 + function! s:preview_commit() 1907 + if b:plug_preview < 0 1908 + let b:plug_preview = !s:is_preview_window_open() 1909 + endif 1910 + 1911 + let sha = matchstr(getline('.'), '\(^ \)\@<=[0-9a-z]\{7}') 1912 + if empty(sha) 1913 + return 1914 + endif 1915 + 1916 + let name = s:find_name(line('.')) 1917 + if empty(name) || !has_key(g:plugs, name) || !isdirectory(g:plugs[name].dir) 1918 + return 1919 + endif 1920 + 1921 + execute 'pedit' sha 1922 + wincmd P 1923 + setlocal filetype=git buftype=nofile nobuflisted modifiable 1924 + execute 'silent read !cd' s:shellesc(g:plugs[name].dir) '&& git show --pretty=medium' sha 1925 + normal! gg"_dd 1926 + setlocal nomodifiable 1927 + nnoremap <silent> <buffer> q :q<cr> 1928 + wincmd p 1929 + endfunction 1930 + 1931 + function! s:section(flags) 1932 + call search('\(^[x-] \)\@<=[^:]\+:', a:flags) 1933 + endfunction 1934 + 1935 + function! s:diff() 1936 + call s:prepare() 1937 + call append(0, 'Collecting updated changes ...') 1938 + normal! gg 1939 + redraw 1940 + 1941 + let cnt = 0 1942 + for [k, v] in items(g:plugs) 1943 + if !isdirectory(v.dir) || !s:is_managed(k) 1944 + continue 1945 + endif 1946 + 1947 + let diff = s:system_chomp('git log --pretty=format:"%h %s (%cr)" "HEAD...HEAD@{1}"', v.dir) 1948 + if !empty(diff) 1949 + call append(1, '') 1950 + call append(2, '- '.k.':') 1951 + call append(3, map(s:lines(diff), '" ". v:val')) 1952 + let cnt += 1 1953 + normal! gg 1954 + redraw 1955 + endif 1956 + endfor 1957 + 1958 + call setline(1, cnt == 0 ? 'No updates.' : 'Last update:') 1959 + nnoremap <silent> <buffer> <cr> :silent! call <SID>preview_commit()<cr> 1960 + nnoremap <silent> <buffer> o :silent! call <SID>preview_commit()<cr> 1961 + nnoremap <silent> <buffer> X :call <SID>revert()<cr> 1962 + normal! gg 1963 + setlocal nomodifiable 1964 + if cnt > 0 1965 + echo "Press 'X' on each block to revert the update" 1966 + endif 1967 + endfunction 1968 + 1969 + function! s:revert() 1970 + let name = s:find_name(line('.')) 1971 + if empty(name) || !has_key(g:plugs, name) || 1972 + \ input(printf('Revert the update of %s? (y/N) ', name)) !~? '^y' 1973 + return 1974 + endif 1975 + 1976 + call s:system('git reset --hard HEAD@{1} && git checkout '.s:esc(g:plugs[name].branch), g:plugs[name].dir) 1977 + setlocal modifiable 1978 + normal! "_dap 1979 + setlocal nomodifiable 1980 + echo 'Reverted.' 1981 + endfunction 1982 + 1983 + function! s:snapshot(...) abort 1984 + let home = get(s:, 'plug_home_org', g:plug_home) 1985 + let [type, var, header] = s:is_win ? 1986 + \ ['dosbatch', '%PLUG_HOME%', 1987 + \ ['@echo off', ':: Generated by vim-plug', ':: '.strftime("%c"), '', 1988 + \ ':: Make sure to PlugUpdate first', '', 'set PLUG_HOME='.home]] : 1989 + \ ['sh', '$PLUG_HOME', 1990 + \ ['#!/bin/sh', '# Generated by vim-plug', '# '.strftime("%c"), '', 1991 + \ 'vim +PlugUpdate +qa', '', 'PLUG_HOME='.s:esc(home)]] 1992 + 1993 + call s:prepare() 1994 + execute 'setf' type 1995 + call append(0, header) 1996 + call append('$', '') 1997 + 1 1998 + redraw 1999 + 2000 + let dirs = sort(map(values(filter(copy(g:plugs), 2001 + \'has_key(v:val, "uri") && isdirectory(v:val.dir)')), 'v:val.dir')) 2002 + let anchor = line('$') - 1 2003 + for dir in reverse(dirs) 2004 + let sha = s:system_chomp('git rev-parse --short HEAD', dir) 2005 + if !empty(sha) 2006 + call append(anchor, printf('cd %s && git reset --hard %s', 2007 + \ substitute(dir, '^\V'.escape(g:plug_home, '\'), var, ''), sha)) 2008 + redraw 2009 + endif 2010 + endfor 2011 + 2012 + if a:0 > 0 2013 + let fn = expand(a:1) 2014 + let fne = s:esc(fn) 2015 + call writefile(getline(1, '$'), fn) 2016 + if !s:is_win | call s:system('chmod +x ' . fne) | endif 2017 + echo 'Saved to '.a:1 2018 + silent execute 'e' fne 2019 + endif 2020 + endfunction 2021 + 2022 + function! s:split_rtp() 2023 + return split(&rtp, '\\\@<!,') 2024 + endfunction 2025 + 2026 + let s:first_rtp = s:escrtp(get(s:split_rtp(), 0, '')) 2027 + let s:last_rtp = s:escrtp(get(s:split_rtp(), -1, '')) 2028 + 2029 + if exists('g:plugs') 2030 + let g:plugs_order = get(g:, 'plugs_order', keys(g:plugs)) 2031 + call s:upgrade_specs() 2032 + call s:define_commands() 2033 + endif 2034 + 2035 + let &cpo = s:cpo_save 2036 + unlet s:cpo_save 2037 +
nvim/bundle/.keep

This is a binary file and will not be displayed.

+53 -3
nvim/init.vim
··· 1 1 " vim:foldmethod=marker:foldlevel=0:foldenable 2 2 3 - " Pathogen {{{ 4 - call pathogen#infect() 5 - call pathogen#helptags() 3 + " Plugins {{{ 4 + call plug#begin() 5 + 6 + Plug 'tpope/vim-sensible' 7 + 8 + " Visual 9 + Plug 'altercation/vim-colors-solarized' 10 + Plug 'bling/vim-bufferline' 11 + Plug 'itchyny/lightline.vim' 12 + Plug 'nathanaelkane/vim-indent-guides' 13 + 14 + " Languages 15 + Plug 'cespare/vim-toml' 16 + Plug 'dag/vim-fish' 17 + Plug 'ekalinin/Dockerfile.vim' 18 + Plug 'elixir-lang/vim-elixir' 19 + Plug 'rust-lang/rust.vim' 20 + 21 + " Git 22 + Plug 'airblade/vim-gitgutter' 23 + Plug 'gregsexton/gitv' 24 + Plug 'tpope/vim-fugitive' 25 + Plug 'tpope/vim-rhubarb' 26 + 27 + " Project management 28 + Plug 'Shougo/unite.vim' 29 + Plug 'tpope/vim-projectionist' 30 + Plug 'tpope/vim-vinegar' 31 + 32 + " TMux Integration 33 + Plug 'benmills/vimux' 34 + Plug 'christoomey/vim-tmux-navigator' 35 + 36 + " Completion 37 + Plug 'racer-rust/vim-racer', { 'for': 'rust' } 38 + Plug 'mattn/emmet-vim' 39 + Plug 'ervandew/supertab' 40 + 41 + " Code manipulation 42 + Plug 'tpope/vim-commentary' 43 + Plug 'Raimondi/delimitMate' 44 + Plug 'tpope/vim-surround' 45 + 46 + " Utils 47 + Plug 'godlygeek/tabular', { 'on': 'Tabularize' } 48 + Plug 'mbbill/undotree', { 'on': 'UndotreeToggle' } 49 + Plug 'mjbrownie/swapit' 50 + Plug 'scrooloose/syntastic' 51 + Plug 'terryma/vim-multiple-cursors' 52 + Plug 'tpope/vim-repeat' 53 + Plug 'tpope/vim-unimpaired' 54 + 55 + call plug#end() 6 56 " }}} 7 57 " Colors {{{ 8 58 " Show 80 column
-42
packages.json
··· 1 - { 2 - "bin": { 3 - "lein": { "type": "curl", "url": "https://raw.githubusercontent.com/technomancy/leiningen/stable/bin/lein", "build": "chmod +x $1" } 4 - }, 5 - "nvim/autoload": { 6 - "pathogen.vim": { "type": "curl", "url": "https://tpo.pe/pathogen.vim" } 7 - }, 8 - "nvim/bundle": { 9 - "bufferline": { "type": "git", "url": "https://github.com/bling/vim-bufferline.git" }, 10 - "commentary": { "type": "git", "url": "https://github.com/tpope/vim-commentary.git" }, 11 - "delimmate": { "type": "git", "url": "https://github.com/Raimondi/delimitMate.git" }, 12 - "docker": { "type": "git", "url": "https://github.com/ekalinin/Dockerfile.vim.git" }, 13 - "elixir": { "type": "git", "url": "https://github.com/elixir-lang/vim-elixir.git" }, 14 - "emmet": { "type": "git", "url": "https://github.com/mattn/emmet-vim.git" }, 15 - "fish": { "type": "git", "url": "https://github.com/dag/vim-fish.git" }, 16 - "fugitive": { "type": "git", "url": "https://github.com/tpope/vim-fugitive.git" }, 17 - "gitgutter": { "type": "git", "url": "https://github.com/airblade/vim-gitgutter.git" }, 18 - "gitv": { "type": "git", "url": "https://github.com/gregsexton/gitv.git" }, 19 - "indent-guides": { "type": "git", "url": "https://github.com/nathanaelkane/vim-indent-guides.git" }, 20 - "lightline": { "type": "git", "url": "https://github.com/itchyny/lightline.vim.git" }, 21 - "multiple-cursors": { "type": "git", "url": "https://github.com/terryma/vim-multiple-cursors.git" }, 22 - "projectionist": { "type": "git", "url": "https://github.com/tpope/vim-projectionist.git" }, 23 - "racer": { "type": "git", "url": "https://github.com/racer-rust/vim-racer.git" }, 24 - "repeat": { "type": "git", "url": "https://github.com/tpope/vim-repeat.git" }, 25 - "rhubarb": { "type": "git", "url": "https://github.com/tpope/vim-rhubarb.git" }, 26 - "rust": { "type": "git", "url": "https://github.com/rust-lang/rust.vim.git" }, 27 - "sensible": { "type": "git", "url": "https://github.com/tpope/vim-sensible.git" }, 28 - "solarized": { "type": "git", "url": "https://github.com/altercation/vim-colors-solarized.git" }, 29 - "supertab": { "type": "git", "url": "https://github.com/ervandew/supertab.git" }, 30 - "surround": { "type": "git", "url": "https://github.com/tpope/vim-surround.git" }, 31 - "swapit": { "type": "git", "url": "https://github.com/mjbrownie/swapit.git" }, 32 - "syntastic": { "type": "git", "url": "https://github.com/scrooloose/syntastic.git" }, 33 - "tabular": { "type": "git", "url": "https://github.com/godlygeek/tabular.git" }, 34 - "tmux-navigator": { "type": "git", "url": "https://github.com/christoomey/vim-tmux-navigator.git" }, 35 - "toml": { "type": "git", "url": "https://github.com/cespare/vim-toml.git" }, 36 - "undotree": { "type": "git", "url": "https://github.com/mbbill/undotree.git" }, 37 - "unimpaired": { "type": "git", "url": "https://github.com/tpope/vim-unimpaired.git" }, 38 - "unite": { "type": "git", "url": "https://github.com/Shougo/unite.vim.git" }, 39 - "vimux": { "type": "git", "url": "https://github.com/benmills/vimux.git" }, 40 - "vinegar": { "type": "git", "url": "https://github.com/tpope/vim-vinegar.git" } 41 - } 42 - }