3

I want to run https://stackoverflow.com/questions/7588531/vim-set-color-theme-based-off-time-of-day

So something like:

if strftime("%H") < 12
  set background=light
else
  set background=dark
endif

But for this to be invoked every hour, rather than only once when opening vim. Does vim or neovim support running a periodic action?

3

You can use timer_start() to set "timers" to run a function every n milliseconds. For example:

fun! s:set_bg(timer_id)
    let &background = (strftime('%H') < 12 ? 'light' : 'dark')
endfun
call timer_start(1000 * 60, function('s:set_bg'), {'repeat': -1})
call s:set_bg(0)  " Run on startup

This will run s:set_bg() every 1 minute (60,000 milliseconds), and by setting repeat to -1 it will run indefinitely (rather than just once).

As far as I've been able to see in my (short) testing, this doesn't cause any side-effects such as slow-downs or flickering. You can consider changing the logic to set background only if it differs from the current value if it does (but looks like Vim is smart enough on its own).


Note that resetting the colour scheme (as you did in your own answer), does cause some flicking for me; you can get the current scheme name with g:colors_name, and use something like this to change it only when needed:

fun! s:set_bg(timer_id)
        let l:hour = strftime('%H')

        if l:hour < 18 && g:colors_name isnot# 'zellner'
                set background=light
                colorscheme zellner
        elseif l:hour > 18 && g:colors_name isnot# 'nightfly'
                set background=dark
                colorscheme nightfly
        endif
endfun

You can probably make this a bit shorter if you want, but should get the idea.

If you want to be able to disable the switching at runtime, then return the timer ID from timer_start() and call timer_stop() on it.


Support for timers was added in Vim 7.4.1578 (March 2016), and some very old installations may not have it (this is also why the SO question you link doesn't mention it, as that was asked before this feature existed).

| improve this answer | |
  • Current colorscheme should be available in g:colors or some such similar variable (I forget the exact name). Good to see you hanging around some :) – D. Ben Knoble Apr 18 at 12:52
  • Thanks @D.BenKnoble; have to do something when you're stuck inside like much of the planet :-( And yeah, looks like it's in g:colors_name. – Martin Tournoij Apr 18 at 12:57
3

As a workaround one can instead target the common FocusLost / FocusGained events.

function DynamicColorThemeSwitch()
  if strftime("%H") < 18
    set background=light
    colorscheme zellner
  else
    set background=dark
    colorscheme nightfly
  endif
endfunction

autocmd FocusLost,FocusGained * call DynamicColorThemeSwitch()
call DynamicColorThemeSwitch()
| improve this answer | |
  • 1
    This is probably the best way to do it if you don't have the +timers feature in your Vim. Perhaps adding the CursorHold event might be a good idea as well? There are quite a few conditions where the Focus* events aren't triggered (not leaving the Vim window for a while, but also in various terminal emulators) – Martin Tournoij Apr 18 at 11:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.