mirror of
https://github.com/dense-analysis/ale.git
synced 2025-12-29 15:26:52 +08:00
Fix #124 Finish implementing command chaining, and make it work for DMD
This commit is contained in:
@@ -53,6 +53,11 @@ function! ale#engine#ClearJob(job) abort
|
||||
endfunction
|
||||
|
||||
function! s:StopPreviousJobs(buffer, linter) abort
|
||||
if !has_key(g:ale_buffer_info, a:buffer)
|
||||
" Do nothing if we didn't run anything for the buffer.
|
||||
return
|
||||
endif
|
||||
|
||||
let l:new_job_list = []
|
||||
|
||||
for l:job in g:ale_buffer_info[a:buffer].job_list
|
||||
@@ -309,25 +314,48 @@ endfunction
|
||||
|
||||
function! s:InvokeChain(buffer, linter, chain_index, input) abort
|
||||
let l:output_stream = get(a:linter, 'output_stream', 'stdout')
|
||||
let l:chain_index = a:chain_index
|
||||
let l:input = a:input
|
||||
|
||||
if has_key(a:linter, 'command_chain')
|
||||
" Run a chain of commands, one asychronous command after the other,
|
||||
" so that many programs can be run in a sequence.
|
||||
let l:chain_item = a:linter.command_chain[a:chain_index]
|
||||
while l:chain_index < len(a:linter.command_chain)
|
||||
" Run a chain of commands, one asychronous command after the other,
|
||||
" so that many programs can be run in a sequence.
|
||||
let l:chain_item = a:linter.command_chain[l:chain_index]
|
||||
|
||||
" The chain item can override the output_stream option.
|
||||
if has_key(l:chain_item)
|
||||
let l:output_stream = l:chain_item.output_stream
|
||||
endif
|
||||
" The chain item can override the output_stream option.
|
||||
if has_key(l:chain_item, 'output_stream')
|
||||
let l:output_stream = l:chain_item.output_stream
|
||||
endif
|
||||
|
||||
let l:callback = ale#util#GetFunction(a:linter.callback)
|
||||
if l:chain_index == 0
|
||||
" The first callback in the chain takes only a buffer number.
|
||||
let l:command = ale#util#GetFunction(l:chain_item.callback)(
|
||||
\ a:buffer
|
||||
\)
|
||||
else
|
||||
" The second callback in the chain takes some input too.
|
||||
let l:command = ale#util#GetFunction(l:chain_item.callback)(
|
||||
\ a:buffer,
|
||||
\ l:input
|
||||
\)
|
||||
endif
|
||||
|
||||
if a:chain_index == 0
|
||||
" The first callback in the chain takes only a buffer number.
|
||||
let l:command = l:callback(a:buffer)
|
||||
else
|
||||
" The second callback in the chain takes some input too.
|
||||
let l:command = l:callback(a:buffer, a:input)
|
||||
if !empty(l:command)
|
||||
" We hit a command to run, so we'll execute that
|
||||
break
|
||||
endif
|
||||
|
||||
" Command chain items can return an empty string to indicate that
|
||||
" a command should be skipped, so we should try the next item
|
||||
" with no input.
|
||||
let l:input = []
|
||||
let l:chain_index += 1
|
||||
endwhile
|
||||
|
||||
if empty(l:command)
|
||||
" Don't run any jobs if the last command is an empty string.
|
||||
return
|
||||
endif
|
||||
elseif has_key(a:linter, 'command_callback')
|
||||
" If there is a callback for generating a command, call that instead.
|
||||
@@ -340,7 +368,7 @@ function! s:InvokeChain(buffer, linter, chain_index, input) abort
|
||||
\ 'buffer': a:buffer,
|
||||
\ 'linter': a:linter,
|
||||
\ 'output_stream': l:output_stream,
|
||||
\ 'next_chain_index': a:chain_index + 1,
|
||||
\ 'next_chain_index': l:chain_index + 1,
|
||||
\})
|
||||
endfunction
|
||||
|
||||
@@ -406,4 +434,27 @@ function! ale#engine#WaitForJobs(deadline) abort
|
||||
" prevents the occasional failure where this function exits after jobs
|
||||
" end, but before handlers are run.
|
||||
sleep 10ms
|
||||
|
||||
" We must check the buffer data again to see if new jobs started
|
||||
" for command_chain linters.
|
||||
let l:has_new_jobs = 0
|
||||
|
||||
for l:info in values(g:ale_buffer_info)
|
||||
if !empty(l:info.job_list)
|
||||
let l:has_new_jobs = 1
|
||||
endif
|
||||
endfor
|
||||
|
||||
if l:has_new_jobs
|
||||
" We have to wait more. Offset the timeout by the time taken so far.
|
||||
let l:now = system('date +%s%3N') + 0
|
||||
let l:new_deadline = a:deadline - (l:now - l:start_time)
|
||||
|
||||
if l:new_deadline <= 0
|
||||
" Enough time passed already, so stop immediately.
|
||||
throw 'Jobs did not complete on time!'
|
||||
endif
|
||||
|
||||
call ale#engine#WaitForJobs(l:new_deadline)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
Reference in New Issue
Block a user