Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generic :python command in vim?

Within a vim script it is possible to embed some python code, as long as vim is built with the +python feature.

function! IcecreamInitialize()
python << EOF
class StrawberryIcecream:
    def __call__(self):
        print('EAT ME')
EOF
endfunction

However, some people have vim built with +python3 instead. This brings up some compatibility issues for vim plugins. Is there a generic command which calls whichever python version is installed on the computer?

like image 296
chtenb Avatar asked Jun 19 '15 17:06

chtenb


2 Answers

This snippet could determine which Python version we're using and switch to it(Python stands for that version installed).

if has('python')
    command! -nargs=1 Python python <args>
elseif has('python3')
    command! -nargs=1 Python python3 <args>
else
    echo "Error: Requires Vim compiled with +python or +python3"
    finish
endif

To load the python code, we first figure out its location(here under the same directory as the Vim Script):

execute "Python import sys"
execute "Python sys.path.append(r'" . expand("<sfile>:p:h") . "')"

Then check if the python module is available. If not, reload it:

Python << EOF
if 'yourModuleName' not in sys.modules:
    import yourModuleName
else:
    import imp
    # Reload python module to avoid errors when updating plugin
    yourModuleName = imp.reload(yourModuleName)
EOF

Two ways to call it:
1.

" call the whole module
execute "Python yourModuleName"

" call a function from that module
execute "Python yourModuleName.aMethod()"

2.

" Call a method using map 
vnoremap <leader> c :Python yourModuleName.aMethod()<cr> 

" Call a module or method using Vim function
vnoremap <leader> c :<c-u> <SID>yourFunctionName(visualmode())<cr>
function! s:YourFunctionName(someName)
    Python YourFunctionName.aMethod(a:someName)
    Python YourFunctionName
endfunction
like image 173
Lerner Zhang Avatar answered Oct 27 '22 13:10

Lerner Zhang


The "heredoc" (<< EOF) syntax is limited only to the script :py, :perl, etc.) commands; you can't use them with normal strings. And using line-continuation in Vim is a bit of a pain.

For this reason, I would put the Python code in a separate file, and pass this to the :py or :py3 commands.

let mycode = join(readfile(expand('~/mycode.py')), "\n")

if has('python')
    execute 'py ' . mycode
elseif has('python3')
    execute 'py3 ' . mycode
else
    echoe 'Your mother was a hamster'
endif

And the mycode.py script:

import sys
import vim
print('This is mycode', sys.version)

vim.command(':echo "Hello"')
print(vim.eval('42'))

From Python 2:

('This is mycode', '2.7.10 (default, May 26 2015, 04:16:29) \n[GCC 5.1.0]')
Hello
42

And from Python 3:

This is mycode 3.4.3 (default, Mar 25 2015, 17:13:50)
[GCC 4.9.2 20150304 (prerelease)]
Hello
42
like image 42
Martin Tournoij Avatar answered Oct 27 '22 15:10

Martin Tournoij