1
0
Fork 0
mirror of synced 2024-11-16 05:55:35 -05:00
ultimate-vim/sources_non_forked/vim-go/autoload/go/job.vim

156 lines
4.6 KiB
VimL
Raw Normal View History

2018-02-04 06:35:08 -05:00
" Spawn returns callbacks to be used with job_start. It is abstracted to be
" used with various go commands, such as build, test, install, etc.. This
" allows us to avoid writing the same callback over and over for some
" commands. It's fully customizable so each command can change it to it's own
" logic.
"
" args is a dictionary with the these keys:
" 'cmd':
" The value to pass to job_start().
" 'bang':
" Set to 0 to jump to the first error in the error list.
" Defaults to 0.
" 'for':
" The g:go_list_type_command key to use to get the error list type to use.
" Defaults to '_job'
" 'complete':
" A function to call after the job exits and the channel is closed. The
" function will be passed three arguments: the job, its exit code, and the
" list of messages received from the channel. The default value will
" process the messages and manage the error list after the job exits and
" the channel is closed.
" The return value is a dictionary with these keys:
" 'callback':
" A function suitable to be passed as a job callback handler. See
" job-callback.
" 'exit_cb':
" A function suitable to be passed as a job exit_cb handler. See
" job-exit_cb.
" 'close_cb':
" A function suitable to be passed as a job close_cb handler. See
" job-close_cb.
2016-12-27 09:46:49 -05:00
function go#job#Spawn(args)
2018-02-04 06:35:08 -05:00
let cbs = {}
2018-03-31 10:56:26 -04:00
let state = {
2018-06-14 06:31:12 -04:00
\ 'winid': win_getid(winnr()),
2018-03-31 10:56:26 -04:00
\ 'dir': getcwd(),
\ 'jobdir': fnameescape(expand("%:p:h")),
\ 'messages': [],
\ 'args': a:args.cmd,
\ 'bang': 0,
\ 'for': "_job",
\ 'exited': 0,
\ 'exit_status': 0,
\ 'closed': 0,
\ 'errorformat': &errorformat
\ }
2016-12-27 09:46:49 -05:00
if has_key(a:args, 'bang')
2018-03-31 10:56:26 -04:00
let state.bang = a:args.bang
2016-12-27 09:46:49 -05:00
endif
if has_key(a:args, 'for')
2018-03-31 10:56:26 -04:00
let state.for = a:args.for
endif
2018-03-31 10:56:26 -04:00
" do nothing in state.complete by default.
function state.complete(job, exit_status, data)
2018-02-04 06:35:08 -05:00
endfunction
if has_key(a:args, 'complete')
2018-03-31 10:56:26 -04:00
let state.complete = a:args.complete
2016-12-27 09:46:49 -05:00
endif
2018-03-31 10:56:26 -04:00
function! s:callback(chan, msg) dict
call add(self.messages, a:msg)
2016-12-27 09:46:49 -05:00
endfunction
2018-03-31 10:56:26 -04:00
" explicitly bind callback to state so that within it, self will
" always refer to state. See :help Partial for more information.
let cbs.callback = function('s:callback', [], state)
2016-12-27 09:46:49 -05:00
2018-03-31 10:56:26 -04:00
function! s:exit_cb(job, exitval) dict
let self.exit_status = a:exitval
let self.exited = 1
2016-12-27 09:46:49 -05:00
2018-06-14 06:31:12 -04:00
if go#config#EchoCommandInfo()
2017-05-02 08:42:08 -04:00
if a:exitval == 0
2016-12-27 09:46:49 -05:00
call go#util#EchoSuccess("SUCCESS")
else
call go#util#EchoError("FAILED")
endif
endif
2018-03-31 10:56:26 -04:00
if self.closed
call self.complete(a:job, self.exit_status, self.messages)
call self.show_errors(a:job, self.exit_status, self.messages)
2017-09-02 06:43:18 -04:00
endif
2018-02-04 06:35:08 -05:00
endfunction
2018-03-31 10:56:26 -04:00
" explicitly bind exit_cb to state so that within it, self will always refer
" to state. See :help Partial for more information.
let cbs.exit_cb = function('s:exit_cb', [], state)
2018-02-04 06:35:08 -05:00
2018-03-31 10:56:26 -04:00
function! s:close_cb(ch) dict
let self.closed = 1
2018-02-04 06:35:08 -05:00
2018-03-31 10:56:26 -04:00
if self.exited
2018-02-04 06:35:08 -05:00
let job = ch_getjob(a:ch)
2018-03-31 10:56:26 -04:00
call self.complete(job, self.exit_status, self.messages)
call self.show_errors(job, self.exit_status, self.messages)
2018-02-04 06:35:08 -05:00
endif
endfunction
2018-03-31 10:56:26 -04:00
" explicitly bind close_cb to state so that within it, self will
" always refer to state. See :help Partial for more information.
let cbs.close_cb = function('s:close_cb', [], state)
2017-09-02 06:43:18 -04:00
2018-03-31 10:56:26 -04:00
function state.show_errors(job, exit_status, data)
2018-06-14 06:31:12 -04:00
let l:winid = win_getid(winnr())
call win_gotoid(self.winid)
2018-03-31 10:56:26 -04:00
let l:listtype = go#list#Type(self.for)
2018-02-04 06:35:08 -05:00
if a:exit_status == 0
2016-12-27 09:46:49 -05:00
call go#list#Clean(l:listtype)
2018-06-14 06:31:12 -04:00
call win_gotoid(l:winid)
2016-12-27 09:46:49 -05:00
return
endif
2018-03-31 10:56:26 -04:00
let l:listtype = go#list#Type(self.for)
2018-02-04 06:35:08 -05:00
if len(a:data) == 0
call go#list#Clean(l:listtype)
2018-06-14 06:31:12 -04:00
call win_gotoid(l:winid)
2018-02-04 06:35:08 -05:00
return
endif
2016-12-27 09:46:49 -05:00
2018-03-31 10:56:26 -04:00
let out = join(self.messages, "\n")
2016-12-27 09:46:49 -05:00
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
try
2018-03-31 10:56:26 -04:00
" parse the errors relative to self.jobdir
execute cd self.jobdir
call go#list#ParseFormat(l:listtype, self.errorformat, out, self.for)
let errors = go#list#Get(l:listtype)
2016-12-27 09:46:49 -05:00
finally
2018-03-31 10:56:26 -04:00
execute cd . fnameescape(self.dir)
2016-12-27 09:46:49 -05:00
endtry
2018-03-31 10:56:26 -04:00
2018-02-04 06:35:08 -05:00
if empty(errors)
2016-12-27 09:46:49 -05:00
" failed to parse errors, output the original content
2018-03-31 10:56:26 -04:00
call go#util#EchoError(self.messages + [self.dir])
2018-06-14 06:31:12 -04:00
call win_gotoid(l:winid)
2016-12-27 09:46:49 -05:00
return
endif
2018-06-14 06:31:12 -04:00
if self.winid == l:winid
2018-02-04 06:35:08 -05:00
call go#list#Window(l:listtype, len(errors))
2018-03-31 10:56:26 -04:00
if !self.bang
2018-02-04 06:35:08 -05:00
call go#list#JumpToFirst(l:listtype)
2016-12-27 09:46:49 -05:00
endif
endif
endfunction
return cbs
endfunction
2018-02-04 06:35:08 -05:00
2016-12-27 09:46:49 -05:00
" vim: sw=2 ts=2 et