Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

I'm struggling with Python in vim.
I still haven't found out how I can import a value from a python script (in a vim function) back to vim p.e.

function! myvimscript()    python << endpython     import vim, random, sys     s = vim.eval("mylist")     # do operation with variable "s" in python   endpython    " import variable "s" from above    " do operation with "s" in vimscript endfunction 

1) How can I use "s" again in vim (how can I import "s" from the python code back to vim)?

I can't find out as well how to use vim.current.buffer with a selection.

function! myvimscript()   let startline = line("'<")   let endline = line("'>")    python << endpython     start = vim.eval("startline")     end = vim.eval("endline")     cb = vim.current.buffer      l = cb[start:end]   endpython endfunction 

2) How can I assign the dynamic value "start" and "end" to "l"

like image 999
Reman Avatar asked Jul 15 '13 14:07

Reman


People also ask

Can you write Python in Vim?

The improved version of vi editor is Vim that can be used for creating or editing source codes of different types of programming or scripting languages. It is a configurable text editor and works faster than other command-based text editors. It can also work with various plugins and vimscript.


2 Answers

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.

like image 175
Kent Avatar answered Oct 05 '22 16:10

Kent


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("'<", "'>") 
like image 28
tossbyte Avatar answered Oct 05 '22 16:10

tossbyte