Vim Tips Wiki

Calculator Editing

1,624pages on
this wiki
Add New Page
Talk0 Share
Tip 1349 Printable Monobook Previous Next

created 2006 · complexity intermediate · author Luis A. Florit · version n/a

This tip adds a good calculator to Vim visual mode selections. It allows you to replace a block of math expressions by their calculated results.

Add the following lines to your vimrc.

function MyCalc(str)
  if exists("g:MyCalcRounding")
    return system("echo 'x=" . a:str . ";d=.5/10^" . g:MyCalcPresition
          \. ";if (x<0) d=-d; x+=d; scale=" . g:MyCalcPresition . ";print x/1' | bc -l")
    return system("echo 'scale=" . g:MyCalcPresition . " ; print " . a:str . "' | bc -l")

" Control the precision with this variable
let g:MyCalcPresition = 2
" Comment this if you don't want rounding
let g:MyCalcRounding = 1
" Use \C to replace the current line of math expression(s) by the value of the computation:
map <silent> <Leader>c :s/.*/\=MyCalc(submatch(0))/<CR>:noh<CR>
" Same for a visual selection block
vmap <silent> <Leader>c :B s/.*/\=MyCalc(submatch(0))/<CR>:noh<CR>
" With \C= don't replace, but add the result at the end of the current line
map <silent> <Leader>c= :s/.*/\=submatch(0) . " = " . MyCalc(submatch(0))/<CR>:noh<CR>
" Same for a visual selection block
vmap <silent> <Leader>c= :B s/.*/\=submatch(0) . " = " . MyCalc(submatch(0))/<CR>:noh<CR>
" Try: :B s/.*/\=MyCalc("1000 - " . submatch(0))/
" The concatenation is important, since otherwise it will try
" to evaluate things like in ":echo 1000 - ' 1748.24'"
vmap <Leader>c+ :B s/.*/\=MyCalc(' +' . submatch(0))/<C-Left><C-Left><C-Left><Left>
vmap <Leader>c- :B s/.*/\=MyCalc(' -' . submatch(0))/<C-Left><C-Left><C-Left><Left>
" With \Cs you add a block of expressions, whose result appears in the command line
vmap <silent> <Leader>ct y:echo MyCalc(substitute(@0," *\n","+","g"))<CR>:silent :noh<CR>
" Try: :MyCalc 12.7 + sqrt(98)
command! -nargs=+ MyCalc :echo MyCalc("<args>")


As a visual block calculator

1. First, visually select a (block of) math expression(s). Example: "12.7 + sqrt(98.7)" (without the quotes).

Then type ether \C or \C=

With \C the formula will be replaced by its result from bc ("22.63" in the example).

With \C= the formula will remain, but the result will be appended ("12.7 + sqrt(98.7) = 22.63" in the example).

2. First, visually select a (block of) math expression(s). Example: "sqrt(98.7)".

Then type:

:B s/.*/\=MyCalc("12.7 + " . submatch(0))/

The expression will be replaced by its result ("22.63" in the example).

The marks '<,'> will appear behind the "B", but that is fine (block marks). This is useful if you want to, say, add "12.7" to a (column of) number(s). The numbers do not have to be integers.

Both methods work for block of expressions. So, if you visually select the block:

12.7 + sqrt(98.7)
57 + 12
1 == 0
3*4 == 12

and type \C you will have the block replaced with:


Using bc, 's()' is the sine function.

As a command line calculator

3. In normal mode, type

:MyCalc 12.7 + sqrt(98.7)

You will get "22.63" in the command line. This usage mode is similar to VimTip1235, but doesn't need embedded python.


It uses Dr.Chip's visual block plugin vis.vim, and the Unix/Linux command line calculator 'bc'.

Do a 'man bc' in the shell to know its built-in functions, like 's()' above. You can easily replace 'bc' by your favorite calculator program.

The precision of the calculator is controlled by the variable g:MyCalcPresition.



With this map you can add a block of expressions, and the result will appear in the command line:

vmap <Leader>Cs y:echo MyCalc(substitute(@0," *\n","+","g"))<CR>

" I've added the code for Windows. This has been checked
" for the shells cmd and 4nt.
" For rounding, the '^' operator, to raise a number to an
" integer power, happens to be the escape character for
" these shells. Because of the odd escaping required in
" CMD, a separate return is needed for CMD vs 4NT. There
" is no difference for the non-rounding return.
" You can enter "2^10" for 2 to the power 10.

let g:MyCalcPrecision = 2
let g:MyCalcRounding = 1

function MyCalc(str)
  if exists("g:MyCalcRounding")
    if has("win32")
      if &shell =~? "cmd\.exe"
        let s:str = substitute(a:str,'\^','^^^^','g')
        return system("echo x=".s:str.";d=.5/10^^^^".g:MyCalcPrecision
              \.";if(x^^^<0)d=-d;x+=d;scale=".g:MyCalcPrecision.";print x/1|bc -l")
        let s:str = substitute(a:str,'\^','^^','g')
        return system("echo x=".s:str.";d=.5/10^^".g:MyCalcPrecision
              \.";if(x^<0)d=-d;x+=d;scale=".g:MyCalcPrecision.";print x/1|bc -l")
      return system("echo 'x=" . a:str . ";d=.5/10^" . g:MyCalcPrecision
            \.";if (x<0) d=-d; x+=d; scale=" . g:MyCalcPrecision
            \. ";print x/1' | bc -l")
    if has("win32")
      if &shell =~? "cmd\.exe"
        let s:str = substitute(a:str,'\^','^^^^','g')
        let s:str = substitute(a:str,'\^','^^','g')
      return system("echo x=".s:str.";scale=".g:MyCalcPrecision
            \.";print x/1|bc -l")
      return system("echo 'scale=" . g:MyCalcPrecision
            \. " ; print " . a:str . "' | bc -l")

See script#219.

Ad blocker interference detected!

Wikia is a free-to-use site that makes money from advertising. We have a modified experience for viewers using ad blockers

Wikia is not accessible if you’ve made further modifications. Remove the custom ad blocker rule(s) and the page will load as expected.

Also on Fandom

Random Wiki