5

I found this vim tip which allows you to evaluate a Python expression and displays the result in the command line. You just have to add

:command! -nargs=+ Calc :py print <args>
:py from math import *

to your .vimrc and then you can do e.g.

:Calc sum([x^2 for x in range(100)])

Which displays 4950in my command line, as if I had executed :echo 4950. This is convenient, but I would like to know how I can either append the result at the location of my cursor, or add it to a certain register.

5
  • 1
    py vim.current.buffer.append(str(sum([x^2 for x in range(100)])), vim.current.window.cursor[0])
    – Alex Kroll
    Commented Aug 1, 2015 at 16:37
  • @AlexKroll This gives me an error: Traceback (most recent call last): File "<string>", line 1 in <module> NameError: name 'vim' is not defined
    – Peter
    Commented Aug 1, 2015 at 18:21
  • 1
    'py import vim' of course!
    – Alex Kroll
    Commented Aug 1, 2015 at 18:23
  • @AlexKroll I was completely unaware that Python had a vim module (or does it?) I prefer your solution to philolo1's but if someone could point me to a command to append the result to a register, that would be great. If you make this an answer I'll probably accept it.
    – Peter
    Commented Aug 1, 2015 at 18:34
  • If your Vim compiled with +python or +puthon3 internal Python interpreteur have module vim, :he python-vim for more exploration.
    – Alex Kroll
    Commented Aug 1, 2015 at 19:02

4 Answers 4

3
function! CalcAndAppend(expr)
py << EOF
import vim
evaluated = eval(vim.eval("a:expr"))

vim.current.buffer.append(str(evaluated), vim.current.window.cursor[0])
EOF
endfunction

function! CalcAndAppendRegister(reg, expr)
py << EOF
import vim
evaluated = eval(vim.eval("a:expr"))
evalString = "'" + str(evaluated) + "'"
register = vim.eval("a:reg")

vim.command("let @%s=%s" % (register,evalString))
EOF
endfunction

command! -nargs=+ Calc call CalcAndAppend(<q-args>) 

command! -register -nargs=+ CalcReg call CalcAndAppendRegister("<reg>",<q-args>)

Usage:
:Calc 2+2
appends 4 to the current buffer on one line below after cursor
:CalcReg a sum[x^2 for x in range(100)] put 4950 to the register named a

3
  • It looks to me like this uses vim to evaluate the expression and not python.
    – Peter
    Commented Aug 2, 2015 at 11:23
  • You're right! Look edited answer!
    – Alex Kroll
    Commented Aug 2, 2015 at 12:20
  • This is exactly what I had in mind. I added support for floating point numbers to avoid E806: using Float as a String.
    – Peter
    Commented Aug 2, 2015 at 15:31
5

That's what pyeval() is good for. The only (minor) inconvenience is that you have to quote the expression you want to evaluate:

let @a = pyeval('sum([x^2 for x in range(100)])')

It works for all data types, and you can do with it everything you can do with a Vim expression. For example:

echo pyeval('[x^2 for x in range(100)]')
3

I do the following:

I create somewhere a calculator.py file containing this.

 import sys                                                                  
 print eval(sys.argv[1]) 

Then in vim i can do the command:

read! python calculator.py "[x^2 for x in range(100)]" 
3
  • I'm curious: why use eval instead of python -c?
    – muru
    Commented Aug 1, 2015 at 19:22
  • No reason, i did not know the command, so you can also so do python -c "[x^2 for x in range(100)]".
    – philolo1
    Commented Aug 2, 2015 at 1:42
  • python -c 'print [x^2 for x in range(100)]', but yes.
    – muru
    Commented Aug 2, 2015 at 1:42
1
  1. Open the great vim.
  2. Enter insert mode and add a python3 statement inside your text file buffer:

    print(5*5)

  3. Go to normal mode (ESC or CTRL+C)

  4. Press !! making sure the cursor is above that line. Your command bar will be filled like:

    :.!

  5. fill the rest of command with python

    :.!python

  6. press enter end you line will be evaluated:

    25

1
  • This doesn't appear to answer the question of putting the answer in a register, or inserting it at the cursor.
    – Herb
    Commented Jun 2, 2017 at 3:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.