Dynamic Neovim Theme from day to night config

Embrace the Light and Dark: Dynamic Neovim Theme for the Coder Chameleon

Spread the love

Like many developers, I swear by dark themes in my code editor. While the rumor that they ward off bugs might be a myth, the real benefit lies in eye comfort. However, spending a day glued to a dark screen makes transitioning to the bright outdoors jarring, leaving your eyes feeling strained and slow to adjust.

Light themes offer a solution for daytime coding, but then the night owl in us developers craves the familiar comfort of darkness.

The ideal scenario? A theme that adapts to the rhythm of the day, automatically switching between light and dark.

Sure, manually flipping the switch is possible, but where’s the fun in that?

We developers thrive on automation, and that’s exactly what we’ll tackle in this article. Get ready to transform your Neovim into a dynamic chameleon, seamlessly adjusting its theme to the passing of time.

Select a Neovim Theme to work with

If your current theme doesn’t offer multiple color schemes, consider upgrading!

This lets you effortlessly switch between a calming dark theme for night owls and a bright, vibrant theme for daytime coding. Explore the list of Neovim themes to find your perfect match.

In this article, I use my favorite Nightfox theme as an example.

require('nightfox').setup({
	options = {
    	hide_nc_statusline = false,
    	hide_end_of_buffer = false,
    	styles = {
        	functions = 'italic',
        	comments = 'italic',
        	keywords = 'bold',
        	types = 'italic,bold',
    	}
	}
})

Create the color scheme day timetable

First, you need to have a timetable for the color schemes you want to use during the day.

Since the theme is always in use, there is at most one color scheme active at a time. We store only the start time of the color scheme. The color scheme will persist until the start time of the next color scheme.

colorscheme day timetable
Nightfox theme timetable
local day_time = {
    {
        colorscheme = 'dayfox',
        start_hour = 6,
        start_min = 0,
    },
    {
        colorscheme = 'dawnfox',
        start_hour = 16,
        start_min = 0,
    },
    {
        colorscheme = 'nightfox',
        start_hour = 18,
        start_min = 0,
    }
}

Change color scheme function

To find the color scheme we want to use at the current time, we use the linear search algorithm.

We sort the color scheme day timetable by start time in descending order. Each element of the table is a time chunk.

function set_colorscheme(current_time, colorscheme_time_chunks)
    -- sort the time chunks by start time
    table.sort(colorscheme_time_chunks, function(a, b)
        return a.start_hour > b.start_hour or (a.start_hour == b.start_hour and a.start_min > b.start_min)
    end)
end

After we sort the time chunks in descending order, the color scheme we want to use must be the first one that its time is smaller or equal to the current time.

function set_colorscheme(current_time, colorscheme_time_chunks)
    -- ...

    -- find the current colorscheme
    local colorscheme = colorscheme_time_chunks[1].colorscheme
    for _, tc in ipairs(colorscheme_time_chunks) do
        if current_time.hour > tc.start_hour or (current_time.hour == tc.start_hour and current_time.min > tc.start_min) then
            colorscheme = tc.colorscheme
            break
        end
    end

end

Then we set the color scheme using Neovim command.

function set_colorscheme(current_time, colorscheme_time_chunks)
    -- ...

    vim.cmd('colorscheme ' .. colorscheme)

end

Automate color scheme switching using Neovim auto command

Having the set_colorscheme function, we can easily set Neovim color scheme just by calling it.

local current_time = os.date("*t")
set_colorscheme(current_time, day_time)

However, that is not enough. This only changes the color scheme when we open Neovim.

We want the color scheme to change automatically throughout the day without closing and re-opening Neovim.

To do this, we use the Neovim auto command.

Neovim Auto command will call a function when an event is triggered.

We want the color scheme to change whenever we enter a buffer or when the cursor is on hold. You can find the full events list in the official Neovim documentation.

vim.api.nvim_create_autocmd({"BufEnter", "BufWinEnter", "CursorHold"}, {
    callback = function()
        local current_time = os.date("*t")
        set_colorscheme(current_time, day_time)
    end
})

Start coding in the dynamic environment

Behold, your Neovim is now a dynamic chameleon!

This newfound flexibility will not only bless your eyes with seamless transitions between light and dark, but also inject a touch of fun into your coding sessions.

Say goodbye to strained eyes and hello to a more comfortable, engaging experience.

Here is the full Neovim dynamic color scheme configuration.

Bonus Tip

Want to turn coding into a self-care practice?

Set a custom “alarm” scheme, like a glaring VSCode Red Theme, to remind you when it’s time to take a break and connect with loved ones.

Your eyes and your relationships will thank you!


Spread the love

Leave a Comment

Your email address will not be published. Required fields are marked *