diff --git a/autoload/ale/fix.vim b/autoload/ale/fix.vim index 197a186..03855ef 100644 --- a/autoload/ale/fix.vim +++ b/autoload/ale/fix.vim @@ -356,8 +356,10 @@ function! s:RunFixer(options) abort call ale#fix#ApplyFixes(l:buffer, l:input) endfunction -function! s:GetCallbacks(buffer) abort - if type(get(b:, 'ale_fixers')) is type([]) +function! s:GetCallbacks(buffer, linters) abort + if len(a:linters) + let l:callback_list = a:linters + elseif type(get(b:, 'ale_fixers')) is type([]) " Lists can be used for buffer-local variables only let l:callback_list = b:ale_fixers else @@ -422,13 +424,13 @@ endfunction " Accepts an optional argument for what to do when fixing. " " Returns 0 if no fixes can be applied, and 1 if fixing can be done. -function! ale#fix#Fix(buffer, fixing_flag) abort +function! ale#fix#Fix(buffer, fixing_flag, ...) abort if a:fixing_flag isnot# '' && a:fixing_flag isnot# 'save_file' throw "fixing_flag must be either '' or 'save_file'" endif try - let l:callback_list = s:GetCallbacks(a:buffer) + let l:callback_list = s:GetCallbacks(a:buffer, a:000) catch /E700\|BADNAME/ let l:function_name = join(split(split(v:exception, ':')[3])) let l:echo_message = printf( diff --git a/autoload/ale/fix/registry.vim b/autoload/ale/fix/registry.vim index 86a1090..d12cf0d 100644 --- a/autoload/ale/fix/registry.vim +++ b/autoload/ale/fix/registry.vim @@ -277,6 +277,14 @@ function! s:ShouldSuggestForType(suggested_filetypes, type_list) abort return 0 endfunction +function! s:IsGenericFixer(suggested_filetypes) abort + if empty(a:suggested_filetypes) + return 1 + endif + + return 0 +endfunction + function! s:FormatEntry(key, entry) abort let l:aliases_str = '' @@ -296,6 +304,27 @@ function! s:FormatEntry(key, entry) abort \) endfunction +" Get list of applicable fixers for filetype, including generic fixers +function! ale#fix#registry#GetApplicableFixers(filetype) abort + let l:type_list = split(a:filetype, '\.') + let l:fixer_name_list = [] + + for l:key in sort(keys(s:entries)) + let l:suggested_filetypes = s:entries[l:key].suggested_filetypes + + if s:IsGenericFixer(l:suggested_filetypes) || s:ShouldSuggestForType(l:suggested_filetypes, l:type_list) + call add(l:fixer_name_list, l:key) + endif + endfor + + return l:fixer_name_list +endfunction + +" Function that returns autocomplete candidates for ALEFix command +function! ale#fix#registry#CompleteFixers(ArgLead, CmdLine, CursorPos) abort + return ale#fix#registry#GetApplicableFixers(&filetype) +endfunction + " Suggest functions to use from the registry. function! ale#fix#registry#Suggest(filetype) abort let l:type_list = split(a:filetype, '\.') @@ -315,7 +344,7 @@ function! ale#fix#registry#Suggest(filetype) abort let l:generic_fixer_list = [] for l:key in sort(keys(s:entries)) - if empty(s:entries[l:key].suggested_filetypes) + if s:IsGenericFixer(s:entries[l:key].suggested_filetypes) call add( \ l:generic_fixer_list, \ s:FormatEntry(l:key, s:entries[l:key]), diff --git a/doc/ale.txt b/doc/ale.txt index 0757101..5931311 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -473,10 +473,12 @@ ftplugin files for different filetypes. =============================================================================== 4. Fixing Problems *ale-fix* -ALE can fix problems with files with the |ALEFix| command. When |ALEFix| is -run, the variable |g:ale_fixers| will be read for getting a |List| of commands -for filetypes, split on `.`, and the functions named in |g:ale_fixers| will be -executed for fixing the errors. +ALE can fix problems with files with the |ALEFix| command. |ALEFix| +accepts names of fixers to be applied as arguments. Alternatively, +when no arguments are provided, the variable |g:ale_fixers| will be +read for getting a |List| of commands for filetypes, split on `.`, and +the functions named in |g:ale_fixers| will be executed for fixing the +errors. The |ALEFixSuggest| command can be used to suggest tools that be used to fix problems for the current buffer. diff --git a/plugin/ale.vim b/plugin/ale.vim index d64229b..3f157bc 100644 --- a/plugin/ale.vim +++ b/plugin/ale.vim @@ -263,7 +263,7 @@ command! -bar ALEInfoToClipboard :call ale#debugging#InfoToClipboard() command! -bar -nargs=1 ALEInfoToFile :call ale#debugging#InfoToFile() " Fix problems in files. -command! -bar ALEFix :call ale#fix#Fix(bufnr(''), '') +command! -bar -nargs=* -complete=customlist,ale#fix#registry#CompleteFixers ALEFix :call ale#fix#Fix(bufnr(''), '', ) " Suggest registered functions to use for fixing problems. command! -bar ALEFixSuggest :call ale#fix#registry#Suggest(&filetype) diff --git a/test/fix/test_ale_fix.vader b/test/fix/test_ale_fix.vader index 0321cba..3bd2367 100644 --- a/test/fix/test_ale_fix.vader +++ b/test/fix/test_ale_fix.vader @@ -272,6 +272,15 @@ Expect(An extra line should be added): c d +Execute(ALEFix should use fixers passed in commandline when provided): + let g:ale_fixers.testft = ['RemoveLastLine'] + ALEFix AddCarets AddDollars + +Expect(Only fixers passed via command line should be run): + $^a + $^b + $^c + Execute(ALEFix should allow temporary files to be read): if has('win32') " Just skip this test on Windows, we can't run it. diff --git a/test/fix/test_ale_fix_completion.vader b/test/fix/test_ale_fix_completion.vader new file mode 100644 index 0000000..6c38bb8 --- /dev/null +++ b/test/fix/test_ale_fix_completion.vader @@ -0,0 +1,23 @@ +Execute (List of available fixers is empty): + call ale#fix#registry#Clear() + +Then (List of applicable fixers for python file is empty): + AssertEqual [], ale#fix#registry#GetApplicableFixers('python') + +Execute (Add ruby fixer): + call ale#fix#registry#Add('ruby_fixer', 'fixer_fun', ['ruby'], 'ruby fixer') + +Then (List of applicable fixers for python file is still empty): + AssertEqual [], ale#fix#registry#GetApplicableFixers('python') + +Execute (Add generic fixer): + call ale#fix#registry#Add('generic_fixer', 'fixer_fun', [], 'generic fixer') + +Then (Generic fixer should be returned as applicable for python file): + AssertEqual ['generic_fixer'], ale#fix#registry#GetApplicableFixers('python') + +Execute (Add python fixer): + call ale#fix#registry#Add('python_fixer', 'fixer_func', ['python'], 'python fixer') + +Then (List of fixers should contain both generic and python fixers): + AssertEqual ['generic_fixer', 'python_fixer'], ale#fix#registry#GetApplicableFixers('python')