Search code examples
regexdatetimevimvim-macros

Vim : time increment in a schedule


I'm new to Vim and I'm trying to see what I can / can't do with it. I would like to increment a list of times like this :

09:00 Breakfast 
09:30 RSS 
09:50 Stretch
10:00 Main proj
13:00 food
14:00 Main proj...

Lets say I woke up too late, and I'd like to quickly increment everything by 45 minutes in Vim

I tried a macro :

  • Time in minutes : 09:00 -> 09 * 60 + 00
  • + 45
  • SUM with Ctrl + R =
  • Trying to reformat it (int)SUM/60 : SUM - ((int)SUM/60)*60

But I couldn't get it to work (it is such a long macro) and I'm quicker at doing it manually.

On top of that, even if I succeed I can't figure out how to keep the "0" of "09" to keep my numbers in a column.

Is it possible in Vim ? Maybe a regex ?

[edit] For the purpose of exercise, I'd rather use macros, a regex, or even a function in VimScript than a plugin


Solution

  • So, I tried in a regex ( remove return carriage) :

    %s@\(\d\d\):\(\d\d\)@\=printf('%.2d:%.2d'((submatch(1)*60+submatch(2)+45)/60),
    ((submatch(1)*60+submatch(2)+45)-((submatch(1)*60+submatch(2)+45)/60)*60))@
    

    it's quite inelegant and i'd like to have inc = 45 and sum = (submatch(1)*60+submatch(2)+inc), I would need to declare the variables on the same line as the printf... but it works ;)

    Inside visual selection : with '<,'> instead of %.

    One problem of course is that it doesnt loop back around midnight, but I guess for that @steffen's answer would be better

    Edit : I found that modulo existed in Vimscript and I couldn't resist...now it loops around midnight :

    %s@\(\d\d\):\(\d\d\)@\=printf('%.2d:%.2d',((submatch(1)*60+submatch(2)+45)/60)%24,
    (submatch(1)*60+submatch(2)+45)%60)@
    

    Edit 2: And here is the code in a function using the func-range (thanks @Kent)

    function! IncrementTime(mins) range
        "Increments time within a range ( current line or selection)
        let pat = '(submatch(1)*60+submatch(2)+'.a:mins.'+1440)'
        execute a:firstline.','.a:lastline.'s@\(\d\d\):\(\d\d\)@\=printf("%.2d:%.2d",('.pat.'/60)%24,'.pat.'%60)@'
    endfunction
    

    I had to add 1440 to avoid negative hours when one decrements