Using Python in vimscript: How to export a value from a python script back to vim?

First of all, please define your function name starting with uppercase.

Here is an example for your two questions. I hope it helps:

function! TestPy() range

    let startline = line("'<")
    let endline = line("'>")
    echo "vim-start:".startline . " vim-endline:".endline
python << EOF
import vim
s = "I was set in python"
vim.command("let sInVim = '%s'"% s)
start = vim.eval("startline")
end = vim.eval("endline")
print "start, end in python:%s,%s"% (start, end)
EOF
    echo sInVim
endfunction

first I paste the output of a small test: I visual selected 3,4,5, three lines, and :call TestPy()

The output I had:

vim-start:3 vim-endline:5
start, end in python:3,5
I was set in python

So I explain the output a bit, you may need to read the example function codes a little for understanding the comment below.

vim-start:3 vim-endline:5   #this line was printed in vim,  by vim's echo.
start, end in python:3,5    # this line was prrinted in py, using the vim var startline and endline. this answered your question two.
I was set in python         # this line was printed in vim, the variable value was set in python. it answered your question one.

I added a range for your function. because, if you don't have it, for each visual-selected line, vim will call your function once. in my example, the function will be executed 3 times (3,4,5). with range, it will handle visualselection as a range. It is sufficient for this example. If your real function will do something else, you could remove the range.

With range, better with a:firstline and a:lastline. I used the line("'<") just for keep it same as your codes.

EDIT with list variable:

check this function:

function! TestPy2()
python << EOF
import vim
s = range(10)
vim.command("let sInVim = %s"% s)
EOF
    echo type(sInVim)
    echo sInVim
endfunction

if you call it, the output is:

3
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

the "3" means type list (check type() function). and one line below is the string representation of list.


As of v7.3.569, vim built-in functions pyeval() and py3eval() allow you to evaluate a python expression, and return its result as a vimscript value. It can handle simple scalar values, but also lists and dictionaries - see :help pyeval()

On 1): For using a python-defined variable in vim:

python << endPython
py_var = 8
endPython

let vim_var = pyeval('py_var')

On 2): I assume you want the buffer lines last highlighted in visual mode, as a list of strings in vimscript:

python << endPython
import vim
cb = vim.current.buffer
start = int(vim.eval("""line("'<")"""))
end = int(vim.eval("""line("'>")"""))
lines = cb[(start - 1) : end]
endPython
let lines = pyeval('lines')

Note: This is a somewhat contrived example, as you could get the same directly in vimscript:

let lines = getline("'<", "'>")