How can you use Python in Vim?

Question:

I waste a lot of time between Vim and Python. I find it too slow to manually copy-paste from Python to Vim and vice versa. A good broken example is:

%!python for i in xrange(25); print 6*i n

How can you do such tweaks direcly in Vim? [Solved]

[Clarification] I need things to Vim, like printing sequences, arithmetics… – things I cannot do in Vim.

[?] Can someone elaborate this point:
“your script can read from stdin to operate directly on the lines given (., %, …).

[Further Clarification]

If I want to print ‘Hello’ to lines 4,5, 6 and 7, what is wrong:

:4-7!python -c “print ‘hello'”

The dot . modifies the current line. Can I print on multiple lines 7, 32 and 99:

:7,32,99!python -c “print ‘hello'”

Clearly not working. How?

Answers:

From your example, it appears as though you want to execute a Python script and have the output of the script appear in the current Vim buffer. If that’s correct, then you can do the following at the command line in Vim:

%!python -c "for i in xrange(25): print 6*i"

The -c option to python gives it a script to run. However, you may find this technique useful only in very short cases, because unlike some other languages, Python does not lend itself well to writing complete programs all on one line.

Answered By: Greg Hewgill

I think you’t just missing the -c flag. For example:

:.!python -c "print 'hello'"

You should not that the script that you provide acts as a filter on the line selection. That is, your script can read from stdin to operate directly on the lines given (., %, …). Anything more than the simplest tasks, however, and you’d be better off putting the python commands into a script file of its own.

Answered By: Martin Carpenter

In any of your vim windows, type something like this:

for x in range(1,10):
    print '-> %d' % x

Visually select both of those lines (V to start visual mode), and type the following:

:!python

Because you pressed ‘:’ in visual mode, that will end up looking like:

:'<,'>!python

Hit enter and the selection is replaced by the output of the print statements. You could easily turn it into a mapping:

:vnoremap <f5> :!python<CR>
Answered By: too much php

Can someone elaborate this point: “your script can read from stdin to operate directly on the lines given (., %, …).”

One common use is to sort lines of text using the ‘sort’ command available in your shell. For example, you can sort the whole file using this command:

:%!sort

Or, you could sort just a few lines by selecting them in visual mode and then typing:

:!sort

You could sort lines 5-10 using this command:

:5,10!sort

You could write your own command-line script (presuming you know how to do that) which reverses lines of text. It works like this:

bash$ myreverse 'hello world!'
!dlrow olleh

You could apply it to one of your open files in vim in exactly the same way you used sort:

:%!myreverse      <- all lines in your file are reversed
Answered By: too much php

If I want to print ‘Hello’ to lines 4,5, 6 and 7, what is wrong:

If you want to do something in randomly chosen places throughout your file, you’re better of recording keystrokes and replaying them. Go to the first line you want to change, and hit qz to starting recording into register z. Do whatever edits you want for that line and hit q again when you’re finished. Go to the next line you want to change and press @z to replay the macro.

Answered By: too much php

If you want to do some python calls without compiling vim with the python interpreter (that would allow you to write plug-ins in Python, and it’s also needed for Omnicomplete anyway) you can try as this:

:.!python -c "import os; print os.getcwd()"

That would tell you where you are in the drive (current path).

Now let’s number a few lines, starting from an empty file so we can see the result easily:

:.!python -c "for i in range(1,101): print i"

(vim numbers lines from 1 not 0)
Now we have just the number of each line in every line up to line 100.

Let’s now put a small script in your current path (as shown above) and run it, see how it works. Let’s copy paste this silly one. In reality you will find most useful to do script that output one line per line, but you don’t have to do that as this script shows:

print "hi"

try:
    while True:
        i=raw_input()
        print "this was:",i
except EOFError:
    print "bye"

So you can call, for instance (imagine you called it “what.py”):

:10,20!python what.py

(Note that tab completion of file names works, so you can verify it’s actually in the path)

As you can see, everyline is fed to the script as standard input. First it outputs “hi”, at the end “bye” and in between, for each line you output “this was: ” plus the line. This way you can process line-by-line. Notice you can do more complex stuff than processing line by line, you can actually consider previous lines. For such stuff I’d rather import sys and do it like this:

import sys

print "hello"

for i in sys.stdin.readlines():
    i = i.rstrip("n") # you can also prevent print from doing n instead
    print "here lyeth",i

print "see you"

Hope that helps.

Answered By: nachik

I think what you really want is explained here.

Answered By: André

You can execute the code, read the output on the cursor and finish with u, supposing you are executing python code. Simple and quick.

:r !python %

u

I like it over mapping and selecting-in-visual-mode, like with too-much-php, because it keeps the base simple!

Answered By: hhh

I just wrote the following module that lets you edit a temporary buffer in vim directly in the Python interpreter.

http://philipbjorge.github.com/EditREPL/

Answered By: philip bjorge

On Windows, if you are editing the python script, just do:

!start python my...

and press tab to cycle along the available file names, until you find your match:

!start python myscript.py

It will run in a new cmd window. Personally I prefer to do !start cmd and from there run Python, since it is easier to debug from the eventual error messages.

Answered By: Saullo G. P. Castro

if you have written your python script in a new [No Name] buffer, then you can use following:

:0,$!python

when you have a no name buffer then you can not use ‘%’, hence the need for 0,$ which means all lines in buffer starting with line zero until the last line

output will be written in buffer and unfortunately not at the end

Answered By: serup
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.