tags:

views:

102

answers:

4

When Vim is compiled with Python support, you can script Vim with Python using the :python command. How would I go about using this to execute the command and insert the result under the cursor? For example, if I were to execute :python import os; os.listdir('aDirectory')[0], I would want the first filename returned to be inserted under the cursor.

EDIT: To clarify, I want the same effect as going to the terminal, executing the command, copying the result and executing "+p.

+3  A: 

You need to assign it to the current line, you can use the vim module:

:python import os; import vim; vim.current.line=os.listdir('.')[0]
Jacobo de Vera
This works ok, but you end up with a command like `:python import os; import vim; vim.current.line = vim.current.line[:vim.current.window.cursor[1]]+os.listdir('blah')[0]+vim.current.line[vim.current.window.cursor[1]:]` which is a bit annoying :-S
Chinmay Kanchi
You could create a command that takes the directory as parameter and put it in your .vimrc:`command -nargs=1 FirstFile :python import os; import vim; vim.current.line = vim.current.line[:vim.current.window.cursor[1]] +os.listdir('<args>')[0]+vim.current.line[vim.current.window.cursor[1]:]`And you can also map some key combination to this for some particular directory:`nmap ff :FirstFile .<CR>`
Jacobo de Vera
+2  A: 
:,!python -c "import os; print os.listdir('aDirectory')[0]"
mg
I get `:!,python -c 'import os; os.listdir("xmls")[0]'` `[No write since last change]` `/bin/bash: ,python: command not found``shell returned 127` and without the `,` the command executes, but the result isn't inserted.
Chinmay Kanchi
@Chinmay Kanchi: re-read the code
mg
Whoops! Looks like I can't even read today...
Chinmay Kanchi
It won't let me re-upvote the answer unless it's edited, do you mind adding an extra space or something and saving it so I can upvote?
Chinmay Kanchi
Also, how can I do it so that the result is inserted _at_ the cursor rather than the line below (with `:r`) or replacing the line completely (with `:,`)? Basically, I want the same effect as going to the terminal, executing the command, copying the result and executing `"+p`.
Chinmay Kanchi
@Chinmay Kanchi: no, you can read and very quickly: i think i edited the post while you were testing the wrong code. The `,!` don't let you to insert the output of a command at cursor position but replace the current line with the new one.
mg
A: 

In the end, I solved it by writing a script called pyexec.vim and put it in my plugin directory. The script is reproduced below:

python << endpython
import vim
def pycurpos(pythonstatement):
    #split the python statement at ;
    pythonstatement = pythonstatement.split(';')
    stringToInsert = ''
    for aStatement in pythonstatement:
        #try to eval() the statement. This will work if the statement is a valid expression
        try:
            s = str(eval(aStatement))
        except SyntaxError:
            #statement is not a valid expression, so try exec. This will work if the statement is a valid python statement (such as if a==b: or print 'a')
            #if this doesn't work either, fail
            s = None
            exec aStatement


        stringToInsert += s if s is not None else ''

    currentPos = vim.current.window.cursor[1]
    currentLine = vim.current.line
    vim.current.line = currentLine[:currentPos]+stringToInsert+currentLine[currentPos:]

endpython

This works as expected for oneliners, but doesn't quite work for multiple statements following a block. So python pycurpos('a=2;if a==3:b=4;c=6') will result in c always being 6, since the if block ends with the first line following it.

But for quick and dirty python execution, which is what I wanted, the script is adequate.

Chinmay Kanchi
+2  A: 

The following works fine for me: write the python code you want to execute in the line you want.

import os
print(os.listdir('.'))

after that visually select the lines you want to execute in python

:'<,'>!python

and after that the python code will replaced by the python output.

skeept
But that doesn't use Vim's internal Python support. That uses Vim's shell support.
Nathan Fellman
yes, you're right, I overlooked that.
skeept
This most directly achieves the stated desire of *the same effect as going to the terminal, executing the command, copying the result and executing "+p* expressed by the OP.
Roger Pate