From a16f2fa5ebde06b89f03a48147f742bca95eed6f Mon Sep 17 00:00:00 2001 From: Vladyslav Krylasov Date: Thu, 23 Oct 2025 12:17:42 +0300 Subject: [PATCH 1/2] Complete external Python support implementation - Add comprehensive guards to prevent script reloading issues - Implement full config override support for external Python execution - Add proper error handling and file reloading for external mode - Support both normal and visual mode mappings for external Python - Update README with examples for custom Python executable paths - Improve code organization with clear comments and structure - Ensure backward compatibility with embedded Python mode --- README.rst | 8 ++++ ftplugin/python_vimisort.vim | 80 ++++++++++++++++++++++++++++++++---- 2 files changed, 79 insertions(+), 9 deletions(-) diff --git a/README.rst b/README.rst index 3f80655..89b9cfa 100644 --- a/README.rst +++ b/README.rst @@ -57,3 +57,11 @@ You can also specify a particular Python version, so if `isort` is installed und .. code-block:: viml let g:vim_isort_python_version = 'python3' + +Or you can specify a full path to a Python executable (e.g., for a virtual environment): + +.. code-block:: viml + + let g:vim_isort_python_version = '/home/user/.local/bin/python3' + " or + let g:vim_isort_python_version = '/home/user/myproject/.venv/bin/python' diff --git a/ftplugin/python_vimisort.vim b/ftplugin/python_vimisort.vim index f48fe6d..5715262 100644 --- a/ftplugin/python_vimisort.vim +++ b/ftplugin/python_vimisort.vim @@ -1,5 +1,23 @@ +" Prevent multiple executions +if exists('b:did_vim_isort_ftplugin') + finish +endif +let b:did_vim_isort_ftplugin = 1 + +" Initialize config overrides if not already set +if !exists('g:vim_isort_config_overrides') + let g:vim_isort_config_overrides = {} +endif + +" Determine Python executable if exists('g:vim_isort_python_version') - if g:vim_isort_python_version ==? 'python2' + if g:vim_isort_python_version =~ '[/\\]' + if !executable(g:vim_isort_python_version) + throw 'Python executable not found at: ' . g:vim_isort_python_version + endif + let g:vim_isort_use_external_python = 1 + let g:vim_isort_python_path = g:vim_isort_python_version + elseif g:vim_isort_python_version ==? 'python2' command! -nargs=1 AvailablePython python let s:available_short_python = 'py' elseif g:vim_isort_python_version ==? 'python3' @@ -14,21 +32,65 @@ else command! -nargs=1 AvailablePython python let s:available_short_python = 'py' else - throw 'No python support present, vim-isort will be disabled' + throw 'No Python support present, vim-isort will be disabled' endif endif -command! Isort exec("call vimisort#init()|AvailablePython isort_file()") +" Define external isort function if needed +if exists('g:vim_isort_use_external_python') && g:vim_isort_use_external_python + if !exists(':Isort') + command! Isort call s:IsortExternal() + endif + + if !exists('*s:IsortExternal') + function! s:IsortExternal() + let l:file = expand('%:p') + if empty(l:file) + echoerr 'No file to sort' + return + endif + + " Save view and write file + let l:view = winsaveview() + write + + " Build config arguments + let l:config_args = '' + for [l:key, l:value] in items(g:vim_isort_config_overrides) + let l:config_args .= ' --' . substitute(l:key, '_', '-', 'g') . '=' . shellescape(l:value) + endfor + + " Run isort + let l:cmd = shellescape(g:vim_isort_python_path) . ' -m isort ' . l:config_args . ' ' . shellescape(l:file) + let l:output = system(l:cmd) + if v:shell_error != 0 + echoerr 'isort failed: ' . l:output + else + " Reload file and restore view safely + silent! edit! + call winrestview(l:view) + endif + endfunction + endif +else + if !exists(':Isort') + command! Isort exec("call vimisort#init()|AvailablePython isort_file()") + endif +endif + +" Default key mapping if !exists('g:vim_isort_map') let g:vim_isort_map = '' endif +" Apply key mappings if g:vim_isort_map != '' - " execute "vnoremap " . g:vim_isort_map . " :call vimisort#init()gv:" . s:available_short_python . " isort_visual()" - execute "vnoremap " . g:vim_isort_map . " call vimisort#init():" . s:available_short_python . " isort_visual()" -endif - -if !exists('g:vim_isort_config_overrides') - let g:vim_isort_config_overrides = {} + if exists('g:vim_isort_use_external_python') && g:vim_isort_use_external_python + execute "nnoremap " . g:vim_isort_map . " :Isort" + execute "vnoremap " . g:vim_isort_map . " :Isort" + else + execute "nnoremap " . g:vim_isort_map . " call vimisort#init():" . s:available_short_python . " isort_file()" + execute "vnoremap " . g:vim_isort_map . " call vimisort#init():" . s:available_short_python . " isort_visual()" + endif endif From a88f1942ea45c84d23bef177868a58318160d43e Mon Sep 17 00:00:00 2001 From: Vladyslav Krylasov Date: Thu, 23 Oct 2025 12:22:42 +0300 Subject: [PATCH 2/2] Rename IsortExternal to IsortViaSystem for clarity The function name now better describes its purpose - running isort via system() call with external Python executable rather than using Vim's embedded Python interpreter. --- ftplugin/python_vimisort.vim | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ftplugin/python_vimisort.vim b/ftplugin/python_vimisort.vim index 5715262..199724f 100644 --- a/ftplugin/python_vimisort.vim +++ b/ftplugin/python_vimisort.vim @@ -39,11 +39,11 @@ endif " Define external isort function if needed if exists('g:vim_isort_use_external_python') && g:vim_isort_use_external_python if !exists(':Isort') - command! Isort call s:IsortExternal() + command! Isort call s:IsortViaSystem() endif - if !exists('*s:IsortExternal') - function! s:IsortExternal() + if !exists('*s:IsortViaSystem') + function! s:IsortViaSystem() let l:file = expand('%:p') if empty(l:file) echoerr 'No file to sort'