I've started to write my first vim plugin, a simple timer. I want to be able to set a timer for an arbitrary amount of time, and have it notify me once that time has passed. I've got it all working, but right now, I'm using echom
(or echoerr
) to display a message like "timer expired". What I want to do is draw some more attention to the fact that the timer has expired, either by using quickfix or the preview window. I've looked around, and short of arbitrarily setting an error string and using setqflist
, I can't really think of anything.
Something I'd also be happy with is the statusline flashing up or something.
How would the more experienced vimscript ninja go about this? Ideally, I'd have something flash, so it draws attention. I'll do some more digging on how I can do that, but in case someone can point me in the right direction, that'd be greatly appreciated.
Just to give you an idea of where I stand in terms of ability: I've been using vim as my main/only editor for about 3 years now. Using vim is not an issue at all. Configuring isn't a problem, either. When it comes to writing plugins, this is my first real attempt. This is what I've written thusfar:
let s:timer_callback = get(g:, 'etimer_callback', 'NotifyTimer')
let s:factors = {
\"ms": 1,
\"s": 1000,
\"m": 60 * 1000,
\"h": 60 * 60 * 1000,
\}
let s:active_timers = {}
function NotifyTimer(timer_id)
let l:timer_interval = remove(s:active_timers, a:timer_id)
call timer_stop(a:timer_id)
echom printf("Timer %d (%s) expired!", a:timer_id, l:timer_interval)
endfunction
function! s:start_timer(i)
let l:interval = s:parse_interval(a:i)
if l:interval == -1
return -1
endif
let l:timer = timer_start(l:interval, s:timer_callback)
let s:active_timers[l:timer] = a:i
echo printf("Timer %d set", l:timer)
endfunction
function s:parse_interval(i)
if a:i!~#"[smh]$"
echoerr printf("Invalid interval %s, expected format \d+(ms|s|m|h)$", a:i)
return -1
endif
let l:len = strlen(trim(a:i))
let l:unit_idx = 1
if a:i=~#"ms$"
let l:unit_idx = 2
endif
let l:split_idx = l:len - l:unit_idx
let l:unit = strpart(a:i, l:split_idx, l:unit_idx)
let l:interval = str2nr(strpart(a:i, 0, l:split_idx))
let l:interval = l:interval * get(s:factors, l:unit, 1)
return l:interval
endfunction
function s:list_timers()
for key in keys(s:active_timers)
echo printf("%d -> %s", key, s:active_timers[key])
endfor
endfunction
function s:cancel_timers()
let s:active_timers = {}
call timer_stopall()
endfunction
Begin a golang dev, I'm really annoyed by the use of a global dictionary. Can't imagine that being safe. I know vim is mostly single threaded when it comes to its scripts, but can't hurt mentioning that concern, and see if it's something I should work on.
pedit
and read the message into the buffer somehow. Not sure how to do that TBH – Elias Van Ootegem Jan 23 '19 at 15:43