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