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
    Aug 1 '15 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
    – Pétur
    Aug 1 '15 at 18:21
  • 1
    'py import vim' of course!
    – Alex Kroll
    Aug 1 '15 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.
    – Pétur
    Aug 1 '15 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
    Aug 1 '15 at 19:02
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.
    – Pétur
    Aug 2 '15 at 11:23
  • You're right! Look edited answer!
    – Alex Kroll
    Aug 2 '15 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.
    – Pétur
    Aug 2 '15 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
    Aug 1 '15 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
    Aug 2 '15 at 1:42
  • python -c 'print [x^2 for x in range(100)]', but yes.
    – muru
    Aug 2 '15 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
    Jun 2 '17 at 3:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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