Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use job for s:system() on vim8 #594

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 52 additions & 30 deletions plug.vim
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ endfunction

function! s:git_version_requirement(...)
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')[0])[2], '\.'), 'str2nr(v:val)')
endif
return s:version_requirement(s:git_version, a:000)
endfunction
Expand Down Expand Up @@ -865,12 +865,12 @@ endfunction

function! s:checkout(spec)
let sha = a:spec.commit
let output = s:system('git rev-parse HEAD', a:spec.dir)
if !v:shell_error && !s:hash_match(sha, s:lines(output)[0])
let output = s:system(
let [output, shellerror] = s:system('git rev-parse HEAD', a:spec.dir)
if !shellerror && !s:hash_match(sha, s:lines(output)[0])
let [output, shellerror] = s:system(
\ 'git fetch --depth 999999 && git checkout '.s:esc(sha), a:spec.dir)
endif
return output
return [output, shellerror]
endfunction

function! s:finish(pull)
Expand Down Expand Up @@ -1053,34 +1053,36 @@ function! s:update_finish()
if !pos
continue
endif
let shellerror = 0
if has_key(spec, 'commit')
call s:log4(name, 'Checking out '.spec.commit)
let out = s:checkout(spec)
let [out, shellerror] = s:checkout(spec)
elseif has_key(spec, 'tag')
let tag = spec.tag
if tag =~ '\*'
let tags = s:lines(s:system('git tag --list '.string(tag).' --sort -version:refname 2>&1', spec.dir))
if !v:shell_error && !empty(tags)
let [output, shellerror] = s:system('git tag --list '.string(tag).' --sort -version:refname 2>&1', spec.dir)
let tags = s:lines(output)
if !shellerror && !empty(tags)
let tag = tags[0]
call s:log4(name, printf('Latest tag for %s -> %s', spec.tag, tag))
call append(3, '')
endif
endif
call s:log4(name, 'Checking out '.tag)
let out = s:system('git checkout -q '.s:esc(tag).' 2>&1', spec.dir)
let [out, shellerror] = s:system('git checkout -q '.s:esc(tag).' 2>&1', spec.dir)
else
let branch = s:esc(get(spec, 'branch', 'master'))
call s:log4(name, 'Merging origin/'.branch)
let out = s:system('git checkout -q '.branch.' 2>&1'
let [out, shellerror] = s:system('git checkout -q '.branch.' 2>&1'
\. (has_key(s:update.new, name) ? '' : ('&& git merge --ff-only origin/'.branch.' 2>&1')), spec.dir)
endif
if !v:shell_error && filereadable(spec.dir.'/.gitmodules') &&
if !shellerror && filereadable(spec.dir.'/.gitmodules') &&
\ (s:update.force || has_key(s:update.new, name) || s:is_updated(spec.dir))
call s:log4(name, 'Updating submodules. This may take a while.')
let out .= s:bang('git submodule update --init --recursive 2>&1', spec.dir)
endif
let msg = s:format_message(v:shell_error ? 'x': '-', name, out)
if v:shell_error
let msg = s:format_message(shellerror ? 'x': '-', name, out)
if shellerror
call add(s:update.errors, name)
call s:regress_bar()
silent execute pos 'd _'
Expand Down Expand Up @@ -1203,8 +1205,9 @@ function! s:spawn(name, cmd, opts)
endif
else
let params = has_key(a:opts, 'dir') ? [a:cmd, a:opts.dir] : [a:cmd]
let job.lines = s:lines(call('s:system', params))
let job.error = v:shell_error != 0
let [output, shellerror] = call('s:system', params)
let job.lines = s:lines(output)
let job.error = shellerror != 0
let job.running = 0
endif
endfunction
Expand Down Expand Up @@ -1979,34 +1982,52 @@ endfunction

function! s:system(cmd, ...)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s:system can be simplified to s:system_with_error(...)[0].

try
let maxfuncdepth = &maxfuncdepth
set maxfuncdepth=99999
let [sh, shrd] = s:chsh(1)
let cmd = a:0 > 0 ? s:with_cd(a:cmd, a:1) : a:cmd
return system(s:is_win ? '('.cmd.')' : cmd)
if s:vim8
let [out, exit_code] = ['', 0]
let job = job_start([&shell, &shellcmdflag, cmd], {
\ 'out_cb': {ch,msg->[execute("let out .= msg"), out]},
\ 'err_cb': {ch,msg->[execute("let out .= msg"), out]},
\ 'exit_cb': {job,code->[execute("let exit_code=code"), exit_code]},
\ 'out_mode': 'raw',
\ 'err_mode': 'raw',
\})
while job_status(job) == 'run'
sleep 10m
endwhile
return [out, exit_code]
endif
return [system(s:is_win ? '('.cmd.')' : cmd), v:shell_error]
finally
let [&shell, &shellredir] = [sh, shrd]
let [&shell, &shellredir, &maxfuncdepth] = [sh, shrd, maxfuncdepth]
endtry
endfunction

function! s:system_chomp(...)
let ret = call('s:system', a:000)
return v:shell_error ? '' : substitute(ret, '\n$', '', '')
let [ret, shellerror] = call('s:system', a:000)
return shellerror ? '' : substitute(ret, '\n$', '', '')
endfunction

function! s:git_validate(spec, check_branch)
let err = ''
if isdirectory(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 [output, shellerror] = s:system('git rev-parse --abbrev-ref HEAD 2>&1 && git config -f .git/config remote.origin.url', a:spec.dir)
let result = s:lines(output)
let remote = result[-1]
if v:shell_error
if shellerror
let err = join([remote, 'PlugClean required.'], "\n")
elseif !s:compare_git_uri(remote, a:spec.uri)
let err = join(['Invalid URI: '.remote,
\ 'Expected: '.a:spec.uri,
\ 'PlugClean required.'], "\n")
elseif a:check_branch && has_key(a:spec, 'commit')
let result = s:lines(s:system('git rev-parse HEAD 2>&1', a:spec.dir))
let [output, shellerror] = s:system('git rev-parse HEAD 2>&1', a:spec.dir)
let result = s:lines(output)
let sha = result[-1]
if v:shell_error
if shellerror
let err = join(add(result, 'PlugClean required.'), "\n")
elseif !s:hash_match(sha, a:spec.commit)
let err = join([printf('Invalid HEAD (expected: %s, actual: %s)',
Expand All @@ -2028,16 +2049,17 @@ function! s:git_validate(spec, check_branch)
\ branch, a:spec.branch)
endif
if empty(err)
let [ahead, behind] = split(s:lastline(s:system(printf(
let [output, shellerror] = s:system(printf(
\ 'git rev-list --count --left-right HEAD...origin/%s',
\ a:spec.branch), a:spec.dir)), '\t')
if !v:shell_error && ahead
if behind
\ a:spec.branch), a:spec.dir)
let [ahead; behind] = split(s:lastline(output), '\t')
if !shellerror && ahead && len(behind) == 1
if behind[0]
" Only mention PlugClean if diverged, otherwise it's likely to be
" pushable (and probably not that messed up).
let err = printf(
\ "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.', a:spec.branch, ahead, behind)
\ .'Backup local changes and run PlugClean and PlugUpdate to reinstall it.', a:spec.branch, ahead, behind[0])
else
let err = printf("Ahead of origin/%s by %d commit(s).\n"
\ .'Cannot update until local changes are pushed.',
Expand Down Expand Up @@ -2163,8 +2185,8 @@ function! s:upgrade()
let new = tmp . '/plug.vim'

try
let out = s:system(printf('git clone --depth 1 %s %s', s:plug_src, tmp))
if v:shell_error
let [out, shellerror] = s:system(printf('git clone --depth 1 %s %s', s:plug_src, tmp))
if shellerror
return s:err('Error upgrading vim-plug: '. out)
endif

Expand Down