Friday, May 07, 2010

VIM inline calculator

Map the F11 key to VIM's eval() function (I hope the Blogger will not eat any characters):

:map <silent> <F11> :exec "s!^\\([^=]\\{-}\\)\\( *=.*\\)\\=$!\\1 = ".eval(substitute(getline(".")," *=.*$","",""))."!"<CR>

Came up during lengthy analysis of log files and source code. Some calculators allow expression. Some support history. But all that is quite limited and often is mouse driven. Check into the VIM's :help :let + digging around pointed in direction of the eval() and thus the monster macro was born.

2 statements are at the core:

1. eval(substitute(getline(".")," *=.*$","","")) strip "= whatever" from the end of the string and feed it to eval(). :h eval()

2. :exec "s!!!" where we take everything from the line, save in \1 string before "=", replace the line with "\1 = " plus result of eval(). Requires :set magic. Backslashes had to be doubled since :exec looks for them.

After adding that to vimrc or executing in place, open VIM, type on empty line "2*2", press Esc and F11. You should see "2*2 = 4".

Edit1 Apparently, the eval() function isn't available in VIM 6.x. Equivalent using :exec ":let":


function CalcX(line_num)
let l = getline(a:line_num)
let expr = substitute( l, " *=.*$","","" )
exec ":let g:tmp_calcx = ".expr
call setline(a:line_num, expr." = ".g:tmp_calcx)
endfunction
:map <silent> <F11> :call CalcX(".")<CR>



Edit2 VIM 7.2 supports floating point numbers. Would be interesting to experiment with it, but I haven't bothered to upgrade yet.

Another little thing. :echo too evaluates its parameters. Typing :echo 2*2[Enter] would display 4.

4 comments:

Andreas Grech said...

For an easier way, you can use the expression register.

Press (CTRL + r) while in INSERT mode and =, and you will have access to a mini terminal below. Type in 2 * 2 and press (Enter) and you'll have the result in your text.

I have written a post about the expression register here: http://blog.dreasgrech.com/2010/06/extending-vim-with-expression-register.html

Ihar Filipau said...

Dreas, that's very cool. Thanks for the hint/link.

Though intent of my calculator was mostly to have the history: type one expression, calculate it, copy-paste, play with numbers, recalculate the new expression, compare the results.

Ihar Filipau said...

Wow. CTRL-R has a load of other functions. That's a great hint indeed.

Gerard W said...

Great reading yourr post