Add commands to run ALEFix, and some tests to cover functionality so far. Add a simple autopep8 function.
This commit is contained in:
parent
7d8390d43e
commit
8ebd15a54d
@ -405,8 +405,7 @@ function! s:RunJob(options) abort
|
|||||||
\ : l:command
|
\ : l:command
|
||||||
\)
|
\)
|
||||||
|
|
||||||
" TODO, get the exit system of the shell call and pass it on here.
|
call l:job_options.exit_cb(l:job_id, v:shell_error)
|
||||||
call l:job_options.exit_cb(l:job_id, 0)
|
|
||||||
endif
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
" FIXME: Switch to using the global buffer data dictionary instead.
|
||||||
|
" Cleanup will work better if there isn't a second Dictionary we have to work
|
||||||
|
" with.
|
||||||
let s:buffer_data = {}
|
let s:buffer_data = {}
|
||||||
let s:job_info_map = {}
|
let s:job_info_map = {}
|
||||||
|
|
||||||
@ -23,8 +26,6 @@ function! ale#fix#ApplyQueuedFixes() abort
|
|||||||
return
|
return
|
||||||
endif
|
endif
|
||||||
|
|
||||||
echom l:data.output[0]
|
|
||||||
|
|
||||||
call setline(1, l:data.output)
|
call setline(1, l:data.output)
|
||||||
|
|
||||||
let l:start_line = len(l:data.output) + 1
|
let l:start_line = len(l:data.output) + 1
|
||||||
@ -145,11 +146,42 @@ function! s:RunJob(options) abort
|
|||||||
let l:job_options.out_cb = function('s:GatherOutput')
|
let l:job_options.out_cb = function('s:GatherOutput')
|
||||||
endif
|
endif
|
||||||
|
|
||||||
let l:job_id = ale#job#Start(l:command, l:job_options)
|
if get(g:, 'ale_emulate_job_failure') == 1
|
||||||
|
let l:job_id = 0
|
||||||
|
elseif get(g:, 'ale_run_synchronously') == 1
|
||||||
|
" Find a unique Job value to use, which will be the same as the ID for
|
||||||
|
" running commands synchronously. This is only for test code.
|
||||||
|
let l:job_id = len(s:job_info_map) + 1
|
||||||
|
|
||||||
" TODO: Check that the job runs, and skip to the next item if it does not.
|
while has_key(s:job_info_map, l:job_id)
|
||||||
|
let l:job_id += 1
|
||||||
|
endwhile
|
||||||
|
else
|
||||||
|
let l:job_id = ale#job#Start(l:command, l:job_options)
|
||||||
|
endif
|
||||||
|
|
||||||
|
if l:job_id == 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
let s:job_info_map[l:job_id] = l:job_info
|
let s:job_info_map[l:job_id] = l:job_info
|
||||||
|
|
||||||
|
if get(g:, 'ale_run_synchronously') == 1
|
||||||
|
" Run a command synchronously if this test option is set.
|
||||||
|
let l:output = systemlist(
|
||||||
|
\ type(l:command) == type([])
|
||||||
|
\ ? join(l:command[0:1]) . ' ' . ale#Escape(l:command[2])
|
||||||
|
\ : l:command
|
||||||
|
\)
|
||||||
|
|
||||||
|
if !l:read_temporary_file
|
||||||
|
let s:job_info_map[l:job_id].output = l:output
|
||||||
|
endif
|
||||||
|
|
||||||
|
call l:job_options.exit_cb(l:job_id, v:shell_error)
|
||||||
|
endif
|
||||||
|
|
||||||
|
return 1
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:RunFixer(options) abort
|
function! s:RunFixer(options) abort
|
||||||
@ -158,7 +190,7 @@ function! s:RunFixer(options) abort
|
|||||||
let l:index = a:options.callback_index
|
let l:index = a:options.callback_index
|
||||||
|
|
||||||
while len(a:options.callback_list) > l:index
|
while len(a:options.callback_list) > l:index
|
||||||
let l:result = function(a:options.callback_list[l:index])(l:buffer, l:input)
|
let l:result = function(a:options.callback_list[l:index])(l:buffer, copy(l:input))
|
||||||
|
|
||||||
if type(l:result) == type(0) && l:result == 0
|
if type(l:result) == type(0) && l:result == 0
|
||||||
" When `0` is returned, skip this item.
|
" When `0` is returned, skip this item.
|
||||||
@ -167,9 +199,7 @@ function! s:RunFixer(options) abort
|
|||||||
let l:input = l:result
|
let l:input = l:result
|
||||||
let l:index += 1
|
let l:index += 1
|
||||||
else
|
else
|
||||||
" TODO: Check the return value here, and skip an index if
|
let l:job_ran = s:RunJob({
|
||||||
" the job fails.
|
|
||||||
call s:RunJob({
|
|
||||||
\ 'buffer': l:buffer,
|
\ 'buffer': l:buffer,
|
||||||
\ 'command': l:result.command,
|
\ 'command': l:result.command,
|
||||||
\ 'output_stream': get(l:result, 'output_stream', 'stdout'),
|
\ 'output_stream': get(l:result, 'output_stream', 'stdout'),
|
||||||
@ -178,8 +208,13 @@ function! s:RunFixer(options) abort
|
|||||||
\ 'callback_index': l:index,
|
\ 'callback_index': l:index,
|
||||||
\})
|
\})
|
||||||
|
|
||||||
" Stop here, we will handle exit later on.
|
if !l:job_ran
|
||||||
return
|
" 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
|
endif
|
||||||
endwhile
|
endwhile
|
||||||
|
|
||||||
|
@ -35,3 +35,9 @@ function! ale#handlers#python#HandlePEP8Format(buffer, lines) abort
|
|||||||
|
|
||||||
return l:output
|
return l:output
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
function! ale#handlers#python#AutoPEP8(buffer, lines) abort
|
||||||
|
return {
|
||||||
|
\ 'command': 'autopep8 -'
|
||||||
|
\}
|
||||||
|
endfunction
|
||||||
|
@ -60,6 +60,9 @@ let g:ale_filetype_blacklist = ['nerdtree', 'unite', 'tags']
|
|||||||
" This Dictionary configures which linters are enabled for which languages.
|
" This Dictionary configures which linters are enabled for which languages.
|
||||||
let g:ale_linters = get(g:, 'ale_linters', {})
|
let g:ale_linters = get(g:, 'ale_linters', {})
|
||||||
|
|
||||||
|
" This Dictionary configures which functions will be used for fixing problems.
|
||||||
|
let g:ale_fixers = get(g:, 'ale_fixers', {})
|
||||||
|
|
||||||
" This Dictionary allows users to set up filetype aliases for new filetypes.
|
" This Dictionary allows users to set up filetype aliases for new filetypes.
|
||||||
let g:ale_linter_aliases = get(g:, 'ale_linter_aliases', {})
|
let g:ale_linter_aliases = get(g:, 'ale_linter_aliases', {})
|
||||||
|
|
||||||
@ -276,6 +279,9 @@ command! -bar ALEInfo :call ale#debugging#Info()
|
|||||||
" The same, but copy output to your clipboard.
|
" The same, but copy output to your clipboard.
|
||||||
command! -bar ALEInfoToClipboard :call ale#debugging#InfoToClipboard()
|
command! -bar ALEInfoToClipboard :call ale#debugging#InfoToClipboard()
|
||||||
|
|
||||||
|
" Fix problems in files.
|
||||||
|
command! -bar ALEFix :call ale#fix#Fix()
|
||||||
|
|
||||||
" <Plug> mappings for commands
|
" <Plug> mappings for commands
|
||||||
nnoremap <silent> <Plug>(ale_previous) :ALEPrevious<Return>
|
nnoremap <silent> <Plug>(ale_previous) :ALEPrevious<Return>
|
||||||
nnoremap <silent> <Plug>(ale_previous_wrap) :ALEPreviousWrap<Return>
|
nnoremap <silent> <Plug>(ale_previous_wrap) :ALEPreviousWrap<Return>
|
||||||
@ -284,6 +290,7 @@ nnoremap <silent> <Plug>(ale_next_wrap) :ALENextWrap<Return>
|
|||||||
nnoremap <silent> <Plug>(ale_toggle) :ALEToggle<Return>
|
nnoremap <silent> <Plug>(ale_toggle) :ALEToggle<Return>
|
||||||
nnoremap <silent> <Plug>(ale_lint) :ALELint<Return>
|
nnoremap <silent> <Plug>(ale_lint) :ALELint<Return>
|
||||||
nnoremap <silent> <Plug>(ale_detail) :ALEDetail<Return>
|
nnoremap <silent> <Plug>(ale_detail) :ALEDetail<Return>
|
||||||
|
nnoremap <silent> <Plug>(ale_fix) :ALEFix<Return>
|
||||||
|
|
||||||
" Housekeeping
|
" Housekeeping
|
||||||
|
|
||||||
|
109
test/test_ale_fix.vader
Normal file
109
test/test_ale_fix.vader
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
Before:
|
||||||
|
Save g:ale_fixers, &shell
|
||||||
|
let g:ale_run_synchronously = 1
|
||||||
|
let g:ale_fixers = {
|
||||||
|
\ 'testft': [],
|
||||||
|
\}
|
||||||
|
let &shell = '/bin/bash'
|
||||||
|
|
||||||
|
function AddCarets(buffer, lines) abort
|
||||||
|
" map() is applied to the original lines here.
|
||||||
|
" This way, we can ensure that defensive copies are made.
|
||||||
|
return map(a:lines, '''^'' . v:val')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function AddDollars(buffer, lines) abort
|
||||||
|
return map(a:lines, '''$'' . v:val')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function DoNothing(buffer, lines) abort
|
||||||
|
return 0
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function CatLine(buffer, lines) abort
|
||||||
|
return {'command': 'cat - <(echo d)'}
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function ReplaceWithTempFile(buffer, lines) abort
|
||||||
|
return {'command': 'echo x > %t', 'read_temporary_file': 1}
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
After:
|
||||||
|
Restore
|
||||||
|
unlet! g:ale_run_synchronously
|
||||||
|
unlet! g:ale_emulate_job_failure
|
||||||
|
delfunction AddCarets
|
||||||
|
delfunction AddDollars
|
||||||
|
delfunction DoNothing
|
||||||
|
delfunction CatLine
|
||||||
|
delfunction ReplaceWithTempFile
|
||||||
|
|
||||||
|
Given testft (A file with three lines):
|
||||||
|
a
|
||||||
|
b
|
||||||
|
c
|
||||||
|
|
||||||
|
Execute(ALEFix should complain when there are no functions to call):
|
||||||
|
AssertThrows ALEFix
|
||||||
|
AssertEqual 'Vim(echoerr):No fixers have been defined for filetype: testft', g:vader_exception
|
||||||
|
|
||||||
|
Execute(ALEFix should apply simple functions):
|
||||||
|
let g:ale_fixers.testft = ['AddCarets']
|
||||||
|
ALEFix
|
||||||
|
|
||||||
|
Expect(The first function should be used):
|
||||||
|
^a
|
||||||
|
^b
|
||||||
|
^c
|
||||||
|
|
||||||
|
Execute(ALEFix should apply simple functions in a chain):
|
||||||
|
let g:ale_fixers.testft = ['AddCarets', 'AddDollars']
|
||||||
|
ALEFix
|
||||||
|
|
||||||
|
Expect(Both functions should be used):
|
||||||
|
$^a
|
||||||
|
$^b
|
||||||
|
$^c
|
||||||
|
|
||||||
|
Execute(ALEFix should allow 0 to be returned to skip functions):
|
||||||
|
let g:ale_fixers.testft = ['DoNothing', 'AddDollars']
|
||||||
|
ALEFix
|
||||||
|
|
||||||
|
Expect(Only the second function should be applied):
|
||||||
|
$a
|
||||||
|
$b
|
||||||
|
$c
|
||||||
|
|
||||||
|
Execute(ALEFix should allow commands to be run):
|
||||||
|
let g:ale_fixers.testft = ['CatLine']
|
||||||
|
ALEFix
|
||||||
|
|
||||||
|
Expect(An extra line should be added):
|
||||||
|
a
|
||||||
|
b
|
||||||
|
c
|
||||||
|
d
|
||||||
|
|
||||||
|
Execute(ALEFix should allow temporary files to be read):
|
||||||
|
let g:ale_fixers.testft = ['ReplaceWithTempFile']
|
||||||
|
ALEFix
|
||||||
|
|
||||||
|
Expect(The line we wrote to the temporary file should be used here):
|
||||||
|
x
|
||||||
|
|
||||||
|
Execute(ALEFix should allow jobs and simple functions to be combined):
|
||||||
|
let g:ale_fixers.testft = ['ReplaceWithTempFile', 'AddDollars']
|
||||||
|
ALEFix
|
||||||
|
|
||||||
|
Expect(The lines from the temporary file should be modified):
|
||||||
|
$x
|
||||||
|
|
||||||
|
Execute(ALEFix should skip commands when jobs fail to run):
|
||||||
|
let g:ale_emulate_job_failure = 1
|
||||||
|
let g:ale_fixers.testft = ['CatLine', 'AddDollars']
|
||||||
|
ALEFix
|
||||||
|
|
||||||
|
Expect(Only the second function should be applied):
|
||||||
|
$a
|
||||||
|
$b
|
||||||
|
$c
|
@ -11,6 +11,7 @@ Before:
|
|||||||
\ 'valid': 1,
|
\ 'valid': 1,
|
||||||
\}]
|
\}]
|
||||||
let g:expected_groups = [
|
let g:expected_groups = [
|
||||||
|
\ 'ALEBufferFixGroup',
|
||||||
\ 'ALECleanupGroup',
|
\ 'ALECleanupGroup',
|
||||||
\ 'ALECursorGroup',
|
\ 'ALECursorGroup',
|
||||||
\ 'ALEHighlightBufferGroup',
|
\ 'ALEHighlightBufferGroup',
|
||||||
@ -101,7 +102,7 @@ Execute(ALEToggle should reset everything and then run again):
|
|||||||
AssertEqual [], getloclist(0)
|
AssertEqual [], getloclist(0)
|
||||||
AssertEqual [], ale#sign#FindCurrentSigns(bufnr('%'))
|
AssertEqual [], ale#sign#FindCurrentSigns(bufnr('%'))
|
||||||
AssertEqual [], getmatches()
|
AssertEqual [], getmatches()
|
||||||
AssertEqual ['ALECleanupGroup', 'ALEHighlightBufferGroup'], ParseAuGroups()
|
AssertEqual ['ALEBufferFixGroup', 'ALECleanupGroup', 'ALEHighlightBufferGroup'], ParseAuGroups()
|
||||||
|
|
||||||
" Toggle ALE on, everything should be set up and run again.
|
" Toggle ALE on, everything should be set up and run again.
|
||||||
ALEToggle
|
ALEToggle
|
||||||
|
@ -20,7 +20,7 @@ Execute(create-react-app directories should be detected correctly):
|
|||||||
|
|
||||||
AssertEqual
|
AssertEqual
|
||||||
\ g:dir . '/eslint-test-files/react-app/node_modules/eslint/bin/eslint.js',
|
\ g:dir . '/eslint-test-files/react-app/node_modules/eslint/bin/eslint.js',
|
||||||
\ ale_linters#javascript#eslint#GetExecutable(bufnr(''))
|
\ ale#handlers#eslint#GetExecutable(bufnr(''))
|
||||||
|
|
||||||
:q
|
:q
|
||||||
|
|
||||||
@ -31,7 +31,7 @@ Execute(use-global should override create-react-app detection):
|
|||||||
|
|
||||||
AssertEqual
|
AssertEqual
|
||||||
\ 'eslint_d',
|
\ 'eslint_d',
|
||||||
\ ale_linters#javascript#eslint#GetExecutable(bufnr(''))
|
\ ale#handlers#eslint#GetExecutable(bufnr(''))
|
||||||
|
|
||||||
:q
|
:q
|
||||||
|
|
||||||
@ -40,7 +40,7 @@ Execute(other app directories should be detected correctly):
|
|||||||
|
|
||||||
AssertEqual
|
AssertEqual
|
||||||
\ g:dir . '/eslint-test-files/node_modules/.bin/eslint',
|
\ g:dir . '/eslint-test-files/node_modules/.bin/eslint',
|
||||||
\ ale_linters#javascript#eslint#GetExecutable(bufnr(''))
|
\ ale#handlers#eslint#GetExecutable(bufnr(''))
|
||||||
|
|
||||||
:q
|
:q
|
||||||
|
|
||||||
@ -51,6 +51,6 @@ Execute(use-global should override other app directories):
|
|||||||
|
|
||||||
AssertEqual
|
AssertEqual
|
||||||
\ 'eslint_d',
|
\ 'eslint_d',
|
||||||
\ ale_linters#javascript#eslint#GetExecutable(bufnr(''))
|
\ ale#handlers#eslint#GetExecutable(bufnr(''))
|
||||||
|
|
||||||
:q
|
:q
|
||||||
|
Loading…
Reference in New Issue
Block a user