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..199724f 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:IsortViaSystem() + endif + + if !exists('*s:IsortViaSystem') + function! s:IsortViaSystem() + 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