From 7517fd82260f03cc3ab7f77c391b6f1ff7372c6a Mon Sep 17 00:00:00 2001 From: w0rp Date: Wed, 7 Jun 2017 14:02:29 +0100 Subject: [PATCH] Move all functions for fixing things to autoload/ale/fixers, and only accept the lines of input where needed. --- autoload/ale/fix.vim | 6 +-- autoload/ale/fix/registry.vim | 16 +++---- autoload/ale/fixers/autopep8.vim | 8 ++++ autoload/ale/fixers/eslint.vim | 36 ++++++++++++++ autoload/ale/{fix => fixers}/generic.vim | 0 autoload/ale/fixers/generic_python.vim | 22 +++++++++ autoload/ale/fixers/isort.vim | 13 +++++ .../ale/{handlers => fixers}/prettier.vim | 0 .../{handlers => fixers}/prettier_eslint.vim | 0 autoload/ale/fixers/yapf.vim | 13 +++++ autoload/ale/handlers/eslint.vim | 35 +------------- autoload/ale/handlers/python.vim | 48 ------------------- autoload/ale/util.vim | 27 +++++++++-- .../test_python_add_blank_lines_fixer.vader | 2 +- test/test_function_arg_count.vader | 4 ++ 15 files changed, 132 insertions(+), 98 deletions(-) create mode 100644 autoload/ale/fixers/autopep8.vim create mode 100644 autoload/ale/fixers/eslint.vim rename autoload/ale/{fix => fixers}/generic.vim (100%) create mode 100644 autoload/ale/fixers/generic_python.vim create mode 100644 autoload/ale/fixers/isort.vim rename autoload/ale/{handlers => fixers}/prettier.vim (100%) rename autoload/ale/{handlers => fixers}/prettier_eslint.vim (100%) create mode 100644 autoload/ale/fixers/yapf.vim diff --git a/autoload/ale/fix.vim b/autoload/ale/fix.vim index e7cac271..5438975b 100644 --- a/autoload/ale/fix.vim +++ b/autoload/ale/fix.vim @@ -232,11 +232,11 @@ function! s:RunFixer(options) abort let l:index = a:options.callback_index while len(a:options.callback_list) > l:index - let l:Function = ale#util#GetFunction(a:options.callback_list[l:index]) + let l:Function = a:options.callback_list[l:index] let l:result = ale#util#FunctionArgCount(l:Function) == 1 - \ ? l:Function(l:buffer) - \ : l:Function(l:buffer, copy(l:input)) + \ ? call(l:Function, [l:buffer]) + \ : call(l:Function, [l:buffer, copy(l:input)]) if type(l:result) == type(0) && l:result == 0 " When `0` is returned, skip this item. diff --git a/autoload/ale/fix/registry.vim b/autoload/ale/fix/registry.vim index 6d992c28..b1df1c08 100644 --- a/autoload/ale/fix/registry.vim +++ b/autoload/ale/fix/registry.vim @@ -3,42 +3,42 @@ let s:default_registry = { \ 'add_blank_lines_for_python_control_statements': { -\ 'function': 'ale#handlers#python#AddLinesBeforeControlStatements', +\ 'function': 'ale#fixers#generic_python#AddLinesBeforeControlStatements', \ 'suggested_filetypes': ['python'], \ 'description': 'Add blank lines before control statements.', \ }, \ 'autopep8': { -\ 'function': 'ale#handlers#python#AutoPEP8', +\ 'function': 'ale#fixers#autopep8#Fix', \ 'suggested_filetypes': ['python'], \ 'description': 'Fix PEP8 issues with autopep8.', \ }, \ 'eslint': { -\ 'function': 'ale#handlers#eslint#Fix', +\ 'function': 'ale#fixers#eslint#Fix', \ 'suggested_filetypes': ['javascript'], \ 'description': 'Apply eslint --fix to a file.', \ }, \ 'isort': { -\ 'function': 'ale#handlers#python#ISort', +\ 'function': 'ale#fixers#isort#Fix', \ 'suggested_filetypes': ['python'], \ 'description': 'Sort Python imports with isort.', \ }, \ 'prettier': { -\ 'function': 'ale#handlers#prettier#Fix', +\ 'function': 'ale#fixers#prettier#Fix', \ 'suggested_filetypes': ['javascript'], \ 'description': 'Apply prettier to a file.', \ }, \ 'prettier_eslint': { -\ 'function': 'ale#handlers#prettier_eslint#Fix', +\ 'function': 'ale#fixers#prettier_eslint#Fix', \ 'suggested_filetypes': ['javascript'], \ 'description': 'Apply prettier-eslint to a file.', \ }, \ 'remove_trailing_lines': { -\ 'function': 'ale#fix#generic#RemoveTrailingBlankLines', +\ 'function': 'ale#fixers#generic#RemoveTrailingBlankLines', \ 'suggested_filetypes': [], \ 'description': 'Remove all blank lines at the end of a file.', \ }, \ 'yapf': { -\ 'function': 'ale#handlers#python#YAPF', +\ 'function': 'ale#fixers#yapf#Fix', \ 'suggested_filetypes': ['python'], \ 'description': 'Fix Python files with yapf.', \ }, diff --git a/autoload/ale/fixers/autopep8.vim b/autoload/ale/fixers/autopep8.vim new file mode 100644 index 00000000..59130af8 --- /dev/null +++ b/autoload/ale/fixers/autopep8.vim @@ -0,0 +1,8 @@ +" Author: w0rp +" Description: Fixing files with autopep8. + +function! ale#fixers#autopep8#Fix(buffer) abort + return { + \ 'command': 'autopep8 -' + \} +endfunction diff --git a/autoload/ale/fixers/eslint.vim b/autoload/ale/fixers/eslint.vim new file mode 100644 index 00000000..e9d615ae --- /dev/null +++ b/autoload/ale/fixers/eslint.vim @@ -0,0 +1,36 @@ +" Author: w0rp +" Description: Fixing files with eslint. + +function! s:FindConfig(buffer) abort + for l:filename in [ + \ '.eslintrc.js', + \ '.eslintrc.yaml', + \ '.eslintrc.yml', + \ '.eslintrc.json', + \ '.eslintrc', + \] + let l:config = ale#path#FindNearestFile(a:buffer, l:filename) + + if !empty(l:config) + return l:config + endif + endfor + + return '' +endfunction + +function! ale#fixers#eslint#Fix(buffer) abort + let l:executable = ale#handlers#eslint#GetExecutable(a:buffer) + let l:config = s:FindConfig(a:buffer) + + if empty(l:config) + return 0 + endif + + return { + \ 'command': ale#Escape(l:executable) + \ . ' --config ' . ale#Escape(l:config) + \ . ' --fix %t', + \ 'read_temporary_file': 1, + \} +endfunction diff --git a/autoload/ale/fix/generic.vim b/autoload/ale/fixers/generic.vim similarity index 100% rename from autoload/ale/fix/generic.vim rename to autoload/ale/fixers/generic.vim diff --git a/autoload/ale/fixers/generic_python.vim b/autoload/ale/fixers/generic_python.vim new file mode 100644 index 00000000..1a4e1e93 --- /dev/null +++ b/autoload/ale/fixers/generic_python.vim @@ -0,0 +1,22 @@ +" Author: w0rp +" Description: Generic fixer functions for Python. + +" Add blank lines before control statements. +function! ale#fixers#generic_python#AddLinesBeforeControlStatements(buffer, lines) abort + let l:new_lines = [] + let l:last_indent_size = 0 + + for l:line in a:lines + let l:indent_size = len(matchstr(l:line, '^ *')) + + if l:indent_size <= l:last_indent_size + \&& match(l:line, '\v^ *(return|if|for|while|break|continue)') >= 0 + call add(l:new_lines, '') + endif + + call add(l:new_lines, l:line) + let l:last_indent_size = l:indent_size + endfor + + return l:new_lines +endfunction diff --git a/autoload/ale/fixers/isort.vim b/autoload/ale/fixers/isort.vim new file mode 100644 index 00000000..2d47434a --- /dev/null +++ b/autoload/ale/fixers/isort.vim @@ -0,0 +1,13 @@ +" Author: w0rp +" Description: Fixing Python imports with isort. + +function! ale#fixers#isort#Fix(buffer) abort + let l:config = ale#path#FindNearestFile(a:buffer, '.isort.cfg') + let l:config_options = !empty(l:config) + \ ? ' --settings-path ' . ale#Escape(l:config) + \ : '' + + return { + \ 'command': 'isort' . l:config_options . ' -', + \} +endfunction diff --git a/autoload/ale/handlers/prettier.vim b/autoload/ale/fixers/prettier.vim similarity index 100% rename from autoload/ale/handlers/prettier.vim rename to autoload/ale/fixers/prettier.vim diff --git a/autoload/ale/handlers/prettier_eslint.vim b/autoload/ale/fixers/prettier_eslint.vim similarity index 100% rename from autoload/ale/handlers/prettier_eslint.vim rename to autoload/ale/fixers/prettier_eslint.vim diff --git a/autoload/ale/fixers/yapf.vim b/autoload/ale/fixers/yapf.vim new file mode 100644 index 00000000..479fd75e --- /dev/null +++ b/autoload/ale/fixers/yapf.vim @@ -0,0 +1,13 @@ +" Author: w0rp +" Description: Fixing Python files with yapf. + +function! ale#fixers#yapf#Fix(buffer) abort + let l:config = ale#path#FindNearestFile(a:buffer, '.style.yapf') + let l:config_options = !empty(l:config) + \ ? ' --style ' . ale#Escape(l:config) + \ : '' + + return { + \ 'command': 'yapf --no-local-style' . l:config_options, + \} +endfunction diff --git a/autoload/ale/handlers/eslint.vim b/autoload/ale/handlers/eslint.vim index 080005a6..ac2d936a 100644 --- a/autoload/ale/handlers/eslint.vim +++ b/autoload/ale/handlers/eslint.vim @@ -1,5 +1,5 @@ " Author: w0rp -" Description: eslint functions for handling and fixing errors. +" Description: Functions for working with eslint, for checking or fixing files. call ale#Set('javascript_eslint_executable', 'eslint') call ale#Set('javascript_eslint_use_global', 0) @@ -11,36 +11,3 @@ function! ale#handlers#eslint#GetExecutable(buffer) abort \ 'node_modules/.bin/eslint', \]) endfunction - -function! s:FindConfig(buffer) abort - for l:filename in [ - \ '.eslintrc.js', - \ '.eslintrc.yaml', - \ '.eslintrc.yml', - \ '.eslintrc.json', - \ '.eslintrc', - \] - let l:config = ale#path#FindNearestFile(a:buffer, l:filename) - - if !empty(l:config) - return l:config - endif - endfor - - return '' -endfunction - -function! ale#handlers#eslint#Fix(buffer, lines) abort - let l:config = s:FindConfig(a:buffer) - - if empty(l:config) - return 0 - endif - - return { - \ 'command': ale#Escape(ale#handlers#eslint#GetExecutable(a:buffer)) - \ . ' --config ' . ale#Escape(l:config) - \ . ' --fix %t', - \ 'read_temporary_file': 1, - \} -endfunction diff --git a/autoload/ale/handlers/python.vim b/autoload/ale/handlers/python.vim index 419e262e..ae6f6d6c 100644 --- a/autoload/ale/handlers/python.vim +++ b/autoload/ale/handlers/python.vim @@ -45,51 +45,3 @@ function! ale#handlers#python#HandlePEP8Format(buffer, lines) abort return l:output endfunction - -" Add blank lines before control statements. -function! ale#handlers#python#AddLinesBeforeControlStatements(buffer, lines) abort - let l:new_lines = [] - let l:last_indent_size = 0 - - for l:line in a:lines - let l:indent_size = len(matchstr(l:line, '^ *')) - - if l:indent_size <= l:last_indent_size - \&& match(l:line, '\v^ *(return|if|for|while|break|continue)') >= 0 - call add(l:new_lines, '') - endif - - call add(l:new_lines, l:line) - let l:last_indent_size = l:indent_size - endfor - - return l:new_lines -endfunction - -function! ale#handlers#python#AutoPEP8(buffer, lines) abort - return { - \ 'command': 'autopep8 -' - \} -endfunction - -function! ale#handlers#python#ISort(buffer, lines) abort - let l:config = ale#path#FindNearestFile(a:buffer, '.isort.cfg') - let l:config_options = !empty(l:config) - \ ? ' --settings-path ' . ale#Escape(l:config) - \ : '' - - return { - \ 'command': 'isort' . l:config_options . ' -', - \} -endfunction - -function! ale#handlers#python#YAPF(buffer, lines) abort - let l:config = ale#path#FindNearestFile(a:buffer, '.style.yapf') - let l:config_options = !empty(l:config) - \ ? ' --style ' . ale#Escape(l:config) - \ : '' - - return { - \ 'command': 'yapf --no-local-style' . l:config_options, - \} -endfunction diff --git a/autoload/ale/util.vim b/autoload/ale/util.vim index 50f5adcf..0fc23d07 100644 --- a/autoload/ale/util.vim +++ b/autoload/ale/util.vim @@ -124,10 +124,8 @@ function! ale#util#GetMatches(lines, patterns) abort return l:matches endfunction -" Given the name of a function, a Funcref, or a lambda, return the number -" of named arguments for a function. -function! ale#util#FunctionArgCount(function) abort - let l:Function = ale#util#GetFunction(a:function) +function! s:LoadArgCount(function) abort + let l:Function = a:function redir => l:output silent! function Function @@ -142,3 +140,24 @@ function! ale#util#FunctionArgCount(function) abort return len(l:arg_list) endfunction + +" Given the name of a function, a Funcref, or a lambda, return the number +" of named arguments for a function. +function! ale#util#FunctionArgCount(function) abort + let l:Function = ale#util#GetFunction(a:function) + let l:count = s:LoadArgCount(l:Function) + + " If we failed to get the count, forcibly load the autoload file, if the + " function is an autoload function. autoload functions aren't normally + " defined until they are called. + if l:count == 0 + let l:function_name = matchlist(string(l:Function), 'function([''"]\(.\+\)[''"])')[1] + + if l:function_name =~# '#' + execute 'runtime autoload/' . join(split(l:function_name, '#')[:-2], '/') . '.vim' + let l:count = s:LoadArgCount(l:Function) + endif + endif + + return l:count +endfunction diff --git a/test/fixers/test_python_add_blank_lines_fixer.vader b/test/fixers/test_python_add_blank_lines_fixer.vader index 6a3c58da..04ae8b45 100644 --- a/test/fixers/test_python_add_blank_lines_fixer.vader +++ b/test/fixers/test_python_add_blank_lines_fixer.vader @@ -39,7 +39,7 @@ Given python(Some Python without blank lines): pass Execute(Blank lines should be added appropriately): - let g:ale_fixers = {'python': ['ale#handlers#python#AddLinesBeforeControlStatements']} + let g:ale_fixers = {'python': ['add_blank_lines_for_python_control_statements']} ALEFix Expect python(Newlines should be added): diff --git a/test/test_function_arg_count.vader b/test/test_function_arg_count.vader index 748eed33..d256c403 100644 --- a/test/test_function_arg_count.vader +++ b/test/test_function_arg_count.vader @@ -39,3 +39,7 @@ Execute(We should be able to compute the argument count for lambdas): AssertEqual 3, ale#util#FunctionArgCount({x,y,z->1}) AssertEqual 3, ale#util#FunctionArgCount({x,y,z,...->1}) endif + +Execute(We should be able to compute the argument count autoload functions not yet loaded): + AssertEqual 1, ale#util#FunctionArgCount(function('ale#fixers#yapf#Fix')) + AssertEqual 1, ale#util#FunctionArgCount('ale#fixers#yapf#Fix')