#2132 Implement deferred objects for ale#command#Run

This commit is contained in:
w0rp
2019-02-08 08:41:38 +00:00
parent 19cc724807
commit b32fdfe816
3 changed files with 55 additions and 37 deletions

View File

@@ -236,11 +236,17 @@ function! s:ExitCallback(buffer, line_list, Callback, data) abort
" If the callback starts any new jobs, use the same job type for them. " If the callback starts any new jobs, use the same job type for them.
call setbufvar(a:buffer, 'ale_job_type', l:job_type) call setbufvar(a:buffer, 'ale_job_type', l:job_type)
call a:Callback(a:buffer, a:line_list, a:data) let l:result = a:Callback(a:buffer, a:line_list, {
\ 'exit_code': a:data.exit_code,
\ 'temporary_file': a:data.temporary_file,
\})
if get(a:data, 'result_callback', v:null) isnot v:null
call call(a:data.result_callback, [l:result])
endif
endfunction endfunction
function! ale#command#Run(buffer, command, options) abort function! ale#command#Run(buffer, command, Callback, options) abort
let l:Callback = a:options.callback
let l:output_stream = get(a:options, 'output_stream', 'stdout') let l:output_stream = get(a:options, 'output_stream', 'stdout')
let l:line_list = [] let l:line_list = []
@@ -256,12 +262,13 @@ function! ale#command#Run(buffer, command, options) abort
\ 'exit_cb': {job_id, exit_code -> s:ExitCallback( \ 'exit_cb': {job_id, exit_code -> s:ExitCallback(
\ a:buffer, \ a:buffer,
\ l:line_list, \ l:line_list,
\ l:Callback, \ a:Callback,
\ { \ {
\ 'job_id': job_id, \ 'job_id': job_id,
\ 'exit_code': exit_code, \ 'exit_code': exit_code,
\ 'temporary_file': l:temporary_file, \ 'temporary_file': l:temporary_file,
\ 'log_output': get(a:options, 'log_output', 1), \ 'log_output': get(a:options, 'log_output', 1),
\ 'result_callback': get(l:result, 'result_callback', v:null),
\ } \ }
\ )}, \ )},
\ 'mode': 'nl', \ 'mode': 'nl',
@@ -302,6 +309,13 @@ function! ale#command#Run(buffer, command, options) abort
call ale#history#Add(a:buffer, l:status, l:job_id, l:command) call ale#history#Add(a:buffer, l:status, l:job_id, l:command)
endif endif
" We'll return this Dictionary. A `result_callback` can be assigned to it
" later for capturing the result of a:Callback.
"
" The `_deferred_job_id` is used for both checking the type of object, and
" for checking the job ID and status.
let l:result = {'_deferred_job_id': l:job_id}
if get(g:, 'ale_run_synchronously') == 1 && l:job_id if get(g:, 'ale_run_synchronously') == 1 && l:job_id
" Run a command synchronously if this test option is set. " Run a command synchronously if this test option is set.
call extend(l:line_list, systemlist( call extend(l:line_list, systemlist(
@@ -326,5 +340,5 @@ function! ale#command#Run(buffer, command, options) abort
\) \)
endif endif
return l:job_id ? v:true : v:false return l:result
endfunction endfunction

View File

@@ -411,37 +411,39 @@ function! s:RunJob(options) abort
let l:read_buffer = a:options.read_buffer let l:read_buffer = a:options.read_buffer
let l:info = g:ale_buffer_info[l:buffer] let l:info = g:ale_buffer_info[l:buffer]
let l:run = ale#command#Run(l:buffer, l:command, { let l:Callback = function('s:HandleExit', [{
\ 'linter': l:linter,
\ 'executable': l:executable,
\ 'next_chain_index': l:next_chain_index,
\}])
let l:result = ale#command#Run(l:buffer, l:command, l:Callback, {
\ 'output_stream': l:output_stream, \ 'output_stream': l:output_stream,
\ 'executable': l:executable, \ 'executable': l:executable,
\ 'read_buffer': l:read_buffer, \ 'read_buffer': l:read_buffer,
\ 'log_output': l:next_chain_index >= len(get(l:linter, 'command_chain', [])), \ 'log_output': l:next_chain_index >= len(get(l:linter, 'command_chain', [])),
\ 'callback': function('s:HandleExit', [{
\ 'linter': l:linter,
\ 'executable': l:executable,
\ 'next_chain_index': l:next_chain_index,
\ }]),
\}) \})
" Only proceed if the job is being run. if !l:result._deferred_job_id
if l:run return 0
let l:found = 0
for l:other_linter in l:info.active_linter_list
if l:other_linter.name is# l:linter.name
let l:found = 1
break
endif
endfor
if !l:found
call add(l:info.active_linter_list, l:linter)
endif
silent doautocmd <nomodeline> User ALEJobStarted
endif endif
return l:run " Only proceed if the job is being run.
let l:found = 0
for l:other_linter in l:info.active_linter_list
if l:other_linter.name is# l:linter.name
let l:found = 1
break
endif
endfor
if !l:found
call add(l:info.active_linter_list, l:linter)
endif
silent doautocmd <nomodeline> User ALEJobStarted
return 1
endfunction endfunction
" Determine which commands to run for a link in a command chain, or " Determine which commands to run for a link in a command chain, or

View File

@@ -163,21 +163,23 @@ function! s:RunJob(options) abort
let l:output_stream = 'none' let l:output_stream = 'none'
endif endif
return ale#command#Run(l:buffer, l:command, { let l:Callback = function('s:HandleExit', [{
\ 'input': l:input,
\ 'chain_with': l:ChainWith,
\ 'callback_index': a:options.callback_index,
\ 'callback_list': a:options.callback_list,
\ 'process_with': a:options.process_with,
\ 'read_temporary_file': a:options.read_temporary_file,
\}])
let l:result = ale#command#Run(l:buffer, l:command, l:Callback, {
\ 'output_stream': l:output_stream, \ 'output_stream': l:output_stream,
\ 'executable': '', \ 'executable': '',
\ 'read_buffer': l:read_buffer, \ 'read_buffer': l:read_buffer,
\ 'input': l:input, \ 'input': l:input,
\ 'log_output': 0, \ 'log_output': 0,
\ 'callback': function('s:HandleExit', [{
\ 'input': l:input,
\ 'chain_with': l:ChainWith,
\ 'callback_index': a:options.callback_index,
\ 'callback_list': a:options.callback_list,
\ 'process_with': a:options.process_with,
\ 'read_temporary_file': a:options.read_temporary_file,
\ }]),
\}) \})
return l:result._deferred_job_id != 0
endfunction endfunction
function! s:RunFixer(options) abort function! s:RunFixer(options) abort