summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorw0rp <devw0rp@gmail.com>2019-02-26 08:35:58 +0000
committerw0rp <devw0rp@gmail.com>2019-02-26 08:35:58 +0000
commit70a9176de0a4fd821fa60d5324ff0a3b5c086e5c (patch)
treefa546e52e44cc6d8065a0b775428374b08327086
parent89e54918623f6ed42beed5c7c33bee796676449c (diff)
downloadale-70a9176de0a4fd821fa60d5324ff0a3b5c086e5c.zip
#2132 - Set up fixers for deferred support
-rw-r--r--autoload/ale/fix.vim140
-rw-r--r--test/fix/test_ale_fix.vader34
2 files changed, 92 insertions, 82 deletions
diff --git a/autoload/ale/fix.vim b/autoload/ale/fix.vim
index a14638c7..b8674606 100644
--- a/autoload/ale/fix.vim
+++ b/autoload/ale/fix.vim
@@ -131,35 +131,55 @@ function! s:HandleExit(job_info, buffer, job_output, data) abort
\})
endfunction
-function! s:RunJob(options) abort
+function! s:RunJob(result, options) abort
+ if ale#command#IsDeferred(a:result)
+ let a:result.result_callback = {x -> s:RunJob(x, a:options)}
+
+ return
+ endif
+
let l:buffer = a:options.buffer
- let l:command = a:options.command
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)
- " If there's nothing further to chain the command with, stop here.
- if l:ChainWith is v:null
- return v:false
+ 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
- " If there's another chained callback to run, then run that.
call s:RunFixer({
\ 'buffer': l:buffer,
\ '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,
\ 'chain_callback': l:ChainWith,
\ 'output': [],
\})
- return v:true
+ return
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'
endif
@@ -168,10 +188,10 @@ function! s:RunJob(options) abort
\ '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,
+ \ 'process_with': get(a:result, 'process_with', v:null),
+ \ '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,
\ 'executable': '',
\ 'read_buffer': l:read_buffer,
@@ -179,70 +199,54 @@ function! s:RunJob(options) abort
\ '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
function! s:RunFixer(options) abort
let l:buffer = a:options.buffer
let l:input = a:options.input
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:Function = l:ChainCallback isnot v:null
+ \ ? ale#util#GetFunction(l:ChainCallback)
+ \ : a:options.callback_list[l:index]
+
" 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
- \ ? ale#util#GetFunction(l:ChainCallback)
- \ : a:options.callback_list[l:index]
-
- if l:ChainCallback isnot v:null
- " Chained commands accept (buffer, output, [input])
- 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, copy(l:input)])
- else
- " Chained commands accept (buffer, [input])
- let l:result = ale#util#FunctionArgCount(l:Function) == 1
- \ ? call(l:Function, [l:buffer])
- \ : call(l:Function, [l:buffer, copy(l:input)])
- endif
-
- if type(l:result) is v:t_number && l:result == 0
- " 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,
- \ 'command': l:result.command,
- \ '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_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
+ if l:ChainCallback isnot v:null
+ " Chained commands accept (buffer, output, [input])
+ 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, copy(l:input)])
+ else
+ " Regular fixer commands accept (buffer, [input])
+ let l:result = ale#util#FunctionArgCount(l:Function) == 1
+ \ ? call(l:Function, [l:buffer])
+ \ : call(l:Function, [l:buffer, copy(l:input)])
+ endif
- call ale#fix#ApplyFixes(l:buffer, l:input)
+ call s:RunJob(l:result, {
+ \ 'buffer': l:buffer,
+ \ 'input': l:input,
+ \ 'callback_list': a:options.callback_list,
+ \ 'callback_index': l:index,
+ \})
endfunction
function! s:AddSubCallbacks(full_list, callbacks) abort
diff --git a/test/fix/test_ale_fix.vader b/test/fix/test_ale_fix.vader
index bf18345d..e5ecd46c 100644
--- a/test/fix/test_ale_fix.vader
+++ b/test/fix/test_ale_fix.vader
@@ -180,6 +180,7 @@ Before:
After:
Restore
+ unlet! g:test_filename
unlet! g:ale_run_synchronously
unlet! g:ale_set_lists_synchronously
unlet! g:ale_run_synchronously_callbacks
@@ -224,8 +225,8 @@ After:
setlocal buftype=nofile
- if filereadable('fix_test_file')
- call delete('fix_test_file')
+ if exists('g:test_filename') && filereadable(g:test_filename)
+ call delete(g:test_filename)
endif
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_enabled = 1
- noautocmd silent file fix_test_file
- call writefile(getline(1, '$'), 'fix_test_file')
+ let g:test_filename = tempname()
+ execute 'noautocmd silent file ' . fnameescape(g:test_filename)
+ call writefile(getline(1, '$'), g:test_filename)
let g:ale_fixers.testft = ['AddDollars']
@@ -492,8 +494,8 @@ Execute(ALEFix should fix files on the save event):
call ale#test#FlushJobs()
" We should save the file.
- AssertEqual ['$a', '$b', '$c'], readfile('fix_test_file')
- Assert !&modified, 'The was marked as ''modified'''
+ AssertEqual ['$a', '$b', '$c'], readfile(g:test_filename)
+ Assert !&modified, 'The file was marked as ''modified'''
if !has('win32')
" 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_enabled = 1
- noautocmd silent file fix_test_file
- call writefile(getline(1, '$'), 'fix_test_file')
+ let g:test_filename = tempname()
+ execute 'noautocmd silent file ' . fnameescape(g:test_filename)
+ call writefile(getline(1, '$'), g:test_filename)
let g:ale_fixers.testft = ['AddDollars']
@@ -534,7 +537,7 @@ Execute(ALEFix should not fix files on :wq):
call ale#events#SaveEvent(bufnr(''))
" 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'''
" 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_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 = []
@@ -563,7 +567,7 @@ Execute(ALEFix should still lint with no linters to be applied):
call ale#events#SaveEvent(bufnr(''))
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')
" 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_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']
@@ -598,7 +603,7 @@ Execute(ALEFix should still lint when nothing was fixed on save):
call ale#events#SaveEvent(bufnr(''))
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')
" We should have run the linter.
@@ -626,7 +631,8 @@ Given testft (A file with three lines):
c
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')