From 5f286eb9098a17209b8e20db87e02d7a5907c9bb Mon Sep 17 00:00:00 2001 From: FouMalade <145741792+FouMalade@users.noreply.github.com> Date: Sat, 22 Nov 2025 13:14:57 +0100 Subject: [PATCH] add unimport fixer (#5068) --- autoload/ale/fix/registry.vim | 5 ++ autoload/ale/fixers/unimport.vim | 42 +++++++++++++++++ .../fixers/test_unimport_fixer_callback.vader | 47 +++++++++++++++++++ 3 files changed, 94 insertions(+) create mode 100644 autoload/ale/fixers/unimport.vim create mode 100644 test/fixers/test_unimport_fixer_callback.vader diff --git a/autoload/ale/fix/registry.vim b/autoload/ale/fix/registry.vim index 8288b1a9..debfb88a 100644 --- a/autoload/ale/fix/registry.vim +++ b/autoload/ale/fix/registry.vim @@ -192,6 +192,11 @@ let s:default_registry = { \ 'suggested_filetypes': ['python'], \ 'description': 'Tidy Python imports with pyflyby.', \ }, +\ 'unimport': { +\ 'function': 'ale#fixers#unimport#Fix', +\ 'suggested_filetypes': ['python'], +\ 'description': 'unimport fixer', +\ }, \ 'importjs': { \ 'function': 'ale#fixers#importjs#Fix', \ 'suggested_filetypes': ['javascript'], diff --git a/autoload/ale/fixers/unimport.vim b/autoload/ale/fixers/unimport.vim new file mode 100644 index 00000000..137dd01c --- /dev/null +++ b/autoload/ale/fixers/unimport.vim @@ -0,0 +1,42 @@ +call ale#Set('python_unimport_executable', 'unimport') +call ale#Set('python_unimport_use_global', get(g:, 'ale_use_global_executables', 0)) +call ale#Set('python_unimport_options', '') +call ale#Set('python_unimport_auto_pipenv', 0) +call ale#Set('python_unimport_auto_poetry', 0) +call ale#Set('python_unimport_auto_uv', 0) + +function! ale#fixers#unimport#GetExecutable(buffer) abort + if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_unimport_auto_pipenv')) + \ && ale#python#PipenvPresent(a:buffer) + return 'pipenv' + endif + + if (ale#Var(a:buffer, 'python_auto_poetry') || ale#Var(a:buffer, 'python_unimport_auto_poetry')) + \ && ale#python#PoetryPresent(a:buffer) + return 'poetry' + endif + + if (ale#Var(a:buffer, 'python_auto_uv') || ale#Var(a:buffer, 'python_unimport_auto_uv')) + \ && ale#python#UvPresent(a:buffer) + return 'uv' + endif + + return ale#python#FindExecutable(a:buffer, 'python_unimport', ['unimport']) +endfunction + +function! ale#fixers#unimport#Fix(buffer) abort + let l:executable = ale#fixers#unimport#GetExecutable(a:buffer) + let l:cmd = [ale#Escape(l:executable)] + + if l:executable =~? '\(pipenv\|poetry\|uv\)$' + call extend(l:cmd, ['run', 'unimport']) + endif + + let l:options = ale#Var(a:buffer, 'python_unimport_options') + + if !empty(l:options) + call add(l:cmd, l:options) + endif + + return {'command': join(l:cmd, ' ')} +endfunction diff --git a/test/fixers/test_unimport_fixer_callback.vader b/test/fixers/test_unimport_fixer_callback.vader new file mode 100644 index 00000000..5f77a70b --- /dev/null +++ b/test/fixers/test_unimport_fixer_callback.vader @@ -0,0 +1,47 @@ +Before: + call ale#assert#SetUpFixerTest('python', 'unimport') + + let b:bin_dir = has('win32') ? 'Scripts' : 'bin' + +After: + call ale#assert#TearDownFixerTest() + + unlet! b:bin_dir + +Execute(The unimport callback should return the correct default values): + call ale#test#SetFilename('../test-files/python/with_virtualenv/subdir/foo/bar.py') + + AssertFixer + \ { + \ 'command': ale#Escape(ale#path#Simplify(g:dir . '/../test-files/python/with_virtualenv/env/' . b:bin_dir . '/unimport')), + \ } + +Execute(Pipenv is detected when python_unimport_auto_pipenv is set): + let g:ale_python_unimport_auto_pipenv = 1 + + call ale#test#SetFilename('../test-files/python/pipenv/whatever.py') + + AssertFixer + \ { + \ 'command': ale#Escape('pipenv') . ' run unimport' + \ } + +Execute(Poetry is detected when python_unimport_auto_poetry is set): + let g:ale_python_unimport_auto_poetry = 1 + + call ale#test#SetFilename('../test-files/python/poetry/whatever.py') + + AssertFixer + \ { + \ 'command': ale#Escape('poetry') . ' run unimport' + \ } + +Execute(uv is detected when python_unimport_auto_uv is set): + let g:ale_python_unimport_auto_uv = 1 + + call ale#test#SetFilename('../test-files/python/uv/whatever.py') + + AssertFixer + \ { + \ 'command': ale#Escape('uv') . ' run unimport' + \ }