0

我是 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
  • Ctrl+相加R =
  • 试图重新格式化(int)SUM/60 : SUM - ((int)SUM/60)*60

但我无法让它工作(它是一个很长的宏),而且我手动完成它的速度更快。

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

在 Vim 中可以吗?也许是一个正则表达式?

[编辑]出于练习的目的,我宁愿使用宏、正则表达式,甚至是 VimScript 中的函数,而不是插件

4

4 回答 4

2

刚找到OP的新编辑,看来他是在找一个小vimscript功能。这是一个非通用功能,但它可以满足您的需求。

请注意,在分钟增量之后,结果可能会比24:00这种情况更大(晚),date信息将丢失,例如添加45mins23:30导致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

在此处输入图像描述

于 2015-03-30T13:08:47.740 回答
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 = 45并且sum = (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 以避免在减少 1 时出现负小时数

于 2015-03-30T16:41:06.793 回答
1

只能使用一些插件(或像 Kent 评论的那样编写函数),如下所示:

快速约会插件

于 2015-03-30T11:16:38.477 回答
1

日期和时间的计算总是比预期的更困难。例如,考虑夏令时。您应该让其他工具进行计算。如果你在 Linux 上,你可以尝试这样做date

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

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

"_dE
"aP0

顺便说一句:这也适用于像“now”这样的字符串:

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

now Breakfast (before)
14:45 Breakfast (after)
于 2015-03-30T12:01:39.143 回答