Chinmay Kanchi
Chinmay Kanchi

Reputation: 65843

Execute a python command within vim and getting the output

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.

Upvotes: 5

Views: 5511

Answers (4)

skeept
skeept

Reputation: 12413

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.

Upvotes: 3

Chinmay Kanchi
Chinmay Kanchi

Reputation: 65843

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.

Upvotes: 0

mg.
mg.

Reputation: 8012

:,!python -c "import os; print os.listdir('aDirectory')[0]"

Upvotes: 5

Jacobo de Vera
Jacobo de Vera

Reputation: 1933

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]

Upvotes: 2

Related Questions