--- title: "Make Neovim respect your macOS appearance settings" layout: ../layouts/Post.astro status: published date: 2025-01-07T19:15:46+0000 --- \[_It turns out they're [working on native support for this feature](https://x.com/Neovim/status/1861441698489884936), but it looks like my approach might be more flexible, so I decided to post this anyway._] When I discovered that [Ghostty][ghostty] can change its colours based on the system light/dark mode settings, I was curious whether I could achieve the same effect in Neovim. It turns out, it's possible! (You don't need to use Ghostty for this to work, that was just my inspiration to figure this out.) This code only works on macOS, but I'm sure you could get an AI to translate it to work on Windows or Linux: ```lua function CheckAppearance() local theme = vim.fn.system('defaults read -g AppleInterfaceStyle'):gsub('\n', '') if theme == 'Dark' then vim.o.background = 'dark' vim.cmd('colorscheme modus_vivendi') vim.cmd [[ hi DiffText cterm=bold gui=bold ctermbg=225 guibg=DarkRed ]] -- For some reason the RenderMarkdown plugin doesn't pick up the changes -- when run through an autocmd vim.cmd [[ hi RenderMarkdown_bgtofg_RenderMarkdownCode guifg=#1e1e1e ]] else vim.o.background = 'light' -- These are my settings, but you can go wild and put whatever you want vim.cmd('colorscheme modus_operandi') vim.cmd [[ hi DiffText cterm=bold gui=bold ctermbg=225 guibg=LightRed ]] -- For some reason the RenderMarkdown plugin doesn't pick up the changes -- when run through an autocmd vim.cmd [[ hi RenderMarkdown_bgtofg_RenderMarkdownCode guifg=#f2f2f2 ]] end end -- Run on startup CheckAppearance() ``` So far, it'll just check the appearance setting when you start Neovim. There are a few ways to get it to dynamically detect changes to the setting: _Manually._ Just create a user command and run it manually (ugh): ```lua vim.api.nvim_create_user_command('CheckAppearance', function() CheckAppearance() end, {}) ``` _On focus gained._ This is what I'm using -- Neovim will check the appearance whenever you activate it. This means it won't switch _immediately_ with the system, but it'll always match when you're actually using Neovim: ```lua vim.api.nvim_create_autocmd("FocusGained", { callback = function() CheckAppearance() end, }) ``` Note: Some plugins might not pick up the changes properly, so you might have to add extra stuff in the `CheckAppearance` function, like that `RenderMarkdown_bgtofg_RenderMarkdownCode` highlight rule. Here's what it looks like in the end:
[ghostty]: https://ghostty.org/