Hi Bill,

* El 14/10/06 a las 21:48, Bill McCarthy chamullaba:

> Thanks for your work on this block calculator. As is, it
> will not work for Windows shells (cmd and 4nt).

Oops, sorry for this.
It more than possible.
I don't have/use/think/need Windows,
so I keep forgetting it even exists.

> BC uses '^' to raise a number to an integer power.  That's
> the escape character for both Windows shells. So to compute
> 2^10, you would write for 4nt:
>
>     MyCalc 2^^10
>
> For cmd, and I'll let cmd users explain this one - it
> appears to be parsing this twice, write:
>
>     MyCalc 2^^^^10
>
> I've also added rounding for the Windows version. I keep
> the 'nix version as it was (except I formatted it to fit in
> email and replaced your g:MyCalcPresition with g:bc_scale.
> This is the number of digits after the decimal point.

I called it MyCalcPresition because users can
use the function without any knowledge of bc.
The name is self-explanatory.

> I've testing this with GNU bc 1.06. Here's the modified
> function:
>
>     function MyCalc(str)
>       if has("win32")
>         if &shell =~? "cmd\.exe"
>           return system("echo x=".a:str
>             \.";d=.5/10^^^^".g:bc_scale
>             \.";if(x^^^<0)d=-d;x+=d;scale="
>             \.g:bc_scale.";print x/1|bc -l")
>         else
>           return system("echo x=".a:str
>             \.";d=.5/10^^".g:bc_scale
>             \.";if(x^<0)d=-d;x+=d;scale="
>             \.g:bc_scale.";print x/1|bc -l")
>         endif
>       else
>         return system("echo \'scale=" . g:bc_scale
>             \ . " ; print " . a:str . "\' | bc -l")
>       endif
>     endfunction

Glad you already ported this.

> I have no way of testing this, but I think the 'nix version
> with rounding would look like this:
>
>     return system("echo \'x=".a:str
>         \.";d=.5/10^^".g:bc_scale
>         \.";if(x^<0)d=-d;x+=d;scale="
>         \.g:bc_scale.";print x/1\'|bc -l")

This is not completely correct because all those '^'. But this works:

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

> One more thing, you define a 'vmap' followed by a 'map' for
> the same lhs.  The 'map' overrides the 'vmap'.  You could
> simply replace 'map' with 'nmap' - but that doesn't define
> the operator pending functionality - I don't think I need
> that.  If you do, an alternate would be to define the 'map'
> before the 'vmap'.

Of course your are right.
I made the 'map' much after the 'vmap', and added it in the wrong place.
As you observed, not as useful as the vmap, though.

    Below is the corrected version, with unnecessary highlighting
also corrected, and with the (optional) rounding feature added.

    Thanks for your comments!

        L.

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

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")
    else
        return system("echo \'scale=" . g:MyCalcPresition . " ; print " . a:str 
. "\' | bc -l")
    endif
endfunction

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

Reply via email to