Stabilize Neovim installer
- Abort running jobs when plug windows is reset - Multi-line error report - Retain window view
This commit is contained in:
parent
4eeff535fa
commit
662274e617
1 changed files with 53 additions and 46 deletions
85
plug.vim
85
plug.vim
|
@ -73,6 +73,7 @@ let s:plug_tab = get(s:, 'plug_tab', -1)
|
||||||
let s:plug_buf = get(s:, 'plug_buf', -1)
|
let s:plug_buf = get(s:, 'plug_buf', -1)
|
||||||
let s:mac_gui = has('gui_macvim') && has('gui_running')
|
let s:mac_gui = has('gui_macvim') && has('gui_running')
|
||||||
let s:is_win = has('win32') || has('win64')
|
let s:is_win = has('win32') || has('win64')
|
||||||
|
let s:nvim = exists('##JobActivity')
|
||||||
let s:me = resolve(expand('<sfile>:p'))
|
let s:me = resolve(expand('<sfile>:p'))
|
||||||
let s:base_spec = { 'branch': 'master', 'frozen': 0 }
|
let s:base_spec = { 'branch': 'master', 'frozen': 0 }
|
||||||
let s:TYPE = {
|
let s:TYPE = {
|
||||||
|
@ -484,9 +485,12 @@ function! s:lpad(str, len)
|
||||||
return a:str . repeat(' ', a:len - len(a:str))
|
return a:str . repeat(' ', a:len - len(a:str))
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
function! s:lines(msg)
|
||||||
|
return split(a:msg, "[\r\n]")
|
||||||
|
endfunction
|
||||||
|
|
||||||
function! s:lastline(msg)
|
function! s:lastline(msg)
|
||||||
let lines = split(a:msg, "[\r\n]")
|
return get(s:lines(a:msg), -1, '')
|
||||||
return get(lines, -1, '')
|
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:new_window()
|
function! s:new_window()
|
||||||
|
@ -506,19 +510,23 @@ function! s:switch_in()
|
||||||
execute 'normal!' s:plug_tab.'gt'
|
execute 'normal!' s:plug_tab.'gt'
|
||||||
let winnr = bufwinnr(s:plug_buf)
|
let winnr = bufwinnr(s:plug_buf)
|
||||||
execute winnr 'wincmd w'
|
execute winnr 'wincmd w'
|
||||||
setlocal modifiable
|
|
||||||
|
|
||||||
|
call add(s:pos, winsaveview())
|
||||||
|
setlocal modifiable
|
||||||
return 1
|
return 1
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:switch_out()
|
function! s:switch_out()
|
||||||
|
call winrestview(s:pos[3])
|
||||||
setlocal nomodifiable
|
setlocal nomodifiable
|
||||||
|
|
||||||
execute 'normal!' s:pos[0].'gt'
|
execute 'normal!' s:pos[0].'gt'
|
||||||
execute s:pos[1] 'wincmd w'
|
execute s:pos[1] 'wincmd w'
|
||||||
call winrestview(s:pos[2])
|
call winrestview(s:pos[2])
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:prepare()
|
function! s:prepare()
|
||||||
|
call s:job_abort()
|
||||||
if bufexists(s:plug_buf)
|
if bufexists(s:plug_buf)
|
||||||
let winnr = bufwinnr(s:plug_buf)
|
let winnr = bufwinnr(s:plug_buf)
|
||||||
if winnr < 0
|
if winnr < 0
|
||||||
|
@ -647,7 +655,6 @@ function! s:update_impl(pull, force, args) abort
|
||||||
let managed = filter(copy(g:plugs), 's:is_managed(v:key)')
|
let managed = filter(copy(g:plugs), 's:is_managed(v:key)')
|
||||||
let todo = empty(args) ? filter(managed, '!v:val.frozen') :
|
let todo = empty(args) ? filter(managed, '!v:val.frozen') :
|
||||||
\ filter(managed, 'index(args, v:key) >= 0')
|
\ filter(managed, 'index(args, v:key) >= 0')
|
||||||
let threads = min([len(todo), threads])
|
|
||||||
|
|
||||||
if empty(todo)
|
if empty(todo)
|
||||||
echohl WarningMsg
|
echohl WarningMsg
|
||||||
|
@ -667,14 +674,13 @@ function! s:update_impl(pull, force, args) abort
|
||||||
|
|
||||||
let s:update = {
|
let s:update = {
|
||||||
\ 'start': reltime(),
|
\ 'start': reltime(),
|
||||||
\ 'neovim': exists('##JobActivity'),
|
|
||||||
\ 'all': todo,
|
\ 'all': todo,
|
||||||
\ 'todo': copy(todo),
|
\ 'todo': copy(todo),
|
||||||
\ 'errors': [],
|
\ 'errors': [],
|
||||||
\ 'pull': a:pull,
|
\ 'pull': a:pull,
|
||||||
\ 'force': a:force,
|
\ 'force': a:force,
|
||||||
\ 'new': {},
|
\ 'new': {},
|
||||||
\ 'threads': (has('ruby') || exists('##JobActivity')) ? threads : 1,
|
\ 'threads': (has('ruby') || s:nvim) ? min([len(todo), threads]) : 1,
|
||||||
\ 'bar': '',
|
\ 'bar': '',
|
||||||
\ 'fin': 0
|
\ 'fin': 0
|
||||||
\ }
|
\ }
|
||||||
|
@ -723,25 +729,34 @@ function! s:update_finish()
|
||||||
endif
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:job_handler()
|
function! s:job_abort()
|
||||||
let name = s:jobs_idx[v:job_data[0]]
|
if !s:nvim || !exists('s:jobs')
|
||||||
let job = s:jobs[name]
|
return
|
||||||
|
endif
|
||||||
" plug window closed
|
|
||||||
if !s:plug_window_exists()
|
|
||||||
augroup PlugJobControl
|
augroup PlugJobControl
|
||||||
autocmd!
|
autocmd!
|
||||||
augroup END
|
augroup END
|
||||||
for [name, j] in items(s:jobs)
|
for [name, j] in items(s:jobs)
|
||||||
call jobstop(j.jobid)
|
silent! call jobstop(j.jobid)
|
||||||
if j.new
|
if j.new
|
||||||
call system('rm -rf ' . s:shellesc(g:plugs[name].dir))
|
call system('rm -rf ' . s:shellesc(g:plugs[name].dir))
|
||||||
endif
|
endif
|
||||||
endfor
|
endfor
|
||||||
return
|
let s:jobs = {}
|
||||||
|
let s:jobs_idx = {}
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:job_handler() abort
|
||||||
|
if !s:plug_window_exists() " plug window closed
|
||||||
|
return s:job_abort()
|
||||||
endif
|
endif
|
||||||
|
|
||||||
let s:tick += 1
|
let name = get(s:jobs_idx, v:job_data[0], '')
|
||||||
|
if empty(name) " stale task
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
let job = s:jobs[name]
|
||||||
|
|
||||||
if v:job_data[1] == 'exit'
|
if v:job_data[1] == 'exit'
|
||||||
let job.running = 0
|
let job.running = 0
|
||||||
call s:reap(name)
|
call s:reap(name)
|
||||||
|
@ -751,7 +766,7 @@ function! s:job_handler()
|
||||||
" To reduce the number of buffer updates
|
" To reduce the number of buffer updates
|
||||||
let job.tick = get(job, 'tick', -1) + 1
|
let job.tick = get(job, 'tick', -1) + 1
|
||||||
if job.tick % len(s:jobs) == 0
|
if job.tick % len(s:jobs) == 0
|
||||||
call s:log(name, s:lastline(job.result), s:update.pull ? 'u' : 'i')
|
call s:log(job.new ? '+' : '*', name, job.result)
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
@ -761,7 +776,7 @@ function! s:spawn(name, cmd, opts)
|
||||||
\ 'error': 0, 'result': '' }
|
\ 'error': 0, 'result': '' }
|
||||||
let s:jobs[a:name] = job
|
let s:jobs[a:name] = job
|
||||||
|
|
||||||
if s:update.neovim
|
if s:nvim
|
||||||
let x = jobstart(a:name, 'sh', ['-c',
|
let x = jobstart(a:name, 'sh', ['-c',
|
||||||
\ has_key(a:opts, 'dir') ? s:with_cd(a:cmd, a:opts.dir) : a:cmd])
|
\ has_key(a:opts, 'dir') ? s:with_cd(a:cmd, a:opts.dir) : a:cmd])
|
||||||
if x > 0
|
if x > 0
|
||||||
|
@ -785,7 +800,7 @@ function! s:spawn(name, cmd, opts)
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:reap(name)
|
function! s:reap(name)
|
||||||
if s:update.neovim
|
if s:nvim
|
||||||
silent! execute 'autocmd! PlugJobControl JobActivity' a:name
|
silent! execute 'autocmd! PlugJobControl JobActivity' a:name
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
@ -797,8 +812,7 @@ function! s:reap(name)
|
||||||
endif
|
endif
|
||||||
let s:update.bar .= job.error ? 'x' : '='
|
let s:update.bar .= job.error ? 'x' : '='
|
||||||
|
|
||||||
" TODO: Error formatting
|
call s:log(job.error ? 'x' : '-', a:name, job.result)
|
||||||
call s:log(a:name, s:lastline(job.result), job.error ? 'x' : '-')
|
|
||||||
call s:bar()
|
call s:bar()
|
||||||
|
|
||||||
call remove(s:jobs, a:name)
|
call remove(s:jobs, a:name)
|
||||||
|
@ -824,7 +838,7 @@ function! s:logpos(name)
|
||||||
return 0
|
return 0
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:log(name, line, type)
|
function! s:log(bullet, name, lines)
|
||||||
if s:switch_in()
|
if s:switch_in()
|
||||||
let pos = s:logpos(a:name)
|
let pos = s:logpos(a:name)
|
||||||
if pos > 0
|
if pos > 0
|
||||||
|
@ -835,12 +849,7 @@ function! s:log(name, line, type)
|
||||||
else
|
else
|
||||||
let pos = 4
|
let pos = 4
|
||||||
endif
|
endif
|
||||||
|
call append(pos - 1, s:format_message(a:bullet, a:name, a:lines))
|
||||||
let bullet = a:type == 'i' ? '+' :
|
|
||||||
\ (a:type == 'u' ? '*' :
|
|
||||||
\ (a:type == 'x' ? 'x' : '-'))
|
|
||||||
|
|
||||||
call append(pos - 1, printf('%s %s: %s', bullet, a:name, a:line))
|
|
||||||
call s:switch_out()
|
call s:switch_out()
|
||||||
endif
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
@ -848,7 +857,6 @@ endfunction
|
||||||
function! s:update_vim()
|
function! s:update_vim()
|
||||||
let s:jobs = {}
|
let s:jobs = {}
|
||||||
let s:jobs_idx = {}
|
let s:jobs_idx = {}
|
||||||
let s:tick = 0
|
|
||||||
|
|
||||||
call s:bar()
|
call s:bar()
|
||||||
normal! 2G
|
normal! 2G
|
||||||
|
@ -856,7 +864,7 @@ function! s:update_vim()
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:tick()
|
function! s:tick()
|
||||||
while 1
|
while 1 " Without TCO, Vim stack is bound to explode
|
||||||
if empty(s:update.todo)
|
if empty(s:update.todo)
|
||||||
if empty(s:jobs) && !s:update.fin
|
if empty(s:jobs) && !s:update.fin
|
||||||
let s:update.fin = 1
|
let s:update.fin = 1
|
||||||
|
@ -868,10 +876,12 @@ while 1
|
||||||
let name = keys(s:update.todo)[0]
|
let name = keys(s:update.todo)[0]
|
||||||
let spec = remove(s:update.todo, name)
|
let spec = remove(s:update.todo, name)
|
||||||
let pull = s:update.pull
|
let pull = s:update.pull
|
||||||
call s:log(name, pull ? 'Updating ...' : 'Installing ...', pull ? 'u' : 'i')
|
let new = !isdirectory(spec.dir)
|
||||||
|
|
||||||
|
call s:log(new ? '+' : '*', name, pull ? 'Updating ...' : 'Installing ...')
|
||||||
redraw
|
redraw
|
||||||
|
|
||||||
if isdirectory(spec.dir)
|
if !new
|
||||||
let [valid, msg] = s:git_valid(spec, 0)
|
let [valid, msg] = s:git_valid(spec, 0)
|
||||||
if valid
|
if valid
|
||||||
if pull
|
if pull
|
||||||
|
@ -894,11 +904,8 @@ while 1
|
||||||
|
|
||||||
if !s:jobs[name].running
|
if !s:jobs[name].running
|
||||||
call s:reap(name)
|
call s:reap(name)
|
||||||
" Without TCO, Vim stack is bound to explode
|
|
||||||
" return s:tick()
|
|
||||||
continue
|
continue
|
||||||
elseif len(s:jobs) < s:update.threads
|
elseif len(s:jobs) < s:update.threads
|
||||||
" return s:tick()
|
|
||||||
continue
|
continue
|
||||||
endif
|
endif
|
||||||
break
|
break
|
||||||
|
@ -1134,11 +1141,11 @@ function! s:compare_git_uri(a, b)
|
||||||
return a ==# b
|
return a ==# b
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:format_message(ok, name, message)
|
function! s:format_message(bullet, name, message)
|
||||||
if a:ok
|
if a:bullet != 'x'
|
||||||
return [printf('- %s: %s', a:name, s:lastline(a:message))]
|
return [printf('%s %s: %s', a:bullet, a:name, s:lastline(a:message))]
|
||||||
else
|
else
|
||||||
let lines = map(split(a:message, '\n'), '" ".v:val')
|
let lines = map(s:lines(a:message), '" ".v:val')
|
||||||
return extend([printf('x %s:', a:name)], lines)
|
return extend([printf('x %s:', a:name)], lines)
|
||||||
endif
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
@ -1321,7 +1328,7 @@ function! s:status()
|
||||||
let msg .= ' (not loaded)'
|
let msg .= ' (not loaded)'
|
||||||
endif
|
endif
|
||||||
call s:progress_bar(2, repeat('=', cnt), total)
|
call s:progress_bar(2, repeat('=', cnt), total)
|
||||||
call append(3, s:format_message(valid, name, msg))
|
call append(3, s:format_message(valid ? '-' : 'x', name, msg))
|
||||||
normal! 2G
|
normal! 2G
|
||||||
redraw
|
redraw
|
||||||
endfor
|
endfor
|
||||||
|
|
Loading…
Reference in a new issue