Vim:计划中的时间增量

时间:2015-03-30 11:11:17

标签: regex datetime vim vim-macros

我是Vim的新手,我正试着看看我能做什么/不能用它做什么。我想增加一个这样的时间列表:

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

让我说我醒得太晚了,我想在Vim快速增加45分钟的所有内容

我尝试了一个宏:

  • 以分钟为单位的时间:09:00 -> 09 * 60 + 00
  • + 45
  • SUM与 Ctrl + R =
  • 尝试重新格式化(int)SUM/60 : SUM - ((int)SUM/60)*60

但我无法让它发挥作用(这是一个很长的宏),而且我手动做得更快。

最重要的是,即使我成功了,我也无法弄清楚如何保持"0" "09"将我的数字保留在一列中。

Vim有可能吗?也许正则表达式?

[edit] 为了练习,我宁愿在VimScript中使用宏,正则表达式,甚至是函数而不是插件

4 个答案:

答案 0 :(得分:2)

我刚刚发现OP的新编辑,似乎他正在寻找一个小vimscript功能。这是一个非通用功能,但它可以满足您的需求。

请注意,在分钟增量后,结果可能会比24:00更大(稍后),date信息将会丢失,例如在45mins上添加23:30 {1}}会产生00:15

function! IncTime(mins) 
    let pat = '^\d\d:\d\d\ze '
    for i in range(line('$'))
        let tss = matchstr(getline(i+1), pat)
        if tss
            let ts = split(tss,':')
            let ns = 60*ts[0] + ts[1] + a:mins
            let nts = printf('%.2d:%.2d', (ns/60)%24, ns % 60)
            execute i+1.'s/'.pat.'/'.nts
        endif
    endfor
endfunction

来源,并在您的文件中调用:call IncTime(45)以检查所应用的更改。您还可以将45以外的其他偏移量传递给该函数,例如10,甚至2000

enter image description here

答案 1 :(得分:2)

所以,我尝试了一个正则表达式(删除回车):

%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))@

它非常不优雅,我想要inc = 45sum = (submatch(1)*60+submatch(2)+inc),我需要在与printf相同的行上声明变量......但是它有效;)

内部视觉选择:使用'<,'>代替%

当然,一个问题是它不会在午夜左右回转,但我想@ steffen的回答会更好

编辑:我发现模数存在于Vimscript中,我无法抗拒......现在它在午夜循环:

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

编辑2:以下是使用func-range的函数中的代码(感谢@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

我不得不添加1440以避免负面小时减少

答案 2 :(得分:1)

只能使用某些插件(或写作Kent评论的函数),例如:

Speeddating plugin

答案 3 :(得分:1)

日期和时间计算总是比预期的更困难。想想夏令时。你应该让其他工具进行计算。如果您使用的是Linux,可以尝试使用date

let @a=substitute(system("date -d @$(($(date -d " . substitute(getline('.'), '\(\S\+\).*', '\1', '') . " +\\%s)+45*60)) +\\%H:\\%M"), ".$", "", "")

这将在当前行的开头添加45分钟(由空格分隔)并将其放入寄存器a。然后,您的宏可以删除时间并将其替换为@a:

"_dE
"aP0

BTW:这也适用于像“now”这样的字符串:

09:00 Breakfast (before)
09:45 Breakfast (after)

now Breakfast (before)
14:45 Breakfast (after)