#2132 - Set up fixers for deferred support
This commit is contained in:
parent
89e5491862
commit
70a9176de0
@ -131,35 +131,55 @@ function! s:HandleExit(job_info, buffer, job_output, data) abort
|
|||||||
\})
|
\})
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:RunJob(options) abort
|
function! s:RunJob(result, options) abort
|
||||||
let l:buffer = a:options.buffer
|
if ale#command#IsDeferred(a:result)
|
||||||
let l:command = a:options.command
|
let a:result.result_callback = {x -> s:RunJob(x, a:options)}
|
||||||
let l:input = a:options.input
|
|
||||||
let l:ChainWith = a:options.chain_with
|
|
||||||
let l:read_buffer = a:options.read_buffer
|
|
||||||
|
|
||||||
if empty(l:command)
|
return
|
||||||
" If there's nothing further to chain the command with, stop here.
|
endif
|
||||||
if l:ChainWith is v:null
|
|
||||||
return v:false
|
let l:buffer = a:options.buffer
|
||||||
|
let l:input = a:options.input
|
||||||
|
|
||||||
|
if a:result is 0 || type(a:result) is v:t_list
|
||||||
|
if type(a:result) is v:t_list
|
||||||
|
let l:input = a:result
|
||||||
endif
|
endif
|
||||||
|
|
||||||
" If there's another chained callback to run, then run that.
|
|
||||||
call s:RunFixer({
|
call s:RunFixer({
|
||||||
\ 'buffer': l:buffer,
|
\ 'buffer': l:buffer,
|
||||||
\ 'input': l:input,
|
\ 'input': l:input,
|
||||||
\ 'callback_index': a:options.callback_index,
|
\ 'callback_index': a:options.callback_index + 1,
|
||||||
|
\ 'callback_list': a:options.callback_list,
|
||||||
|
\})
|
||||||
|
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:command = get(a:result, 'command', '')
|
||||||
|
let l:ChainWith = get(a:result, 'chain_with', v:null)
|
||||||
|
|
||||||
|
if empty(l:command)
|
||||||
|
" If the command is empty, skip to the next item, or call the
|
||||||
|
" chain_with function.
|
||||||
|
call s:RunFixer({
|
||||||
|
\ 'buffer': l:buffer,
|
||||||
|
\ 'input': l:input,
|
||||||
|
\ 'callback_index': a:options.callback_index + (l:ChainWith is v:null),
|
||||||
\ 'callback_list': a:options.callback_list,
|
\ 'callback_list': a:options.callback_list,
|
||||||
\ 'chain_callback': l:ChainWith,
|
\ 'chain_callback': l:ChainWith,
|
||||||
\ 'output': [],
|
\ 'output': [],
|
||||||
\})
|
\})
|
||||||
|
|
||||||
return v:true
|
return
|
||||||
endif
|
endif
|
||||||
|
|
||||||
let l:output_stream = a:options.output_stream
|
let l:read_temporary_file = get(a:result, 'read_temporary_file', 0)
|
||||||
|
" Default to piping the buffer for the last fixer in the chain.
|
||||||
|
let l:read_buffer = get(a:result, 'read_buffer', l:ChainWith is v:null)
|
||||||
|
let l:output_stream = get(a:result, 'output_stream', 'stdout')
|
||||||
|
|
||||||
if a:options.read_temporary_file
|
if l:read_temporary_file
|
||||||
let l:output_stream = 'none'
|
let l:output_stream = 'none'
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@ -168,10 +188,10 @@ function! s:RunJob(options) abort
|
|||||||
\ 'chain_with': l:ChainWith,
|
\ 'chain_with': l:ChainWith,
|
||||||
\ 'callback_index': a:options.callback_index,
|
\ 'callback_index': a:options.callback_index,
|
||||||
\ 'callback_list': a:options.callback_list,
|
\ 'callback_list': a:options.callback_list,
|
||||||
\ 'process_with': a:options.process_with,
|
\ 'process_with': get(a:result, 'process_with', v:null),
|
||||||
\ 'read_temporary_file': a:options.read_temporary_file,
|
\ 'read_temporary_file': l:read_temporary_file,
|
||||||
\}])
|
\}])
|
||||||
let l:result = ale#command#Run(l:buffer, l:command, l:Callback, {
|
let l:run_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,
|
||||||
@ -179,70 +199,54 @@ function! s:RunJob(options) abort
|
|||||||
\ 'log_output': 0,
|
\ 'log_output': 0,
|
||||||
\})
|
\})
|
||||||
|
|
||||||
return !empty(l:result)
|
if empty(l:run_result)
|
||||||
|
call s:RunFixer({
|
||||||
|
\ 'buffer': l:buffer,
|
||||||
|
\ 'input': l:input,
|
||||||
|
\ 'callback_index': a:options.callback_index + 1,
|
||||||
|
\ 'callback_list': a:options.callback_list,
|
||||||
|
\})
|
||||||
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:RunFixer(options) abort
|
function! s:RunFixer(options) abort
|
||||||
let l:buffer = a:options.buffer
|
let l:buffer = a:options.buffer
|
||||||
let l:input = a:options.input
|
let l:input = a:options.input
|
||||||
let l:index = a:options.callback_index
|
let l:index = a:options.callback_index
|
||||||
|
|
||||||
|
if len(a:options.callback_list) <= l:index
|
||||||
|
call ale#fix#ApplyFixes(l:buffer, l:input)
|
||||||
|
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
let l:ChainCallback = get(a:options, 'chain_callback', v:null)
|
let l:ChainCallback = get(a:options, 'chain_callback', v:null)
|
||||||
|
|
||||||
" Record new jobs started as fixer jobs.
|
|
||||||
call setbufvar(l:buffer, 'ale_job_type', 'fixer')
|
|
||||||
|
|
||||||
while len(a:options.callback_list) > l:index
|
|
||||||
let l:Function = l:ChainCallback isnot v:null
|
let l:Function = l:ChainCallback isnot v:null
|
||||||
\ ? ale#util#GetFunction(l:ChainCallback)
|
\ ? ale#util#GetFunction(l:ChainCallback)
|
||||||
\ : a:options.callback_list[l:index]
|
\ : a:options.callback_list[l:index]
|
||||||
|
|
||||||
|
" Record new jobs started as fixer jobs.
|
||||||
|
call setbufvar(l:buffer, 'ale_job_type', 'fixer')
|
||||||
|
|
||||||
if l:ChainCallback isnot v:null
|
if l:ChainCallback isnot v:null
|
||||||
" Chained commands accept (buffer, output, [input])
|
" Chained commands accept (buffer, output, [input])
|
||||||
let l:result = ale#util#FunctionArgCount(l:Function) == 2
|
let l:result = ale#util#FunctionArgCount(l:Function) == 2
|
||||||
\ ? call(l:Function, [l:buffer, a:options.output])
|
\ ? call(l:Function, [l:buffer, a:options.output])
|
||||||
\ : call(l:Function, [l:buffer, a:options.output, copy(l:input)])
|
\ : call(l:Function, [l:buffer, a:options.output, copy(l:input)])
|
||||||
else
|
else
|
||||||
" Chained commands accept (buffer, [input])
|
" Regular fixer commands accept (buffer, [input])
|
||||||
let l:result = ale#util#FunctionArgCount(l:Function) == 1
|
let l:result = ale#util#FunctionArgCount(l:Function) == 1
|
||||||
\ ? call(l:Function, [l:buffer])
|
\ ? call(l:Function, [l:buffer])
|
||||||
\ : call(l:Function, [l:buffer, copy(l:input)])
|
\ : call(l:Function, [l:buffer, copy(l:input)])
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if type(l:result) is v:t_number && l:result == 0
|
call s:RunJob(l:result, {
|
||||||
" When `0` is returned, skip this item.
|
|
||||||
let l:index += 1
|
|
||||||
elseif type(l:result) is v:t_list
|
|
||||||
let l:input = l:result
|
|
||||||
let l:index += 1
|
|
||||||
else
|
|
||||||
let l:ChainWith = get(l:result, 'chain_with', v:null)
|
|
||||||
" Default to piping the buffer for the last fixer in the chain.
|
|
||||||
let l:read_buffer = get(l:result, 'read_buffer', l:ChainWith is v:null)
|
|
||||||
|
|
||||||
let l:job_ran = s:RunJob({
|
|
||||||
\ 'buffer': l:buffer,
|
\ 'buffer': l:buffer,
|
||||||
\ 'command': l:result.command,
|
|
||||||
\ 'input': l:input,
|
\ 'input': l:input,
|
||||||
\ 'output_stream': get(l:result, 'output_stream', 'stdout'),
|
|
||||||
\ 'read_temporary_file': get(l:result, 'read_temporary_file', 0),
|
|
||||||
\ 'read_buffer': l:read_buffer,
|
|
||||||
\ 'chain_with': l:ChainWith,
|
|
||||||
\ 'callback_list': a:options.callback_list,
|
\ 'callback_list': a:options.callback_list,
|
||||||
\ 'callback_index': l:index,
|
\ 'callback_index': l:index,
|
||||||
\ 'process_with': get(l:result, 'process_with', v:null),
|
|
||||||
\})
|
\})
|
||||||
|
|
||||||
if !l:job_ran
|
|
||||||
" The job failed to run, so skip to the next item.
|
|
||||||
let l:index += 1
|
|
||||||
else
|
|
||||||
" Stop here, we will handle exit later on.
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
endwhile
|
|
||||||
|
|
||||||
call ale#fix#ApplyFixes(l:buffer, l:input)
|
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:AddSubCallbacks(full_list, callbacks) abort
|
function! s:AddSubCallbacks(full_list, callbacks) abort
|
||||||
|
@ -180,6 +180,7 @@ Before:
|
|||||||
|
|
||||||
After:
|
After:
|
||||||
Restore
|
Restore
|
||||||
|
unlet! g:test_filename
|
||||||
unlet! g:ale_run_synchronously
|
unlet! g:ale_run_synchronously
|
||||||
unlet! g:ale_set_lists_synchronously
|
unlet! g:ale_set_lists_synchronously
|
||||||
unlet! g:ale_run_synchronously_callbacks
|
unlet! g:ale_run_synchronously_callbacks
|
||||||
@ -224,8 +225,8 @@ After:
|
|||||||
|
|
||||||
setlocal buftype=nofile
|
setlocal buftype=nofile
|
||||||
|
|
||||||
if filereadable('fix_test_file')
|
if exists('g:test_filename') && filereadable(g:test_filename)
|
||||||
call delete('fix_test_file')
|
call delete(g:test_filename)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
call setloclist(0, [])
|
call setloclist(0, [])
|
||||||
@ -479,8 +480,9 @@ Execute(ALEFix should fix files on the save event):
|
|||||||
let g:ale_lint_on_save = 1
|
let g:ale_lint_on_save = 1
|
||||||
let g:ale_enabled = 1
|
let g:ale_enabled = 1
|
||||||
|
|
||||||
noautocmd silent file fix_test_file
|
let g:test_filename = tempname()
|
||||||
call writefile(getline(1, '$'), 'fix_test_file')
|
execute 'noautocmd silent file ' . fnameescape(g:test_filename)
|
||||||
|
call writefile(getline(1, '$'), g:test_filename)
|
||||||
|
|
||||||
let g:ale_fixers.testft = ['AddDollars']
|
let g:ale_fixers.testft = ['AddDollars']
|
||||||
|
|
||||||
@ -492,8 +494,8 @@ Execute(ALEFix should fix files on the save event):
|
|||||||
call ale#test#FlushJobs()
|
call ale#test#FlushJobs()
|
||||||
|
|
||||||
" We should save the file.
|
" We should save the file.
|
||||||
AssertEqual ['$a', '$b', '$c'], readfile('fix_test_file')
|
AssertEqual ['$a', '$b', '$c'], readfile(g:test_filename)
|
||||||
Assert !&modified, 'The was marked as ''modified'''
|
Assert !&modified, 'The file was marked as ''modified'''
|
||||||
|
|
||||||
if !has('win32')
|
if !has('win32')
|
||||||
" We should have run the linter.
|
" We should have run the linter.
|
||||||
@ -520,8 +522,9 @@ Execute(ALEFix should not fix files on :wq):
|
|||||||
let g:ale_lint_on_save = 1
|
let g:ale_lint_on_save = 1
|
||||||
let g:ale_enabled = 1
|
let g:ale_enabled = 1
|
||||||
|
|
||||||
noautocmd silent file fix_test_file
|
let g:test_filename = tempname()
|
||||||
call writefile(getline(1, '$'), 'fix_test_file')
|
execute 'noautocmd silent file ' . fnameescape(g:test_filename)
|
||||||
|
call writefile(getline(1, '$'), g:test_filename)
|
||||||
|
|
||||||
let g:ale_fixers.testft = ['AddDollars']
|
let g:ale_fixers.testft = ['AddDollars']
|
||||||
|
|
||||||
@ -534,7 +537,7 @@ Execute(ALEFix should not fix files on :wq):
|
|||||||
call ale#events#SaveEvent(bufnr(''))
|
call ale#events#SaveEvent(bufnr(''))
|
||||||
|
|
||||||
" We should save the file.
|
" We should save the file.
|
||||||
AssertEqual ['a', 'b', 'c'], readfile('fix_test_file')
|
AssertEqual ['a', 'b', 'c'], readfile(g:test_filename)
|
||||||
Assert &modified, 'The was not marked as ''modified'''
|
Assert &modified, 'The was not marked as ''modified'''
|
||||||
|
|
||||||
" We should not run the linter.
|
" We should not run the linter.
|
||||||
@ -555,7 +558,8 @@ Execute(ALEFix should still lint with no linters to be applied):
|
|||||||
let g:ale_lint_on_save = 1
|
let g:ale_lint_on_save = 1
|
||||||
let g:ale_enabled = 1
|
let g:ale_enabled = 1
|
||||||
|
|
||||||
noautocmd silent file fix_test_file
|
let g:test_filename = tempname()
|
||||||
|
execute 'noautocmd silent file ' . fnameescape(g:test_filename)
|
||||||
|
|
||||||
let g:ale_fixers.testft = []
|
let g:ale_fixers.testft = []
|
||||||
|
|
||||||
@ -563,7 +567,7 @@ Execute(ALEFix should still lint with no linters to be applied):
|
|||||||
call ale#events#SaveEvent(bufnr(''))
|
call ale#events#SaveEvent(bufnr(''))
|
||||||
call ale#test#FlushJobs()
|
call ale#test#FlushJobs()
|
||||||
|
|
||||||
Assert !filereadable('fix_test_file'), 'The file should not have been saved'
|
Assert !filereadable(g:test_filename), 'The file should not have been saved'
|
||||||
|
|
||||||
if !has('win32')
|
if !has('win32')
|
||||||
" We have run the linter.
|
" We have run the linter.
|
||||||
@ -590,7 +594,8 @@ Execute(ALEFix should still lint when nothing was fixed on save):
|
|||||||
let g:ale_lint_on_save = 1
|
let g:ale_lint_on_save = 1
|
||||||
let g:ale_enabled = 1
|
let g:ale_enabled = 1
|
||||||
|
|
||||||
noautocmd silent file fix_test_file
|
let g:test_filename = tempname()
|
||||||
|
execute 'noautocmd silent file ' . fnameescape(g:test_filename)
|
||||||
|
|
||||||
let g:ale_fixers.testft = ['DoNothing']
|
let g:ale_fixers.testft = ['DoNothing']
|
||||||
|
|
||||||
@ -598,7 +603,7 @@ Execute(ALEFix should still lint when nothing was fixed on save):
|
|||||||
call ale#events#SaveEvent(bufnr(''))
|
call ale#events#SaveEvent(bufnr(''))
|
||||||
call ale#test#FlushJobs()
|
call ale#test#FlushJobs()
|
||||||
|
|
||||||
Assert !filereadable('fix_test_file'), 'The file should not have been saved'
|
Assert !filereadable(g:test_filename), 'The file should not have been saved'
|
||||||
|
|
||||||
if !has('win32')
|
if !has('win32')
|
||||||
" We should have run the linter.
|
" We should have run the linter.
|
||||||
@ -626,7 +631,8 @@ Given testft (A file with three lines):
|
|||||||
c
|
c
|
||||||
|
|
||||||
Execute(ale#fix#InitBufferData() should set up the correct data):
|
Execute(ale#fix#InitBufferData() should set up the correct data):
|
||||||
noautocmd silent file fix_test_file
|
let g:test_filename = tempname()
|
||||||
|
execute 'noautocmd silent file ' . fnameescape(g:test_filename)
|
||||||
|
|
||||||
call ale#fix#InitBufferData(bufnr(''), 'save_file')
|
call ale#fix#InitBufferData(bufnr(''), 'save_file')
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user