DEV Community

loading...
Cover image for Vim: Set your vim colorscheme and background based on Hour

Vim: Set your vim colorscheme and background based on Hour

Sérgio Araújo
I am a Free Software enthusiast and a (neo)?vim addicted, I also like shell script, sed, awk, and as you can see I love Regular Expressions.
Updated on ・2 min read

References

Settig color and background on vim:

To set your color you do:

:colo colorname
Enter fullscreen mode Exit fullscreen mode

And the background could be:

:set background=light
Enter fullscreen mode Exit fullscreen mode

or

:set background=dark
Enter fullscreen mode Exit fullscreen mode

We are gonna get the remainder of the division of hour by 18 and compare with 6 (our criteria). Everything is encapsulated on a ternary operator.

One example of a ternary operator to change your tabstop

:nnoremap <silent><Leader>T :let &ts = (&ts == 4) ? 2 : 4<CR>
Enter fullscreen mode Exit fullscreen mode

In the above code if the &ts is equal to 4 it will be setted to value 2, otherwise, it will be setted to 4

Our two line of code

exe 'colo' ((strftime('%H') % 18) > 6 ? 'gruvbox' : 'kolor')
exe 'set background='. ((strftime('%H') % 18) > 6 ? 'light' : 'dark')
Enter fullscreen mode Exit fullscreen mode

If we were not using a ternary statement we would have to use a lot more code, as you can se below.

let hr = (strftime('%H'))
if hr >= 19
    set background=dark
elseif hr >= 8
    set background=light
elseif hr >= 0
    set background=dark
endif
Enter fullscreen mode Exit fullscreen mode

In my opinion, I only need to change the background because the "gruvbox" theme has nice light and dark backgrounds.

The secret behind reminded division

I have used my super power google skills to figure out how to test these values on bash.

Thus, the reminder of a division in bash (see references) is given throught

remainder=$((dividend%divisor))
Enter fullscreen mode Exit fullscreen mode

In my case, I like the light background on vim from six hours until 18 hours.

In order to have a better idea on how the remainder of the division makes our code shorter, run this code on your terminal.

for ((i=1;i<=23;i++)){
    reminder=$(( $i % 18 ))
    if [[ "$reminder" -gt "6" ]]; then
        echo "Hour: $i Reminder: $reminder bigger than 6 - BG: light"
    else
        echo "Hour: $i Reminder: $reminder $reminder less than 6 - BG: dark"
    fi
}
Enter fullscreen mode Exit fullscreen mode

The big issue and the solution

At this point, we have a line of code that runs every time vim starts, but if I, for example, open my vim at 17:50h and keep working with no stop for many hours (withour reloading $MYVIMRC), the background will not change. So, the solution is bellow:

" https://vi.stackexchange.com/a/24672/7339
fun! s:set_bg(timer_id)
    let &background = ((strftime('%H') % 18) >= 6 ? '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).

Enter fullscreen mode Exit fullscreen mode

Bonus

" keybinding to toggle backaground
" source: http://tilvim.com/2013/07/31/swapping-bg.html <F19> = Shif-F7
nmap <F19> :let &background = ( &background == "dark" ? "light" : "dark")<CR>

" Reloads vimrc after saving but keep cursor position
if !exists('*ReloadVimrcFunction')
    function! ReloadVimrcFunction()
        let save_cursor = getcurpos()
        source $MYVIMRC | setf vim | windo redraw
        call setpos('.', save_cursor)
        echom "Reloaded $MYVIMRC"
    endfunction
endif
noremap <silent> <Leader>v :drop $MYVIMRC<cr>
command! -nargs=0 ReloadVimrc :call ReloadVimrcFunction()
nnoremap <silent> <C-s> :call ReloadVimrcFunction()<CR>
Enter fullscreen mode Exit fullscreen mode

Discussion (0)