git-subtree-dir: old-conf git-subtree-mainline:4667974392git-subtree-split:62a64a79a8
210 lines
5.1 KiB
Lua
210 lines
5.1 KiB
Lua
-- http://lua-users.org/wiki/StringTrim
|
|
function trim6(s)
|
|
return s:match '^()%s*$' and '' or s:match '^%s*(.*%S)'
|
|
end
|
|
|
|
-- from norcalli/nvim_utils
|
|
function nvim_create_augroups(definitions)
|
|
for group_name, definition in pairs(definitions) do
|
|
vim.api.nvim_command('augroup ' .. group_name)
|
|
vim.api.nvim_command('autocmd!')
|
|
for _, def in ipairs(definition) do
|
|
-- if type(def) == 'table' and type(def[#def]) == 'function' then
|
|
-- def[#def] = lua_callback(def[#def])
|
|
-- end
|
|
local command = table.concat(vim.tbl_flatten { 'autocmd', def }, ' ')
|
|
vim.api.nvim_command(command)
|
|
end
|
|
vim.api.nvim_command('augroup END')
|
|
end
|
|
end
|
|
|
|
local state = {
|
|
initialized = false,
|
|
pid = -1,
|
|
stdin_handle = nil,
|
|
config = {},
|
|
}
|
|
|
|
local M = {}
|
|
|
|
local function ensure_config()
|
|
if state.config == nil then
|
|
state.config = {}
|
|
end
|
|
end
|
|
|
|
local function get_config()
|
|
ensure_config()
|
|
return state.config
|
|
end
|
|
|
|
local function edit_config(fn)
|
|
ensure_config()
|
|
fn(state.config)
|
|
end
|
|
|
|
local function apply_mode(mode)
|
|
local config = get_config()
|
|
local sel = config.schemes[mode] or {}
|
|
local colorscheme = sel.colorscheme or nil
|
|
local bg = sel.background or mode
|
|
local lualineTheme = sel.lualine or nil
|
|
|
|
vim.api.nvim_command('set background=' .. bg)
|
|
if colorscheme ~= nil then
|
|
vim.api.nvim_command('colorscheme ' .. colorscheme)
|
|
end
|
|
|
|
require('lualine').setup { options = { theme = lualineTheme } }
|
|
|
|
if config.onchange ~= nil then
|
|
config.onchange(mode)
|
|
end
|
|
|
|
state.current_mode = mode
|
|
end
|
|
|
|
function M.update()
|
|
local mode = vim.fn.system('dark-notify --exit')
|
|
mode = trim6(mode)
|
|
apply_mode(mode)
|
|
end
|
|
|
|
function M.set_mode(mode)
|
|
mode = trim6(mode)
|
|
if not (mode == "light" or mode == "dark") then
|
|
error("mode must be either \"light\" or \"dark\"" .. mode)
|
|
return
|
|
end
|
|
apply_mode(mode)
|
|
end
|
|
|
|
function M.toggle()
|
|
local mode = state.current_mode
|
|
if mode == "light" then
|
|
mode = "dark"
|
|
elseif mode == "dark" then
|
|
mode = "light"
|
|
else
|
|
M.update()
|
|
return
|
|
end
|
|
apply_mode(mode)
|
|
end
|
|
|
|
local function init_dark_notify()
|
|
-- Docs on this vim.loop stuff: https://github.com/luvit/luv
|
|
|
|
local handle, pid
|
|
local stdout = vim.loop.new_pipe(false)
|
|
local stdin = vim.loop.new_pipe(false)
|
|
|
|
local function onexit()
|
|
vim.loop.close(handle, vim.schedule_wrap(function()
|
|
vim.loop.shutdown(stdout)
|
|
vim.loop.shutdown(stdin)
|
|
state.initialized = false
|
|
state.pid = nil
|
|
state.stdin_handle = nil
|
|
end))
|
|
end
|
|
|
|
local function onread(err, chunk)
|
|
assert(not err, err)
|
|
if (chunk) then
|
|
local mode = trim6(chunk)
|
|
if not (mode == "light" or mode == "dark") then
|
|
error("dark-notify output not expected: " .. chunk)
|
|
return
|
|
end
|
|
apply_mode(mode)
|
|
end
|
|
end
|
|
|
|
handle, pid = vim.loop.spawn(
|
|
"dark-notify",
|
|
{ stdio = { stdin, stdout, nil } },
|
|
vim.schedule_wrap(onexit)
|
|
)
|
|
|
|
vim.loop.read_start(stdout, vim.schedule_wrap(onread))
|
|
|
|
state.initialized = true
|
|
state.pid = pid
|
|
state.stdin_handle = stdin
|
|
|
|
-- For whatever reason, nvim isn't killing child processes properly on exit
|
|
-- So if you don't do this, you get zombie dark-notify processes hanging about.
|
|
nvim_create_augroups({
|
|
DarkNotifyKillChildProcess = {
|
|
{ "VimLeave", "*", "lua require('dark_notify').stop()" },
|
|
}
|
|
})
|
|
end
|
|
|
|
-- For whatever reason, killing the child process doesn't work, at all. So we
|
|
-- send it the line "quit\n", and it kills itself.
|
|
function M.stop()
|
|
if state.stdin_handle == nil then
|
|
return
|
|
end
|
|
vim.loop.write(state.stdin_handle, "quit\n")
|
|
-- process quits itself, calls onexit
|
|
-- config gets edited from there
|
|
end
|
|
|
|
function M.configure(config)
|
|
if config == nil then
|
|
return
|
|
end
|
|
local lightline_loaders = config.lightline_loaders or {}
|
|
local schemes = config.schemes or {}
|
|
local onchange = config.onchange
|
|
|
|
for _, mode in pairs({ "light", "dark" }) do
|
|
if type(schemes[mode]) == "string" then
|
|
schemes[mode] = { colorscheme = schemes[mode] }
|
|
end
|
|
end
|
|
|
|
edit_config(function(conf)
|
|
conf.lightline_loaders = lightline_loaders
|
|
conf.schemes = schemes
|
|
conf.onchange = onchange
|
|
end)
|
|
end
|
|
|
|
function M.run(config)
|
|
if config ~= nil or get_config().schemes == nil then
|
|
-- if it's nil, it's a first run, so configure with no options.
|
|
config = config or {}
|
|
M.configure(config)
|
|
end
|
|
|
|
local config = get_config()
|
|
if not config.initialized then
|
|
-- first run on startup, also happens to apply current mode
|
|
init_dark_notify()
|
|
elseif state.current_mode ~= nil then
|
|
-- we have run it before, but we're updating the settings
|
|
-- so don't reset to system, but do apply changed config.
|
|
local mode = state.current_mode
|
|
apply_mode(mode)
|
|
end
|
|
end
|
|
|
|
return M
|
|
|
|
-- init.lua or init.vim in a lua <<EOF
|
|
-- require('dark_notify').run({
|
|
-- lightline_loaders = {
|
|
-- my_colorscheme = "path_to_my_colorscheme's lightline autoload file"
|
|
-- },
|
|
-- schemes = {
|
|
-- dark = "dark colorscheme name",
|
|
-- light = { colorscheme = "light scheme name", background = "optional override, either light or dark" }
|
|
-- },
|
|
-- onchange = function(mode)
|
|
-- end,
|
|
-- })
|