diff --git a/autoload/ale/fixers/autopep8.vim b/autoload/ale/fixers/autopep8.vim index 59130af8..92271336 100644 --- a/autoload/ale/fixers/autopep8.vim +++ b/autoload/ale/fixers/autopep8.vim @@ -2,7 +2,12 @@ " Description: Fixing files with autopep8. function! ale#fixers#autopep8#Fix(buffer) abort + let l:executable = ale#handlers#python#GetExecutable(a:buffer, 'autopep8') + if empty(l:executable) + return 0 + endif + return { - \ 'command': 'autopep8 -' + \ 'command': ale#Escape(l:executable) . ' -' \} endfunction diff --git a/autoload/ale/fixers/isort.vim b/autoload/ale/fixers/isort.vim index 2d47434a..04830b28 100644 --- a/autoload/ale/fixers/isort.vim +++ b/autoload/ale/fixers/isort.vim @@ -2,12 +2,17 @@ " Description: Fixing Python imports with isort. function! ale#fixers#isort#Fix(buffer) abort + let l:executable = ale#handlers#python#GetExecutable(a:buffer, 'isort') + if empty(l:executable) + return 0 + endif + 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 . ' -', + \ 'command': ale#Escape(l:executable) . l:config_options . ' -', \} endfunction diff --git a/autoload/ale/fixers/yapf.vim b/autoload/ale/fixers/yapf.vim index 479fd75e..46da4081 100644 --- a/autoload/ale/fixers/yapf.vim +++ b/autoload/ale/fixers/yapf.vim @@ -2,12 +2,17 @@ " Description: Fixing Python files with yapf. function! ale#fixers#yapf#Fix(buffer) abort + let l:executable = ale#handlers#python#GetExecutable(a:buffer, 'yapf') + if empty(l:executable) + return 0 + endif + 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, + \ 'command': ale#Escape(l:executable) . ' --no-local-style' . l:config_options, \} endfunction diff --git a/autoload/ale/handlers/python.vim b/autoload/ale/handlers/python.vim index ae6f6d6c..58e7d757 100644 --- a/autoload/ale/handlers/python.vim +++ b/autoload/ale/handlers/python.vim @@ -45,3 +45,24 @@ function! ale#handlers#python#HandlePEP8Format(buffer, lines) abort return l:output endfunction + +" Given a buffer number and a command name, find the path to the executable. +" First search on a virtualenv for Python, if nothing is found, try the global +" command. Returns an empty string if cannot find the executable +function! ale#handlers#python#GetExecutable(buffer, cmd_name) abort + let l:virtualenv = ale#python#FindVirtualenv(a:buffer) + + if !empty(l:virtualenv) + let l:ve_executable = l:virtualenv . '/bin/' . a:cmd_name + + if executable(l:ve_executable) + return l:ve_executable + endif + endif + + if executable(a:cmd_name) + return a:cmd_name + endif + + return '' +endfunction diff --git a/test/command_callback/python_paths/with_virtualenv/env/bin/autopep8 b/test/command_callback/python_paths/with_virtualenv/env/bin/autopep8 new file mode 100755 index 00000000..e69de29b diff --git a/test/command_callback/python_paths/with_virtualenv/env/bin/isort b/test/command_callback/python_paths/with_virtualenv/env/bin/isort new file mode 100755 index 00000000..e69de29b diff --git a/test/command_callback/python_paths/with_virtualenv/env/bin/yapf b/test/command_callback/python_paths/with_virtualenv/env/bin/yapf new file mode 100755 index 00000000..e69de29b diff --git a/test/fixers/test_python_fixer_command_callback.vader b/test/fixers/test_python_fixer_command_callback.vader new file mode 100644 index 00000000..59135d38 --- /dev/null +++ b/test/fixers/test_python_fixer_command_callback.vader @@ -0,0 +1,58 @@ +Before: + silent! execute 'cd /testplugin/test/command_callback' + let g:dir = getcwd() + +After: + " Set the file to something else, + " or we'll cause issues when running other tests + silent file 'dummy.py' + unlet! g:dir + +Execute(The python GetExecutable callbacks should return the correct path): + AssertEqual + \ '', + \ ale#handlers#python#GetExecutable(bufnr(''), 'isort') + + silent execute 'file ' . fnameescape(g:dir . '/python_paths/with_virtualenv/subdir/foo/bar.py') + AssertEqual + \ g:dir . '/python_paths/with_virtualenv/env/bin/isort', + \ ale#handlers#python#GetExecutable(bufnr(''), 'isort') + AssertEqual + \ g:dir . '/python_paths/with_virtualenv/env/bin/autopep8', + \ ale#handlers#python#GetExecutable(bufnr(''), 'autopep8') + AssertEqual + \ g:dir . '/python_paths/with_virtualenv/env/bin/yapf', + \ ale#handlers#python#GetExecutable(bufnr(''), 'yapf') + + +Execute(The autopep8 callbacks should return the correct default values): + AssertEqual + \ 0, + \ ale#fixers#autopep8#Fix(bufnr('')) + + silent execute 'file ' . fnameescape(g:dir . '/python_paths/with_virtualenv/subdir/foo/bar.py') + AssertEqual + \ {'command': "'" . g:dir . "/python_paths/with_virtualenv/env/bin/autopep8' -" }, + \ ale#fixers#autopep8#Fix(bufnr('')) + + +Execute(The isort callbacks should return the correct default values): + AssertEqual + \ 0, + \ ale#fixers#isort#Fix(bufnr('')) + + silent execute 'file ' . fnameescape(g:dir . '/python_paths/with_virtualenv/subdir/foo/bar.py') + AssertEqual + \ {'command': "'" . g:dir . "/python_paths/with_virtualenv/env/bin/isort' -" }, + \ ale#fixers#isort#Fix(bufnr('')) + + +Execute(The yapf callbacks should return the correct default values): + AssertEqual + \ 0, + \ ale#fixers#yapf#Fix(bufnr('')) + + silent execute 'file ' . fnameescape(g:dir . '/python_paths/with_virtualenv/subdir/foo/bar.py') + AssertEqual + \ {'command': "'" . g:dir . "/python_paths/with_virtualenv/env/bin/yapf' --no-local-style" }, + \ ale#fixers#yapf#Fix(bufnr(''))