Sunday, May 19, 2013

Re: How to do math in vim ?

On Monday, May 20, 2013 5:00:03 AM UTC+12, Jeri Raye wrote:
>
> Can you do math in Vim?
> Can you do subtractions?

Surely. Floating point, trigonometry even. I would:

1. Write a regex that matches the numbers you want to manipulate, and not anything else. Maybe

/\d\d:\d\d:\d\d,

2. Put capturing parentheses around the numbers that might change. In vim these are \( and \):

/\d\d:\(\d\d\):\(\d\d\),

3. For convenience, isolate the parts that will change with \zs and \ze:

/\d\d:\zs\(\d\d\):\(\d\d\)\ze,

4. Use :substitute with \= and submatch() to change the minutes and seconds to seconds, with markers. Also, now is a good time to do the arithmetic. Note the tricky precedence of string concatenation

:%s//\='##'.(submatch(1)*60+submatch(2)-7).'###'/g

5. Use :substitute with \=, submatch(), and printf()

:%s@##\(\d\+\)###@\=printf('%02d:%02d',submatch(1)/60,submatch(1)%60)@g

Here the replace expression has a /, so :s uses @ instead.

That, which flowed off my fingers as I went along, didn't end up all that simple, I'm sorry. Straightforward if one is a C programmer, and so familiar with printf and integer arithmetic with / and %. It would be better to write a function that does the manipulation:

function! Sub(in)
let minutes = a:in[0:1]
let seconds = a:in[3:4]
let time = minutes * 60 + seconds

let time -= 7

let minutes = time / 60
let seconds = time % 60

return printf('%02d:%02d', minutes, seconds)
endfunction

Put that in a file, say sub.vim, source it:

:so sub.vim

Then
:%s/\d\d:\zs\d\d:\d\d\ze,/\=Sub(submatch(0))/g

Regards, John Little

--
--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

---
You received this message because you are subscribed to the Google Groups "vim_use" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vim_use+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

No comments:

Post a Comment