Skip to content

Conversation

@alberti42
Copy link

@alberti42 alberti42 commented Sep 13, 2025

Summary

This PR adds an opt-in option sync_start that performs the first dark-mode query synchronously (blocking), so users don’t see a brief flash of the default colorscheme at startup. Subsequent polling remains asynchronous.

It also fixes a legacy Neovim bug where running the timer callback on versions without vim.system caused:

vbnetCopy codeE5560: Vimscript function must not be called in a fast event context

because vim.fn.jobstart() was being invoked in a fast-event context. We now vim.schedule that call to the main loop.

Motivation

  • Avoid a one-frame startup flash before the plugin applies the correct scheme.
  • Keep compatibility with Neovim < 0.10 (no vim.system) without fast-event errors.
  • Do all this without breaking existing configurations and with a minimal API change.

What’s changed

  • New option: sync_start (default false)
    • When true, the first poll runs synchronously and applies the hooks immediately (no vim.schedule), preventing startup flicker.
  • Fix (legacy Neovim): wrap vim.fn.jobstart(...) inside vim.schedule(function() ... end) when called from the timer to avoid E5560.
  • Internals: poll_dark_mode(callback, sync?) now supports both sync and async modes in a single function.
  • Types: documented sync_start in code and corrected the docstring”.

Backwards compatibility

  • Default behavior unchanged (sync_start = false).
  • No breaking API changes; existing configs continue to work.
  • On Neovim ≥ 0.10, we keep using vim.system.
  • On legacy Neovim, we still use jobstart (async) / system (sync) as before, now safely scheduled.

Documentation new feature: sync_start

Here is a suggestion for an extension of current documentation:

Avoid startup flicker with sync_start

If you notice a brief flash of your default colorscheme before auto-dark-mode applies the correct one, enable a synchronous first poll:

require("auto-dark-mode").setup({
  sync_start = true,      -- <— new option
  fallback   = "dark",
  update_interval = 3000,
  set_dark_mode = function()
    vim.api.nvim_set_option_value("background", "dark", {})
    vim.cmd.colorscheme("catppuccin-macchiato")
  end,
  set_light_mode = function()
    vim.api.nvim_set_option_value("background", "light", {})
    vim.cmd.colorscheme("catppuccin-frappe")
  end,
})
  • sync_start = true performs the first OS query blocking, then applies your hooks immediately (no vim.schedule), so there’s no flash.
  • All periodic checks remain asynchronous.

Note: In your init.lua, you don’t need to (and shouldn’t) call require("auto-dark-mode").init() manually; setup() already initializes the plugin.

Disclaimer

This PR was prepared with the help of ChatGPT. All line codes have been tested, and the documentation reviewed manually.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant