4

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.

  • 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
2
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

  • 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
4

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)]" 
  • 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

  • This doesn't appear to answer the question of putting the answer in a register, or inserting it at the cursor. – Herb Wolfe 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.