我有一个 todo.txt 文件,我认为将光标放在待办事项(todo.txt 文件中的一行)上,按下组合键,然后让 Vim 开始计算分钟数会很有趣。然后,当我按下另一个组合键时,它会停止计数,并插入经过的分钟数,例如min:25
。有没有办法在 vim 中做到这一点?
同样令人惊叹的是,如果我在已经开始的行上按下组合键min:
,它会将分钟数附加到现有的分钟数中。
答案1
我试用了一下,并想出了以下脚本。为了使其可靠,我必须让它处理“ minMM:SS
”的格式,其中MM
和SS
代表分钟和秒。
我怀疑您需要以某种方式修改它以满足您的实际需要,但当您在正常模式下键入以下命令时,脚本基本上开始计数:\sc
然后,当您键入以下命令时,它将停止计数并将上述格式附加到光标位置:\ec
如果该行已经包含与上述格式匹配的时间戳,则会添加到其中。
请注意,如果您改变了您的,mapleader
您将使用它来代替\
上面的按键序列。
function! s:Start()
if exists('b:CountMinutesStart')
echohl ERROR
echomsg "Already counting."
echohl NONE
return
endif
echohl TODO
echomsg "Counting started."
echohl NONE
let b:CountMinutesStart = localtime()
endfunction
function! s:Stop()
if !exists('b:CountMinutesStart')
echohl ERROR
echomsg "Not counting."
echohl NONE
return -1
endif
let l:start = b:CountMinutesStart
let l:end = localtime()
unlet b:CountMinutesStart
let l:elapsed = l:end - l:start
echohl TODO
echomsg "Elapsed time since start: " . s:Format(l:elapsed)
echohl NONE
return l:elapsed
endfunction
function! s:Format(seconds)
let l:minutes = a:seconds / 60
let l:seconds = a:seconds % 60
return printf('min%02d:%02d', l:minutes, l:seconds)
endfunction
function! s:InsertTime()
let l:seconds = s:Stop()
if l:seconds == -1
return
endif
let l:line = getline('.')
if l:line =~ 'min\d\{2}:\d\{2}'
let l:tmp = split(substitute(l:line, '.*min\(\d\{2}\):\(\d\{2}\).*', '\1 \2', ''), ' ')
let l:seconds = l:seconds + (l:tmp[0] * 60 + l:tmp[1])
call setline('.', substitute(l:line, 'min\d\{2}:\d\{2}', s:Format(l:seconds), ''))
else
exe 'normal a' . s:Format(l:seconds)
endif
endfunction
command! StartCounting call s:Start()
command! StopCounting call s:InsertTime()
nmap <silent> <leader>sc :StartCounting<cr>
nmap <silent> <leader>ec :StopCounting<cr>