Move all functions for fixing things to autoload/ale/fixers, and only accept the lines of input where needed.
This commit is contained in:
parent
edddb1910b
commit
7517fd8226
15 changed files with 132 additions and 98 deletions
|
@ -232,11 +232,11 @@ 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: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
|
let l:result = ale#util#FunctionArgCount(l:Function) == 1
|
||||||
\ ? l:Function(l:buffer)
|
\ ? call(l:Function, [l:buffer])
|
||||||
\ : l:Function(l:buffer, copy(l:input))
|
\ : call(l:Function, [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.
|
||||||
|
|
|
@ -3,42 +3,42 @@
|
||||||
|
|
||||||
let s:default_registry = {
|
let s:default_registry = {
|
||||||
\ 'add_blank_lines_for_python_control_statements': {
|
\ 'add_blank_lines_for_python_control_statements': {
|
||||||
\ 'function': 'ale#handlers#python#AddLinesBeforeControlStatements',
|
\ 'function': 'ale#fixers#generic_python#AddLinesBeforeControlStatements',
|
||||||
\ 'suggested_filetypes': ['python'],
|
\ 'suggested_filetypes': ['python'],
|
||||||
\ 'description': 'Add blank lines before control statements.',
|
\ 'description': 'Add blank lines before control statements.',
|
||||||
\ },
|
\ },
|
||||||
\ 'autopep8': {
|
\ 'autopep8': {
|
||||||
\ 'function': 'ale#handlers#python#AutoPEP8',
|
\ 'function': 'ale#fixers#autopep8#Fix',
|
||||||
\ 'suggested_filetypes': ['python'],
|
\ 'suggested_filetypes': ['python'],
|
||||||
\ 'description': 'Fix PEP8 issues with autopep8.',
|
\ 'description': 'Fix PEP8 issues with autopep8.',
|
||||||
\ },
|
\ },
|
||||||
\ 'eslint': {
|
\ 'eslint': {
|
||||||
\ 'function': 'ale#handlers#eslint#Fix',
|
\ 'function': 'ale#fixers#eslint#Fix',
|
||||||
\ 'suggested_filetypes': ['javascript'],
|
\ 'suggested_filetypes': ['javascript'],
|
||||||
\ 'description': 'Apply eslint --fix to a file.',
|
\ 'description': 'Apply eslint --fix to a file.',
|
||||||
\ },
|
\ },
|
||||||
\ 'isort': {
|
\ 'isort': {
|
||||||
\ 'function': 'ale#handlers#python#ISort',
|
\ 'function': 'ale#fixers#isort#Fix',
|
||||||
\ 'suggested_filetypes': ['python'],
|
\ 'suggested_filetypes': ['python'],
|
||||||
\ 'description': 'Sort Python imports with isort.',
|
\ 'description': 'Sort Python imports with isort.',
|
||||||
\ },
|
\ },
|
||||||
\ 'prettier': {
|
\ 'prettier': {
|
||||||
\ 'function': 'ale#handlers#prettier#Fix',
|
\ 'function': 'ale#fixers#prettier#Fix',
|
||||||
\ 'suggested_filetypes': ['javascript'],
|
\ 'suggested_filetypes': ['javascript'],
|
||||||
\ 'description': 'Apply prettier to a file.',
|
\ 'description': 'Apply prettier to a file.',
|
||||||
\ },
|
\ },
|
||||||
\ 'prettier_eslint': {
|
\ 'prettier_eslint': {
|
||||||
\ 'function': 'ale#handlers#prettier_eslint#Fix',
|
\ 'function': 'ale#fixers#prettier_eslint#Fix',
|
||||||
\ 'suggested_filetypes': ['javascript'],
|
\ 'suggested_filetypes': ['javascript'],
|
||||||
\ 'description': 'Apply prettier-eslint to a file.',
|
\ 'description': 'Apply prettier-eslint to a file.',
|
||||||
\ },
|
\ },
|
||||||
\ 'remove_trailing_lines': {
|
\ 'remove_trailing_lines': {
|
||||||
\ 'function': 'ale#fix#generic#RemoveTrailingBlankLines',
|
\ 'function': 'ale#fixers#generic#RemoveTrailingBlankLines',
|
||||||
\ 'suggested_filetypes': [],
|
\ 'suggested_filetypes': [],
|
||||||
\ 'description': 'Remove all blank lines at the end of a file.',
|
\ 'description': 'Remove all blank lines at the end of a file.',
|
||||||
\ },
|
\ },
|
||||||
\ 'yapf': {
|
\ 'yapf': {
|
||||||
\ 'function': 'ale#handlers#python#YAPF',
|
\ 'function': 'ale#fixers#yapf#Fix',
|
||||||
\ 'suggested_filetypes': ['python'],
|
\ 'suggested_filetypes': ['python'],
|
||||||
\ 'description': 'Fix Python files with yapf.',
|
\ 'description': 'Fix Python files with yapf.',
|
||||||
\ },
|
\ },
|
||||||
|
|
8
autoload/ale/fixers/autopep8.vim
Normal file
8
autoload/ale/fixers/autopep8.vim
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
" Author: w0rp <devw0rp@gmail.com>
|
||||||
|
" Description: Fixing files with autopep8.
|
||||||
|
|
||||||
|
function! ale#fixers#autopep8#Fix(buffer) abort
|
||||||
|
return {
|
||||||
|
\ 'command': 'autopep8 -'
|
||||||
|
\}
|
||||||
|
endfunction
|
36
autoload/ale/fixers/eslint.vim
Normal file
36
autoload/ale/fixers/eslint.vim
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
" Author: w0rp <devw0rp@gmail.com>
|
||||||
|
" 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
|
22
autoload/ale/fixers/generic_python.vim
Normal file
22
autoload/ale/fixers/generic_python.vim
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
" Author: w0rp <devw0rp@gmail.com>
|
||||||
|
" 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
|
13
autoload/ale/fixers/isort.vim
Normal file
13
autoload/ale/fixers/isort.vim
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
" Author: w0rp <devw0rp@gmail.com>
|
||||||
|
" 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
|
13
autoload/ale/fixers/yapf.vim
Normal file
13
autoload/ale/fixers/yapf.vim
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
" Author: w0rp <devw0rp@gmail.com>
|
||||||
|
" 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
|
|
@ -1,5 +1,5 @@
|
||||||
" Author: w0rp <devw0rp@gmail.com>
|
" Author: w0rp <devw0rp@gmail.com>
|
||||||
" 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_executable', 'eslint')
|
||||||
call ale#Set('javascript_eslint_use_global', 0)
|
call ale#Set('javascript_eslint_use_global', 0)
|
||||||
|
@ -11,36 +11,3 @@ function! ale#handlers#eslint#GetExecutable(buffer) abort
|
||||||
\ 'node_modules/.bin/eslint',
|
\ 'node_modules/.bin/eslint',
|
||||||
\])
|
\])
|
||||||
endfunction
|
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
|
|
||||||
|
|
|
@ -45,51 +45,3 @@ function! ale#handlers#python#HandlePEP8Format(buffer, lines) abort
|
||||||
|
|
||||||
return l:output
|
return l:output
|
||||||
endfunction
|
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
|
|
||||||
|
|
|
@ -124,10 +124,8 @@ function! ale#util#GetMatches(lines, patterns) abort
|
||||||
return l:matches
|
return l:matches
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
" Given the name of a function, a Funcref, or a lambda, return the number
|
function! s:LoadArgCount(function) abort
|
||||||
" of named arguments for a function.
|
let l:Function = a:function
|
||||||
function! ale#util#FunctionArgCount(function) abort
|
|
||||||
let l:Function = ale#util#GetFunction(a:function)
|
|
||||||
|
|
||||||
redir => l:output
|
redir => l:output
|
||||||
silent! function Function
|
silent! function Function
|
||||||
|
@ -142,3 +140,24 @@ function! ale#util#FunctionArgCount(function) abort
|
||||||
|
|
||||||
return len(l:arg_list)
|
return len(l:arg_list)
|
||||||
endfunction
|
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
|
||||||
|
|
|
@ -39,7 +39,7 @@ Given python(Some Python without blank lines):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
Execute(Blank lines should be added appropriately):
|
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
|
ALEFix
|
||||||
|
|
||||||
Expect python(Newlines should be added):
|
Expect python(Newlines should be added):
|
||||||
|
|
|
@ -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})
|
||||||
AssertEqual 3, ale#util#FunctionArgCount({x,y,z,...->1})
|
AssertEqual 3, ale#util#FunctionArgCount({x,y,z,...->1})
|
||||||
endif
|
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')
|
||||||
|
|
Reference in a new issue