mirror of
https://github.com/amix/vimrc
synced 2025-06-16 09:35:01 +08:00
Updated plugins
This commit is contained in:
@ -2,9 +2,6 @@ if has('nvim') && !exists("g:go_term_mode")
|
||||
let g:go_term_mode = 'vsplit'
|
||||
endif
|
||||
|
||||
" s:jobs is a global reference to all jobs started with new()
|
||||
let s:jobs = {}
|
||||
|
||||
" new creates a new terminal with the given command. Mode is set based on the
|
||||
" global variable g:go_term_mode, which is by default set to :vsplit
|
||||
function! go#term#new(bang, cmd) abort
|
||||
@ -18,8 +15,14 @@ function! go#term#newmode(bang, cmd, mode) abort
|
||||
let mode = g:go_term_mode
|
||||
endif
|
||||
|
||||
let state = {
|
||||
\ 'cmd': a:cmd,
|
||||
\ 'bang' : a:bang,
|
||||
\ 'winid': win_getid(winnr()),
|
||||
\ 'stdout': []
|
||||
\ }
|
||||
|
||||
" execute go build in the files directory
|
||||
let l:winnr = winnr()
|
||||
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
|
||||
let dir = getcwd()
|
||||
|
||||
@ -33,30 +36,27 @@ function! go#term#newmode(bang, cmd, mode) abort
|
||||
setlocal noswapfile
|
||||
setlocal nobuflisted
|
||||
|
||||
" explicitly bind callbacks to state so that within them, self will always
|
||||
" refer to state. See :help Partial for more information.
|
||||
"
|
||||
" Don't set an on_stderr, because it will be passed the same data as
|
||||
" on_stdout. See https://github.com/neovim/neovim/issues/2836
|
||||
let job = {
|
||||
\ 'stderr' : [],
|
||||
\ 'stdout' : [],
|
||||
\ 'bang' : a:bang,
|
||||
\ 'on_stdout': function('s:on_stdout'),
|
||||
\ 'on_stderr': function('s:on_stderr'),
|
||||
\ 'on_exit' : function('s:on_exit'),
|
||||
\ }
|
||||
\ 'on_stdout': function('s:on_stdout', [], state),
|
||||
\ 'on_exit' : function('s:on_exit', [], state),
|
||||
\ }
|
||||
|
||||
let id = termopen(a:cmd, job)
|
||||
let state.id = termopen(a:cmd, job)
|
||||
let state.termwinid = win_getid(winnr())
|
||||
|
||||
execute cd . fnameescape(dir)
|
||||
|
||||
let job.id = id
|
||||
let job.cmd = a:cmd
|
||||
startinsert
|
||||
|
||||
" resize new term if needed.
|
||||
let height = get(g:, 'go_term_height', winheight(0))
|
||||
let width = get(g:, 'go_term_width', winwidth(0))
|
||||
|
||||
" we are careful how to resize. for example it's vsplit we don't change
|
||||
" the height. The below command resizes the buffer
|
||||
|
||||
" Adjust the window width or height depending on whether it's a vertical or
|
||||
" horizontal split.
|
||||
if mode =~ "vertical" || mode =~ "vsplit" || mode =~ "vnew"
|
||||
exe 'vertical resize ' . width
|
||||
elseif mode =~ "split" || mode =~ "new"
|
||||
@ -64,77 +64,56 @@ function! go#term#newmode(bang, cmd, mode) abort
|
||||
endif
|
||||
|
||||
" we also need to resize the pty, so there you go...
|
||||
call jobresize(id, width, height)
|
||||
call jobresize(state.id, width, height)
|
||||
|
||||
let s:jobs[id] = job
|
||||
stopinsert
|
||||
call win_gotoid(state.winid)
|
||||
|
||||
if l:winnr !=# winnr()
|
||||
exe l:winnr . "wincmd w"
|
||||
endif
|
||||
|
||||
return id
|
||||
return state.id
|
||||
endfunction
|
||||
|
||||
function! s:on_stdout(job_id, data, event) dict abort
|
||||
if !has_key(s:jobs, a:job_id)
|
||||
return
|
||||
endif
|
||||
let job = s:jobs[a:job_id]
|
||||
|
||||
call extend(job.stdout, a:data)
|
||||
endfunction
|
||||
|
||||
function! s:on_stderr(job_id, data, event) dict abort
|
||||
if !has_key(s:jobs, a:job_id)
|
||||
return
|
||||
endif
|
||||
let job = s:jobs[a:job_id]
|
||||
|
||||
call extend(job.stderr, a:data)
|
||||
call extend(self.stdout, a:data)
|
||||
endfunction
|
||||
|
||||
function! s:on_exit(job_id, exit_status, event) dict abort
|
||||
if !has_key(s:jobs, a:job_id)
|
||||
return
|
||||
endif
|
||||
let job = s:jobs[a:job_id]
|
||||
|
||||
let l:listtype = go#list#Type("_term")
|
||||
|
||||
" usually there is always output so never branch into this clause
|
||||
if empty(job.stdout)
|
||||
call go#list#Clean(l:listtype)
|
||||
call go#list#Window(l:listtype)
|
||||
unlet s:jobs[a:job_id]
|
||||
if empty(self.stdout)
|
||||
call s:cleanlist(self.winid, l:listtype)
|
||||
return
|
||||
endif
|
||||
|
||||
let errors = go#tool#ParseErrors(job.stdout)
|
||||
let errors = go#tool#ParseErrors(self.stdout)
|
||||
let errors = go#tool#FilterValids(errors)
|
||||
|
||||
if !empty(errors)
|
||||
" close terminal we don't need it anymore
|
||||
" close terminal; we don't need it anymore
|
||||
call win_gotoid(self.termwinid)
|
||||
close
|
||||
|
||||
call go#list#Populate(l:listtype, errors, job.cmd)
|
||||
call win_gotoid(self.winid)
|
||||
|
||||
call go#list#Populate(l:listtype, errors, self.cmd)
|
||||
call go#list#Window(l:listtype, len(errors))
|
||||
if !self.bang
|
||||
call go#list#JumpToFirst(l:listtype)
|
||||
endif
|
||||
unlet s:jobs[a:job_id]
|
||||
|
||||
return
|
||||
endif
|
||||
|
||||
" tests are passing clean the list and close the list. But we only can
|
||||
" close them from a normal view, so jump back, close the list and then
|
||||
" again jump back to the terminal
|
||||
wincmd p
|
||||
call go#list#Clean(l:listtype)
|
||||
call go#list#Window(l:listtype)
|
||||
wincmd p
|
||||
call s:cleanlist(self.winid, l:listtype)
|
||||
endfunction
|
||||
|
||||
unlet s:jobs[a:job_id]
|
||||
function! s:cleanlist(winid, listtype) abort
|
||||
" There are no errors. Clean and close the list. Jump to the window to which
|
||||
" the location list is attached, close the list, and then jump back to the
|
||||
" current window.
|
||||
let winid = win_getid(winnr())
|
||||
call win_gotoid(a:winid)
|
||||
call go#list#Clean(a:listtype)
|
||||
call win_gotoid(l:winid)
|
||||
endfunction
|
||||
|
||||
" vim: sw=2 ts=2 et
|
||||
|
Reference in New Issue
Block a user