* El 11/10/06 a las 17:18, Benji Fisher chamullaba:

> On Thu, Sep 28, 2006 at 02:30:37PM -0300, Luis A. Florit wrote:
> > Pals: I want to evaluate a block selection with formulas to its value.
> > So, if you have 2 lines like:
> >
> > home roof 89.4 + 76 home roof
> > home roof 17 + 13.3 home roof
> >
> > I would like to replace "89.4 + 76" by 165.4 and "17 + 13.3" by 30.3
> > by selecting the block with the formulas and applying some command
> > sequence (for example, using perl, bc, python, etc).
> > Of course, I want this for arbitrary aritmetic formulas.
> >
> >     Thanks!
> >
> >         Luis.
>
>      On Linux, I can use the bc command like this:
>
> :s/\d[0-9 .+*/-]*/\=substitute(system('echo ' . submatch(0) . ' | bc'), '\n', 
> '', 'g')
>
> That is,
>
> :s/<pat>/\=<expr>
>
> where my pattern <pat> is '\d[0-9 .+*/-]*', a first attempt at capturing
> the sort of "arithmetic string" you have in mind.  Inside <expr>,
> submatch(0) is replaced by the matched text, such as "89.4 + 76".  Then
>
>   system('echo 89.4 + 76 | bc')
>
> will pass the string to bc as stdin and return the result.  I wrapped
> this in substitute() to strip off the trailing newline character.
>
>      It will be easier to read and maintain if you do something like
> this (untested):
>
> fun! EvalMath(str)
>   let res = system('echo ' . a:str . ' | bc')
>   return substitute(res, '\n', '', 'g')
> endfun
>
> :s/\d[0-9 .+*/-]*/\=EvalMath(submatch(0))
>
> HTH                   --Benji Fisher

Benji,

    I only received this today, October 12. I've already found a solution,
that is quite similar to yours, even with the newline trick. I put it as a
vimtip a couple of weeks ago: http://www.vim.org/tips/tip.php?tip_id=1349

    I found the mappings I made very handy also that, for example,
computes math expressions in visual block selections and replaces
(or adds) the computation, or adds a block of math expressions.
These maps use Chip's vis.vim plugin #1195.

    Below is the 'last version' of the tip, with comments for using
each map. Just add the code to your .vimrc.

    Thanks, and sorry for the delay,

        Luis.

==============================================================================================

let g:MyCalcPresition = 2

function MyCalc(str)
    return system("echo \'scale=" . g:MyCalcPresition . " ; print " . a:str . 
"\' | bc -l")
endfunction

" Use \C to replace a (block of) visual math expression(s) by the value of the 
computation:
vmap <silent> <leader>c :B s/.*/\=MyCalc(submatch(0))/<cr>
" Same in normal mode, for the whole current line
map  <silent> <leader>c :s/.*/\=MyCalc(submatch(0))/<cr>
" With \C=  no replace, but add the result
vmap <silent> <leader>c= :B s/.*/\=submatch(0) . " = " . 
MyCalc(submatch(0))/<cr>
" Same in normal mode, for the whole current line
map  <silent> <leader>c= :s/.*/\=submatch(0) . " = " . MyCalc(submatch(0))/<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>
" Try: :MyCalc 12.7 + sqrt(98)
command! -nargs=+ MyCalc :echo MyCalc("<args>")

Reply via email to