@ -22,10 +22,10 @@
" Plug 'SirVer/ultisnips' | Plug 'honza/vim-snippets'
" Plug 'SirVer/ultisnips' | Plug 'honza/vim-snippets'
"
"
" " On-demand loading
" " On-demand loading
" Plug ' preservim/nerdtree', { 'on': 'NERDTreeToggle' }
" Plug ' scrooloose/nerdtree', { 'on': 'NERDTreeToggle' }
" Plug 'tpope/vim-fireplace', { 'for': 'clojure' }
" Plug 'tpope/vim-fireplace', { 'for': 'clojure' }
"
"
" " Using a non- default branch
" " Using a non- master branch
" Plug 'rdnetto/YCM-Generator', { 'branch': 'stable' }
" Plug 'rdnetto/YCM-Generator', { 'branch': 'stable' }
"
"
" " Using a tagged release; wildcard allowed (requires git 1.9.2 or above)
" " Using a tagged release; wildcard allowed (requires git 1.9.2 or above)
@ -106,7 +106,7 @@ if s:is_win && &shellslash
else
else
let s :me = resolve ( expand ( '<sfile>:p' ) )
let s :me = resolve ( expand ( '<sfile>:p' ) )
endif
endif
let s :base_spec = { 'branch' : ' ', 'frozen' : 0 }
let s :base_spec = { 'branch' : ' master ', 'frozen' : 0 }
let s :TYPE = {
let s :TYPE = {
\ 'string' : type ( '' ) ,
\ 'string' : type ( '' ) ,
\ 'list' : type ( []) ,
\ 'list' : type ( []) ,
@ -116,94 +116,6 @@ let s:TYPE = {
let s :loaded = get ( s :, 'loaded' , {})
let s :loaded = get ( s :, 'loaded' , {})
let s :triggers = get ( s :, 'triggers' , {})
let s :triggers = get ( s :, 'triggers' , {})
function ! s :is_powershell ( shell )
return a :shell = ~ # 'powershell\(\.exe\)\?$' | | a :shell = ~ # 'pwsh\(\.exe\)\?$'
endfunction
function ! s :isabsolute ( dir ) abort
return a :dir = ~ # '^/' | | ( has ( 'win32' ) && a :dir = ~ ? '^\%(\\\|[A-Z]:\)' )
endfunction
function ! s :git_dir ( dir ) abort
let gitdir = s :trim ( a :dir ) . '/.git'
if isdirectory ( gitdir )
return gitdir
endif
if ! filereadable ( gitdir )
return ''
endif
let gitdir = matchstr ( get ( readfile ( gitdir ) , 0 , '' ) , '^gitdir: \zs.*' )
if len ( gitdir ) && ! s :isabsolute ( gitdir )
let gitdir = a :dir . '/' . gitdir
endif
return isdirectory ( gitdir ) ? gitdir : ''
endfunction
function ! s :git_origin_url ( dir ) abort
let gitdir = s :git_dir ( a :dir )
let config = gitdir . '/config'
if empty ( gitdir ) | | ! filereadable ( config )
return ''
endif
return matchstr ( join ( readfile ( config ) ) , '\[remote "origin"\].\{-}url\s*=\s*\zs\S*\ze' )
endfunction
function ! s :git_revision ( dir ) abort
let gitdir = s :git_dir ( a :dir )
let head = gitdir . '/HEAD'
if empty ( gitdir ) | | ! filereadable ( head )
return ''
endif
let line = get ( readfile ( head ) , 0 , '' )
let ref = matchstr ( line , '^ref: \zs.*' )
if empty ( ref )
return line
endif
if filereadable ( gitdir . '/' . ref )
return get ( readfile ( gitdir . '/' . ref ) , 0 , '' )
endif
if filereadable ( gitdir . '/packed-refs' )
for line in readfile ( gitdir . '/packed-refs' )
if line = ~ # ' ' . ref
return matchstr ( line , '^[0-9a-f]*' )
endif
endfor
endif
return ''
endfunction
function ! s :git_local_branch ( dir ) abort
let gitdir = s :git_dir ( a :dir )
let head = gitdir . '/HEAD'
if empty ( gitdir ) | | ! filereadable ( head )
return ''
endif
let branch = matchstr ( get ( readfile ( head ) , 0 , '' ) , '^ref: refs/heads/\zs.*' )
return len ( branch ) ? branch : 'HEAD'
endfunction
function ! s :git_origin_branch ( spec )
if len ( a :spec .branch )
return a :spec .branch
endif
" The file may not be present if this is a local repository
let gitdir = s :git_dir ( a :spec .dir )
let origin_head = gitdir .'/refs/remotes/origin/HEAD'
if len ( gitdir ) && filereadable ( origin_head )
return matchstr ( get ( readfile ( origin_head ) , 0 , '' ) ,
\ '^ref: refs/remotes/origin/\zs.*' )
endif
" The command may not return the name of a branch in detached HEAD state
let result = s :lines ( s :system ( 'git symbolic-ref --short HEAD' , a :spec .dir ) )
return v :shell_error ? '' : result [-1 ]
endfunction
if s :is_win
if s :is_win
function ! s :plug_call ( fn , ...)
function ! s :plug_call ( fn , ...)
let shellslash = &shellslash
let shellslash = &shellslash
@ -242,8 +154,6 @@ function! plug#begin(...)
let home = s :path ( s :plug_fnamemodify ( s :plug_expand ( a :1 ) , ':p' ) )
let home = s :path ( s :plug_fnamemodify ( s :plug_expand ( a :1 ) , ':p' ) )
elseif exists ( 'g:plug_home' )
elseif exists ( 'g:plug_home' )
let home = s :path ( g :plug_home )
let home = s :path ( g :plug_home )
elseif has ( 'nvim' )
let home = stdpath ( 'data' ) . '/plugged'
elseif ! empty ( &rtp )
elseif ! empty ( &rtp )
let home = s :path ( split ( &rtp , ',' ) [0 ]) . '/plugged'
let home = s :path ( split ( &rtp , ',' ) [0 ]) . '/plugged'
else
else
@ -269,7 +179,7 @@ function! s:define_commands()
endif
endif
if has ( 'win32' )
if has ( 'win32' )
\ && &shellslash
\ && &shellslash
\ && ( &shell = ~ # 'cmd\ (\.exe\)\?$' | | s :is_powershell ( &shell ) )
\ && ( &shell = ~ # 'cmd\ .exe' | | &shell = ~ # 'powershell\.exe' )
return s :err ( 'vim-plug does not support shell, ' . &shell . ', when shellslash is set.' )
return s :err ( 'vim-plug does not support shell, ' . &shell . ', when shellslash is set.' )
endif
endif
if ! has ( 'nvim' )
if ! has ( 'nvim' )
@ -352,7 +262,7 @@ function! plug#end()
endif
endif
let lod = { 'ft' : {}, 'map' : {}, 'cmd' : {} }
let lod = { 'ft' : {}, 'map' : {}, 'cmd' : {} }
if g et( g :, ' did_load_filetypes', 0 )
if exis ts ( ' g: did_load_filetypes')
filetype off
filetype off
endif
endif
for name in g :plugs_order
for name in g :plugs_order
@ -407,7 +317,7 @@ function! plug#end()
for [map , names ] in items ( lod .map )
for [map , names ] in items ( lod .map )
for [mode , map_prefix , key_prefix ] in
for [mode , map_prefix , key_prefix ] in
\ [['i' , '<C- \><C- O>', '' ], ['n' , '' , '' ], ['v' , '' , 'gv' ], ['o' , '' , '' ]]
\ [['i' , '<C- O>', '' ], ['n' , '' , '' ], ['v' , '' , 'gv' ], ['o' , '' , '' ]]
execute printf (
execute printf (
\ '%snoremap <silent> %s %s:<C-U>call <SID>lod_map(%s, %s, %s, "%s")<CR>' ,
\ '%snoremap <silent> %s %s:<C-U>call <SID>lod_map(%s, %s, %s, "%s")<CR>' ,
\ mode , map , map_prefix , string ( map ) , string ( names ) , mode ! = 'i' , key_prefix )
\ mode , map , map_prefix , string ( map ) , string ( names ) , mode ! = 'i' , key_prefix )
@ -462,7 +372,7 @@ endfunction
function ! s :git_version_requirement ( ...)
function ! s :git_version_requirement ( ...)
if ! exists ( 's:git_version' )
if ! exists ( 's:git_version' )
let s :git_version = map ( split ( split ( s :system ( [ 'git ', ' --version'] ) ) [2 ], '\.' ) , 'str2nr(v:val)' )
let s :git_version = map ( split ( split ( s :system ( 'git --version') ) [2 ], '\.' ) , 'str2nr(v:val)' )
endif
endif
return s :version_requirement ( s :git_version , a :000 )
return s :version_requirement ( s :git_version , a :000 )
endfunction
endfunction
@ -509,7 +419,7 @@ if s:is_win
let batchfile = s :plug_tempname ( ) .'.bat'
let batchfile = s :plug_tempname ( ) .'.bat'
call writefile ( s :wrap_cmds ( a :cmd ) , batchfile )
call writefile ( s :wrap_cmds ( a :cmd ) , batchfile )
let cmd = plug #shellescape ( batchfile , {'shell' : &shell , 'script' : 0 })
let cmd = plug #shellescape ( batchfile , {'shell' : &shell , 'script' : 0 })
if s :is_powershell ( &shell )
if &shell = ~ # 'powershell\.exe'
let cmd = '& ' . cmd
let cmd = '& ' . cmd
endif
endif
return [batchfile , cmd ]
return [batchfile , cmd ]
@ -722,38 +632,16 @@ function! plug#(repo, ...)
let g :plugs [name ] = spec
let g :plugs [name ] = spec
let s :loaded [name ] = get ( s :loaded , name , 0 )
let s :loaded [name ] = get ( s :loaded , name , 0 )
catch
catch
return s :err ( repo . ' ' . v:exception )
return s :err ( v:exception )
endtry
endtry
endfunction
endfunction
function ! s :parse_options ( arg )
function ! s :parse_options ( arg )
let opts = copy ( s :base_spec )
let opts = copy ( s :base_spec )
let type = type ( a :arg )
let type = type ( a :arg )
let opt_errfmt = 'Invalid argument for "%s" option of :Plug (expected: %s)'
if type = = s :TYPE .string
if type = = s :TYPE .string
if empty ( a :arg )
throw printf ( opt_errfmt , 'tag' , 'string' )
endif
let opts .tag = a :arg
let opts .tag = a :arg
elseif type = = s :TYPE .dict
elseif type = = s :TYPE .dict
for opt in ['branch' , 'tag' , 'commit' , 'rtp' , 'dir' , 'as' ]
if has_key ( a :arg , opt )
\ && ( type ( a :arg [opt ]) ! = s :TYPE .string | | empty ( a :arg [opt ]) )
throw printf ( opt_errfmt , opt , 'string' )
endif
endfor
for opt in ['on' , 'for' ]
if has_key ( a :arg , opt )
\ && type ( a :arg [opt ]) ! = s :TYPE .list
\ && ( type ( a :arg [opt ]) ! = s :TYPE .string | | empty ( a :arg [opt ]) )
throw printf ( opt_errfmt , opt , 'string or list' )
endif
endfor
if has_key ( a :arg , 'do' )
\ && type ( a :arg .do ) ! = s :TYPE .funcref
\ && ( type ( a :arg .do ) ! = s :TYPE .string | | empty ( a :arg .do ) )
throw printf ( opt_errfmt , 'do' , 'string or funcref' )
endif
call extend ( opts , a :arg )
call extend ( opts , a :arg )
if has_key ( opts , 'dir' )
if has_key ( opts , 'dir' )
let opts .dir = s :dirpath ( s :plug_expand ( opts .dir ) )
let opts .dir = s :dirpath ( s :plug_expand ( opts .dir ) )
@ -810,7 +698,7 @@ function! s:syntax()
syn match plugNumber /[0-9]\+[0-9.]*/ contained
syn match plugNumber /[0-9]\+[0-9.]*/ contained
syn match plugBracket /[[\]]/ contained
syn match plugBracket /[[\]]/ contained
syn match plugX /x/ contained
syn match plugX /x/ contained
syn match plugDash /^- \{1}\ /
syn match plugDash /^- /
syn match plugPlus /^+/
syn match plugPlus /^+/
syn match plugStar /^*/
syn match plugStar /^*/
syn match plugMessage /\(^- \)\@<=.*/
syn match plugMessage /\(^- \)\@<=.*/
@ -828,7 +716,6 @@ function! s:syntax()
syn match plugError /^x.*/
syn match plugError /^x.*/
syn region plugDeleted start = /^\~ .*/ end = /^\ze\S/
syn region plugDeleted start = /^\~ .*/ end = /^\ze\S/
syn match plugH2 /^.*:\n-\+$/
syn match plugH2 /^.*:\n-\+$/
syn match plugH2 /^-\{2,}/
syn keyword Function PlugInstall PlugStatus PlugUpdate PlugClean
syn keyword Function PlugInstall PlugStatus PlugUpdate PlugClean
hi def link plug1 Title
hi def link plug1 Title
hi def link plug2 Repeat
hi def link plug2 Repeat
@ -941,7 +828,7 @@ function! s:prepare(...)
call s :new_window ( )
call s :new_window ( )
endif
endif
nnoremap < silent > < buffer > q :call < SID > close_pane ( ) < cr >
nnoremap < silent > < buffer > q :if b :plug_preview = = 1 < bar > pc < bar > endif < bar > bd < cr >
if a :0 = = 0
if a :0 = = 0
call s :finish_bindings ( )
call s :finish_bindings ( )
endif
endif
@ -963,15 +850,6 @@ function! s:prepare(...)
endif
endif
endfunction
endfunction
function ! s :close_pane ( )
if b :plug_preview = = 1
pc
let b :plug_preview = -1
else
bd
endif
endfunction
function ! s :assign_name ( )
function ! s :assign_name ( )
" Assign buffer name
" Assign buffer name
let prefix = '[Plugins]'
let prefix = '[Plugins]'
@ -986,15 +864,8 @@ endfunction
function ! s :chsh ( swap )
function ! s :chsh ( swap )
let prev = [&shell , &shellcmdflag , &shellredir ]
let prev = [&shell , &shellcmdflag , &shellredir ]
if ! s :is_win
if ! s :is_win && a :swap
set shell = sh
set shell = sh shellredir = > %s \ 2 > &1
endif
if a :swap
if s :is_powershell ( &shell )
let &shellredir = '2>&1 | Out-File -Encoding UTF8 %s'
elseif &shell = ~ # 'sh' | | &shell = ~ # 'cmd\(\.exe\)\?$'
set shellredir = > %s \ 2 > &1
endif
endif
endif
return prev
return prev
endfunction
endfunction
@ -1027,7 +898,7 @@ function! s:regress_bar()
endfunction
endfunction
function ! s :is_updated ( dir )
function ! s :is_updated ( dir )
return ! empty ( s :system_chomp ( ['git' , 'log' , '--pretty=format:%h' , 'HEAD...HEAD@{1}' ] , a :dir ) )
return ! empty ( s :system_chomp ( 'git log --pretty=format:"%h" "HEAD...HEAD@{1}"' , a :dir ) )
endfunction
endfunction
function ! s :do ( pull , force , todo )
function ! s :do ( pull , force , todo )
@ -1064,7 +935,6 @@ function! s:do(pull, force, todo)
endif
endif
elseif type = = s :TYPE .funcref
elseif type = = s :TYPE .funcref
try
try
call s :load_plugin ( spec )
let status = installed ? 'installed' : ( updated ? 'updated' : 'unchanged' )
let status = installed ? 'installed' : ( updated ? 'updated' : 'unchanged' )
call spec .do ( { 'name' : name , 'status' : status , 'force' : a :force })
call spec .do ( { 'name' : name , 'status' : status , 'force' : a :force })
catch
catch
@ -1091,11 +961,10 @@ endfunction
function ! s :checkout ( spec )
function ! s :checkout ( spec )
let sha = a :spec .commit
let sha = a :spec .commit
let output = s :git_revision ( a :spec .dir )
let output = s :system ( 'git rev-parse HEAD' , a :spec .dir )
if ! empty ( output ) && ! s :hash_match ( sha , s :lines ( output ) [0 ])
if ! v :shell_error && ! s :hash_match ( sha , s :lines ( output ) [0 ])
let credential_helper = s :git_version_requirement ( 2 ) ? '-c credential.helper= ' : ''
let output = s :system (
let output = s :system (
\ 'git '.credential_helper .' fetch --depth 999999 && git checkout '.plug #shellescape ( sha ) .' --' , a :spec .dir )
\ 'git fetch --depth 999999 && git checkout '.plug #shellescape ( sha ) .' --' , a :spec .dir )
endif
endif
return output
return output
endfunction
endfunction
@ -1210,17 +1079,11 @@ function! s:update_impl(pull, force, args) abort
normal ! 2 G
normal ! 2 G
silent ! redraw
silent ! redraw
" Set remote name, overriding a possible user git config's clone.defaultRemoteName
let s :clone_opt = get ( g :, 'plug_shallow' , 1 ) ?
let s :clone_opt = ['--origin' , 'origin' ]
\ '--depth 1' . ( s :git_version_requirement ( 1 , 7 , 10 ) ? ' --no-single-branch' : '' ) : ''
if get ( g :, 'plug_shallow' , 1 )
call extend ( s :clone_opt , ['--depth' , '1' ])
if s :git_version_requirement ( 1 , 7 , 10 )
call add ( s :clone_opt , '--no-single-branch' )
endif
endif
if has ( 'win32unix' ) | | has ( 'wsl' )
if has ( 'win32unix' ) | | has ( 'wsl' )
call extend ( s :clone_opt , ['-c' , 'core.eol=lf' , '-c' , 'core.autocrlf=input' ])
let s :clone_opt .= ' -c core.eol=lf -c core.autocrlf=input'
endif
endif
let s :submodule_opt = s :git_version_requirement ( 2 , 8 ) ? ' --jobs=' .threads : ''
let s :submodule_opt = s :git_version_requirement ( 2 , 8 ) ? ' --jobs=' .threads : ''
@ -1308,7 +1171,7 @@ function! s:update_finish()
call s :log4 ( name , 'Checking out ' .tag )
call s :log4 ( name , 'Checking out ' .tag )
let out = s :system ( 'git checkout -q ' .plug #shellescape ( tag ) .' -- 2>&1' , spec .dir )
let out = s :system ( 'git checkout -q ' .plug #shellescape ( tag ) .' -- 2>&1' , spec .dir )
else
else
let branch = s:git_origin_branch ( spec )
let branch = get( spec , 'branch' , 'master' )
call s :log4 ( name , 'Merging origin/' .s :esc ( branch ) )
call s :log4 ( name , 'Merging origin/' .s :esc ( branch ) )
let out = s :system ( 'git checkout -q ' .plug #shellescape ( branch ) .' -- 2>&1'
let out = s :system ( 'git checkout -q ' .plug #shellescape ( branch ) .' -- 2>&1'
\. ( has_key ( s :update .new , name ) ? '' : ( '&& git merge --ff-only ' .plug #shellescape ( 'origin/' .branch ) .' 2>&1' ) ) , spec .dir )
\. ( has_key ( s :update .new , name ) ? '' : ( '&& git merge --ff-only ' .plug #shellescape ( 'origin/' .branch ) .' 2>&1' ) ) , spec .dir )
@ -1401,7 +1264,7 @@ function! s:job_cb(fn, job, ch, data)
endfunction
endfunction
function ! s :nvim_cb ( job_id , data , event ) dict abort
function ! s :nvim_cb ( job_id , data , event ) dict abort
return ( a :event = = 'stdout' | | a :event = = 'stderr' ) ?
return a :event = = 'stdout' ?
\ s :job_cb ( 's:job_out_cb' , self , 0 , join ( a :data , "\n" ) ) :
\ s :job_cb ( 's:job_out_cb' , self , 0 , join ( a :data , "\n" ) ) :
\ s :job_cb ( 's:job_exit_cb' , self , 0 , a :data )
\ s :job_cb ( 's:job_exit_cb' , self , 0 , a :data )
endfunction
endfunction
@ -1410,15 +1273,12 @@ function! s:spawn(name, cmd, opts)
let job = { 'name' : a :name , 'running' : 1 , 'error' : 0 , 'lines' : ['' ],
let job = { 'name' : a :name , 'running' : 1 , 'error' : 0 , 'lines' : ['' ],
\ 'new' : get ( a :opts , 'new' , 0 ) }
\ 'new' : get ( a :opts , 'new' , 0 ) }
let s :jobs [a :name ] = job
let s :jobs [a :name ] = job
let cmd = has_key ( a :opts , 'dir' ) ? s :with_cd ( a :cmd , a :opts .dir , 0 ) : a :cmd
let argv = s :is_win ? ['cmd' , '/s' , '/c' , '"' .cmd .'"' ] : ['sh' , '-c' , cmd ]
if s :nvim
if s :nvim
if has_key ( a :opts , 'dir' )
let job .cwd = a :opts .dir
endif
let argv = a :cmd
call extend ( job , {
call extend ( job , {
\ 'on_stdout' : function ( 's:nvim_cb' ) ,
\ 'on_stdout' : function ( 's:nvim_cb' ) ,
\ 'on_stderr' : function ( 's:nvim_cb' ) ,
\ 'on_exit' : function ( 's:nvim_cb' ) ,
\ 'on_exit' : function ( 's:nvim_cb' ) ,
\ })
\ })
let jid = s :plug_call ( 'jobstart' , argv , job )
let jid = s :plug_call ( 'jobstart' , argv , job )
@ -1431,16 +1291,9 @@ function! s:spawn(name, cmd, opts)
\ 'Invalid arguments (or job table is full)' ]
\ 'Invalid arguments (or job table is full)' ]
endif
endif
elseif s :vim8
elseif s :vim8
let cmd = join ( map ( copy ( a :cmd ) , 'plug#shellescape(v:val, {"script": 0})' ) )
if has_key ( a :opts , 'dir' )
let cmd = s :with_cd ( cmd , a :opts .dir , 0 )
endif
let argv = s :is_win ? ['cmd' , '/s' , '/c' , '"' .cmd .'"' ] : ['sh' , '-c' , cmd ]
let jid = job_start ( s :is_win ? join ( argv , ' ' ) : argv , {
let jid = job_start ( s :is_win ? join ( argv , ' ' ) : argv , {
\ 'out_cb' : function ( 's:job_cb' , ['s:job_out_cb' , job ]) ,
\ 'out_cb' : function ( 's:job_cb' , ['s:job_out_cb' , job ]) ,
\ 'err_cb' : function ( 's:job_cb' , ['s:job_out_cb' , job ]) ,
\ 'exit_cb' : function ( 's:job_cb' , ['s:job_exit_cb' , job ]) ,
\ 'exit_cb' : function ( 's:job_cb' , ['s:job_exit_cb' , job ]) ,
\ 'err_mode' : 'raw' ,
\ 'out_mode' : 'raw'
\ 'out_mode' : 'raw'
\})
\})
if job_status ( jid ) = = 'run'
if job_status ( jid ) = = 'run'
@ -1451,7 +1304,7 @@ function! s:spawn(name, cmd, opts)
let job .lines = ['Failed to start job' ]
let job .lines = ['Failed to start job' ]
endif
endif
else
else
let job .lines = s :lines ( call ( 's:system' , has_key ( a :opts , 'dir' ) ? [a :cmd , a :opts .dir ] : [a :cmd ]) )
let job .lines = s :lines ( call ( 's:system' , [cmd ]) )
let job .error = v :shell_error ! = 0
let job .error = v :shell_error ! = 0
let job .running = 0
let job .running = 0
endif
endif
@ -1548,14 +1401,8 @@ while 1 " Without TCO, Vim stack is bound to explode
let [error , _ ] = s :git_validate ( spec , 0 )
let [error , _ ] = s :git_validate ( spec , 0 )
if empty ( error )
if empty ( error )
if pull
if pull
let cmd = s :git_version_requirement ( 2 ) ? ['git' , '-c' , 'credential.helper=' , 'fetch' ] : ['git' , 'fetch' ]
let fetch_opt = ( has_tag && ! empty ( globpath ( spec .dir , '.git/shallow' ) ) ) ? '--depth 99999999' : ''
if has_tag && ! empty ( globpath ( spec .dir , '.git/shallow' ) )
call s :spawn ( name , printf ( 'git fetch %s %s 2>&1' , fetch_opt , prog ) , { 'dir' : spec .dir })
call extend ( cmd , ['--depth' , '99999999' ])
endif
if ! empty ( prog )
call add ( cmd , prog )
endif
call s :spawn ( name , cmd , { 'dir' : spec .dir })
else
else
let s :jobs [name ] = { 'running' : 0 , 'lines' : ['Already installed' ], 'error' : 0 }
let s :jobs [name ] = { 'running' : 0 , 'lines' : ['Already installed' ], 'error' : 0 }
endif
endif
@ -1563,14 +1410,12 @@ while 1 " Without TCO, Vim stack is bound to explode
let s :jobs [name ] = { 'running' : 0 , 'lines' : s :lines ( error ) , 'error' : 1 }
let s :jobs [name ] = { 'running' : 0 , 'lines' : s :lines ( error ) , 'error' : 1 }
endif
endif
else
else
let cmd = ['git' , 'clone' ]
call s :spawn ( name ,
if ! has_tag
\ printf ( 'git clone %s %s %s %s 2>&1' ,
call extend ( cmd , s :clone_opt )
\ has_tag ? '' : s :clone_opt ,
endif
\ prog ,
if ! empty ( prog )
\ plug #shellescape ( spec .uri , {'script' : 0 }) ,
call add ( cmd , prog )
\ plug #shellescape ( s :trim ( spec .dir ) , {'script' : 0 }) ) , { 'new' : 1 })
endif
call s :spawn ( name , extend ( cmd , [spec .uri , s :trim ( spec .dir ) ]) , { 'new' : 1 })
endif
endif
if ! s :jobs [name ].running
if ! s :jobs [name ].running
@ -1607,7 +1452,7 @@ G_NVIM = vim.eval("has('nvim')") == '1'
G_PULL = vim .eval ( 's:update.pull' ) = = '1'
G_PULL = vim .eval ( 's:update.pull' ) = = '1'
G_RETRIES = int ( vim .eval ( 'get(g:, "plug_retries", 2)' ) ) + 1
G_RETRIES = int ( vim .eval ( 'get(g:, "plug_retries", 2)' ) ) + 1
G_TIMEOUT = int ( vim .eval ( 'get(g:, "plug_timeout", 60)' ) )
G_TIMEOUT = int ( vim .eval ( 'get(g:, "plug_timeout", 60)' ) )
G_CLONE_OPT = ' ' .join ( vim .eval ( 's:clone_opt' ) )
G_CLONE_OPT = vim .eval ( 's:clone_opt' )
G_PROGRESS = vim .eval ( 's:progress_opt(1)' )
G_PROGRESS = vim .eval ( 's:progress_opt(1)' )
G_LOG_PROB = 1 .0 / int ( vim .eval ( 's:update.threads' ) )
G_LOG_PROB = 1 .0 / int ( vim .eval ( 's:update.threads' ) )
G_STOP = thr .Event ( )
G_STOP = thr .Event ( )
@ -2144,7 +1989,7 @@ function! s:update_ruby()
end
end
} if VIM ::evaluate ( 's:mac_gui' ) = = 1
} if VIM ::evaluate ( 's:mac_gui' ) = = 1
clone_opt = VIM ::evaluate ( 's:clone_opt' ) .join ( ' ' )
clone_opt = VIM ::evaluate ( 's:clone_opt' )
progress = VIM ::evaluate ( 's:progress_opt(1)' )
progress = VIM ::evaluate ( 's:progress_opt(1)' )
nthr .times do
nthr .times do
mtx .synchronize do
mtx .synchronize do
@ -2210,29 +2055,13 @@ function! s:shellesc_sh(arg)
return "'" .substitute ( a :arg , "'" , "'\\\\''" , 'g' ) ."'"
return "'" .substitute ( a :arg , "'" , "'\\\\''" , 'g' ) ."'"
endfunction
endfunction
" Escape the shell argument based on the shell.
" Vim and Neovim's shellescape() are insufficient.
" 1. shellslash determines whether to use single/double quotes.
" Double-quote escaping is fragile for cmd.exe.
" 2. It does not work for powershell.
" 3. It does not work for *sh shells if the command is executed
" via cmd.exe (ie. cmd.exe /c sh -c command command_args)
" 4. It does not support batchfile syntax.
"
" Accepts an optional dictionary with the following keys:
" - shell: same as Vim/Neovim 'shell' option.
" If unset, fallback to 'cmd.exe' on Windows or 'sh'.
" - script: If truthy and shell is cmd.exe, escape for batchfile syntax.
function ! plug #shellescape ( arg , ...)
function ! plug #shellescape ( arg , ...)
if a :arg = ~ # '^[A-Za-z0-9_/:.-]\+$'
return a :arg
endif
let opts = a :0 > 0 && type ( a :1 ) = = s :TYPE .dict ? a :1 : {}
let opts = a :0 > 0 && type ( a :1 ) = = s :TYPE .dict ? a :1 : {}
let shell = get ( opts , 'shell' , s :is_win ? 'cmd.exe' : 'sh' )
let shell = get ( opts , 'shell' , s :is_win ? 'cmd.exe' : 'sh' )
let script = get ( opts , 'script' , 1 )
let script = get ( opts , 'script' , 1 )
if shell = ~ # 'cmd\ (\ .exe\)\?$ '
if shell = ~ # 'cmd\.exe'
return s :shellesc_cmd ( a :arg , script )
return s :shellesc_cmd ( a :arg , script )
elseif s :is_powershell ( shell )
elseif shell = ~ # 'powershell\.exe' | | shell = ~ # 'pwsh$'
return s :shellesc_ps1 ( a :arg )
return s :shellesc_ps1 ( a :arg )
endif
endif
return s :shellesc_sh ( a :arg )
return s :shellesc_sh ( a :arg )
@ -2276,24 +2105,8 @@ function! s:system(cmd, ...)
let batchfile = ''
let batchfile = ''
try
try
let [sh , shellcmdflag , shrd ] = s :chsh ( 1 )
let [sh , shellcmdflag , shrd ] = s :chsh ( 1 )
if type ( a :cmd ) = = s :TYPE .list
let cmd = a :0 > 0 ? s :with_cd ( a :cmd , a :1 ) : a :cmd
" Neovim's system() supports list argument to bypass the shell
if s :is_win
" but it cannot set the working directory for the command.
" Assume that the command does not rely on the shell.
if has ( 'nvim' ) && a :0 = = 0
return system ( a :cmd )
endif
let cmd = join ( map ( copy ( a :cmd ) , 'plug#shellescape(v:val, {"shell": &shell, "script": 0})' ) )
if s :is_powershell ( &shell )
let cmd = '& ' . cmd
endif
else
let cmd = a :cmd
endif
if a :0 > 0
let cmd = s :with_cd ( cmd , a :1 , type ( a :cmd ) ! = s :TYPE .list )
endif
if s :is_win && type ( a :cmd ) ! = s :TYPE .list
let [batchfile , cmd ] = s :batchfile ( cmd )
let [batchfile , cmd ] = s :batchfile ( cmd )
endif
endif
return system ( cmd )
return system ( cmd )
@ -2313,17 +2126,18 @@ endfunction
function ! s :git_validate ( spec , check_branch )
function ! s :git_validate ( spec , check_branch )
let err = ''
let err = ''
if isdirectory ( a :spec .dir )
if isdirectory ( a :spec .dir )
let result = [s :git_local_branch ( a :spec .dir ) , s :git_origin_url ( a :spec .dir ) ]
let result = s :lines ( s :system ( 'git rev-parse --abbrev-ref HEAD 2>&1 && git config -f .git/config remote.origin.url' , a :spec .dir ) )
let remote = result [-1 ]
let remote = result [-1 ]
if empty( remote )
if v:shell_error
let err = join ( [remote , 'PlugClean required.' ], "\n" )
let err = join ( [remote , 'PlugClean required.' ], "\n" )
elseif ! s :compare_git_uri ( remote , a :spec .uri )
elseif ! s :compare_git_uri ( remote , a :spec .uri )
let err = join ( ['Invalid URI: ' .remote ,
let err = join ( ['Invalid URI: ' .remote ,
\ 'Expected: ' .a :spec .uri ,
\ 'Expected: ' .a :spec .uri ,
\ 'PlugClean required.' ], "\n" )
\ 'PlugClean required.' ], "\n" )
elseif a :check_branch && has_key ( a :spec , 'commit' )
elseif a :check_branch && has_key ( a :spec , 'commit' )
let sha = s :git_revision ( a :spec .dir )
let result = s :lines ( s :system ( 'git rev-parse HEAD 2>&1' , a :spec .dir ) )
if empty ( sha )
let sha = result [-1 ]
if v :shell_error
let err = join ( add ( result , 'PlugClean required.' ) , "\n" )
let err = join ( add ( result , 'PlugClean required.' ) , "\n" )
elseif ! s :hash_match ( sha , a :spec .commit )
elseif ! s :hash_match ( sha , a :spec .commit )
let err = join ( [printf ( 'Invalid HEAD (expected: %s, actual: %s)' ,
let err = join ( [printf ( 'Invalid HEAD (expected: %s, actual: %s)' ,
@ -2331,9 +2145,8 @@ function! s:git_validate(spec, check_branch)
\ 'PlugUpdate required.' ], "\n" )
\ 'PlugUpdate required.' ], "\n" )
endif
endif
elseif a :check_branch
elseif a :check_branch
let current_ branch = result [0 ]
let branch = result [0 ]
" Check tag
" Check tag
let origin_branch = s :git_origin_branch ( a :spec )
if has_key ( a :spec , 'tag' )
if has_key ( a :spec , 'tag' )
let tag = s :system_chomp ( 'git describe --exact-match --tags HEAD 2>&1' , a :spec .dir )
let tag = s :system_chomp ( 'git describe --exact-match --tags HEAD 2>&1' , a :spec .dir )
if a :spec .tag ! = # tag && a :spec .tag ! ~ '\*'
if a :spec .tag ! = # tag && a :spec .tag ! ~ '\*'
@ -2341,26 +2154,25 @@ function! s:git_validate(spec, check_branch)
\ ( empty ( tag ) ? 'N/A' : tag ) , a :spec .tag )
\ ( empty ( tag ) ? 'N/A' : tag ) , a :spec .tag )
endif
endif
" Check branch
" Check branch
elseif origin_branch ! = # current_ branch
elseif a:spec .branch ! = # branch
let err = printf ( 'Invalid branch: %s (expected: %s). Try PlugUpdate.' ,
let err = printf ( 'Invalid branch: %s (expected: %s). Try PlugUpdate.' ,
\ current_branch, origin_ branch)
\ branch, a :spec . branch)
endif
endif
if empty ( err )
if empty ( err )
let [ahead , behind ] = split ( s :lastline ( s :system ( [
let [ahead , behind ] = split ( s :lastline ( s :system ( printf (
\ 'git' , 'rev-list' , '--count' , '--left-right' ,
\ 'git rev-list --count --left-right HEAD...origin/%s' ,
\ printf ( 'HEAD...origin/%s' , origin_branch )
\ a :spec .branch ) , a :spec .dir ) ) , '\t' )
\ ], a :spec .dir ) ) , '\t' )
if ! v :shell_error && ahead
if ! v :shell_error && ahead
if behind
if behind
" Only mention PlugClean if diverged, otherwise it's likely to be
" Only mention PlugClean if diverged, otherwise it's likely to be
" pushable (and probably not that messed up).
" pushable (and probably not that messed up).
let err = printf (
let err = printf (
\ "Diverged from origin/%s (%d commit(s) ahead and %d commit(s) behind!\n"
\ "Diverged from origin/%s (%d commit(s) ahead and %d commit(s) behind!\n"
\ .'Backup local changes and run PlugClean and PlugUpdate to reinstall it.' , origin_ branch, ahead , behind )
\ .'Backup local changes and run PlugClean and PlugUpdate to reinstall it.' , a:spec . branch, ahead , behind )
else
else
let err = printf ( "Ahead of origin/%s by %d commit(s).\n"
let err = printf ( "Ahead of origin/%s by %d commit(s).\n"
\ .'Cannot update until local changes are pushed.' ,
\ .'Cannot update until local changes are pushed.' ,
\ origin_ branch, ahead )
\ a:spec . branch, ahead )
endif
endif
endif
endif
endif
endif
@ -2373,9 +2185,7 @@ endfunction
function ! s :rm_rf ( dir )
function ! s :rm_rf ( dir )
if isdirectory ( a :dir )
if isdirectory ( a :dir )
return s :system ( s :is_win
call s :system ( ( s :is_win ? 'rmdir /S /Q ' : 'rm -rf ' ) . plug #shellescape ( a :dir ) )
\ ? 'rmdir /S /Q ' .plug #shellescape ( a :dir )
\ : ['rm' , '-rf' , a :dir ])
endif
endif
endfunction
endfunction
@ -2457,7 +2267,6 @@ endfunction
function ! s :delete ( range , force )
function ! s :delete ( range , force )
let [l1 , l2 ] = a :range
let [l1 , l2 ] = a :range
let force = a :force
let force = a :force
let err_count = 0
while l1 < = l2
while l1 < = l2
let line = getline ( l1 )
let line = getline ( l1 )
if line = ~ '^- ' && isdirectory ( line [2 :])
if line = ~ '^- ' && isdirectory ( line [2 :])
@ -2466,22 +2275,11 @@ function! s:delete(range, force)
let answer = force ? 1 : s :ask ( 'Delete ' .line [2 :].'?' , 1 )
let answer = force ? 1 : s :ask ( 'Delete ' .line [2 :].'?' , 1 )
let force = force | | answer > 1
let force = force | | answer > 1
if answer
if answer
let err = s :rm_rf ( line [2 :])
call s :rm_rf ( line [2 :])
setlocal modifiable
setlocal modifiable
if empty ( err )
call setline ( l1 , '~' .line [1 :])
call setline ( l1 , '~' .line [1 :])
let s :clean_count + = 1
let s :clean_count + = 1
call setline ( 4 , printf ( 'Removed %d directories.' , s :clean_count ) )
else
delete _
call append ( l1 - 1 , s :format_message ( 'x' , line [1 :], err ) )
let l2 + = len ( s :lines ( err ) )
let err_count + = 1
endif
let msg = printf ( 'Removed %d directories.' , s :clean_count )
if err_count > 0
let msg .= printf ( ' Failed to remove %d directories.' , err_count )
endif
call setline ( 4 , msg )
setlocal nomodifiable
setlocal nomodifiable
endif
endif
endif
endif
@ -2496,7 +2294,7 @@ function! s:upgrade()
let new = tmp . '/plug.vim'
let new = tmp . '/plug.vim'
try
try
let out = s :system ( ['git' , 'clone' , '--depth' , '1' , s :plug_src , tmp ] )
let out = s :system ( printf ( 'git clone --depth 1 %s %s' , plug #shellescape ( s :plug_src ) , plug #shellescape ( tmp ) ) )
if v :shell_error
if v :shell_error
return s :err ( 'Error upgrading vim-plug: ' . out )
return s :err ( 'Error upgrading vim-plug: ' . out )
endif
endif
@ -2621,34 +2419,26 @@ function! s:preview_commit()
let sha = matchstr ( getline ( '.' ) , '^ \X*\zs[0-9a-f]\{7,9}' )
let sha = matchstr ( getline ( '.' ) , '^ \X*\zs[0-9a-f]\{7,9}' )
if empty ( sha )
if empty ( sha )
let name = matchstr ( getline ( '.' ) , '^- \zs[^:]*\ze:$' )
return
if empty ( name )
return
endif
let title = 'HEAD@{1}..'
let command = 'git diff --no-color HEAD@{1}'
else
let title = sha
let command = 'git show --no-color --pretty=medium ' .sha
let name = s :find_name ( line ( '.' ) )
endif
endif
let name = s :find_name ( line ( '.' ) )
if empty ( name ) | | ! has_key ( g :plugs , name ) | | ! isdirectory ( g :plugs [name ].dir )
if empty ( name ) | | ! has_key ( g :plugs , name ) | | ! isdirectory ( g :plugs [name ].dir )
return
return
endif
endif
if exists ( 'g:plug_pwindow' ) && ! s :is_preview_window_open ( )
if exists ( 'g:plug_pwindow' ) && ! s :is_preview_window_open ( )
execute g :plug_pwindow
execute g :plug_pwindow
execute 'e' title
execute 'e' sha
else
else
execute 'pedit' title
execute 'pedit' sha
wincmd P
wincmd P
endif
endif
setlocal previewwindow filetype = git buftype = nofile bufhidden= wipe nobuflisted modifiable
setlocal previewwindow filetype = git buftype = nofile nobuflisted modifiable
let batchfile = ''
let batchfile = ''
try
try
let [sh , shellcmdflag , shrd ] = s :chsh ( 1 )
let [sh , shellcmdflag , shrd ] = s :chsh ( 1 )
let cmd = 'cd ' .plug #shellescape ( g :plugs [name ].dir ) .' && '.command
let cmd = 'cd ' .plug #shellescape ( g :plugs [name ].dir ) .' && git show --no-color --pretty=medium '.sha
if s :is_win
if s :is_win
let [batchfile , cmd ] = s :batchfile ( cmd )
let [batchfile , cmd ] = s :batchfile ( cmd )
endif
endif
@ -2698,23 +2488,18 @@ function! s:diff()
endif
endif
call s :append_ul ( 2 , origin ? 'Pending updates:' : 'Last update:' )
call s :append_ul ( 2 , origin ? 'Pending updates:' : 'Last update:' )
for [k , v ] in plugs
for [k , v ] in plugs
let branch = s :git_origin_branch ( v )
let range = origin ? '..origin/' .v .branch : 'HEAD@{1}..'
if len ( branch )
let cmd = 'git log --graph --color=never '
let range = origin ? '..origin/' .branch : 'HEAD@{1}..'
\ . ( s :git_version_requirement ( 2 , 10 , 0 ) ? '--no-show-signature ' : '' )
let cmd = ['git' , 'log' , '--graph' , '--color=never' ]
\ . join ( map ( ['--pretty=format:%x01%h%x01%d%x01%s%x01%cr' , range ], 'plug#shellescape(v:val)' ) )
if s :git_version_requirement ( 2 , 10 , 0 )
if has_key ( v , 'rtp' )
call add ( cmd , '--no-show-signature' )
let cmd .= ' -- ' .plug #shellescape ( v .rtp )
endif
endif
call extend ( cmd , ['--pretty=format:%x01%h%x01%d%x01%s%x01%cr' , range ])
let diff = s :system_chomp ( cmd , v .dir )
if has_key ( v , 'rtp' )
if ! empty ( diff )
call extend ( cmd , ['--' , v .rtp ])
let ref = has_key ( v , 'tag' ) ? ( ' (tag: ' .v .tag .')' ) : has_key ( v , 'commit' ) ? ( ' ' .v .commit ) : ''
endif
call append ( 5 , extend ( ['' , '- ' .k .':' .ref ], map ( s :lines ( diff ) , 's:format_git_log(v:val)' ) ) )
let diff = s :system_chomp ( cmd , v .dir )
let cnts [origin ] + = 1
if ! empty ( diff )
let ref = has_key ( v , 'tag' ) ? ( ' (tag: ' .v .tag .')' ) : has_key ( v , 'commit' ) ? ( ' ' .v .commit ) : ''
call append ( 5 , extend ( ['' , '- ' .k .':' .ref ], map ( s :lines ( diff ) , 's:format_git_log(v:val)' ) ) )
let cnts [origin ] + = 1
endif
endif
endif
let bar .= '='
let bar .= '='
call s :progress_bar ( 2 , bar , len ( total ) )
call s :progress_bar ( 2 , bar , len ( total ) )
@ -2774,9 +2559,9 @@ function! s:snapshot(force, ...) abort
1
1
let anchor = line ( '$' ) - 3
let anchor = line ( '$' ) - 3
let names = sort ( keys ( filter ( copy ( g :plugs ) ,
let names = sort ( keys ( filter ( copy ( g :plugs ) ,
\'has_key(v:val, "uri") && isdirectory(v:val.dir)') ) )
\'has_key(v:val, "uri") && !has_key(v:val, "commit") && isdirectory(v:val.dir)') ) )
for name in reverse ( names )
for name in reverse ( names )
let sha = has_key( g :plugs [name ], 'commit' ) ? g :plugs [name ].commit : s :git_revision ( g :plugs [name ].dir )
let sha = s:system_chomp ( 'git rev-parse --short HEAD' , g :plugs [name ].dir )
if ! empty ( sha )
if ! empty ( sha )
call append ( anchor , printf ( "silent! let g:plugs['%s'].commit = '%s'" , name , sha ) )
call append ( anchor , printf ( "silent! let g:plugs['%s'].commit = '%s'" , name , sha ) )
redraw
redraw