9

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?

1
  • 3
    The short answer is no. Thne longer answer is you can abstract some of it out, by testing which version of Python is available, setting a variable say py to either python or python3, and then calling that with exec py . ' print("EAT ME")'. Yeah, I never said it was nice. Commented Jun 19, 2015 at 18:13

2 Answers 2

3

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
Sign up to request clarification or add additional context in comments.

Comments

2

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.