Merge pull request #201 from G-Rowell/dev-chadThemeSwitcher
Chad theme switcher
This commit is contained in:
commit
021cf9c6f4
10 changed files with 298 additions and 20 deletions
3
init.lua
3
init.lua
|
@ -1,7 +1,6 @@
|
||||||
local chad_modules = {
|
local chad_modules = {
|
||||||
"options",
|
"options",
|
||||||
"mappings",
|
"mappings"
|
||||||
"utils"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for i = 1, #chad_modules, 1 do
|
for i = 1, #chad_modules, 1 do
|
||||||
|
|
|
@ -134,6 +134,7 @@ map("n", "<Leader>fp", ":Telescope media_files <CR>", opt)
|
||||||
map("n", "<Leader>fb", ":Telescope buffers<CR>", opt)
|
map("n", "<Leader>fb", ":Telescope buffers<CR>", opt)
|
||||||
map("n", "<Leader>fh", ":Telescope help_tags<CR>", opt)
|
map("n", "<Leader>fh", ":Telescope help_tags<CR>", opt)
|
||||||
map("n", "<Leader>fo", ":Telescope oldfiles<CR>", opt)
|
map("n", "<Leader>fo", ":Telescope oldfiles<CR>", opt)
|
||||||
|
map("n", "<Leader>th", ":Telescope themes<CR>", opt)
|
||||||
|
|
||||||
-- bufferline tab stuff
|
-- bufferline tab stuff
|
||||||
map("n", "<S-t>", ":enew<CR>", opt) -- new buffer
|
map("n", "<S-t>", ":enew<CR>", opt) -- new buffer
|
||||||
|
|
|
@ -65,10 +65,10 @@ for _, plugin in pairs(disabled_built_ins) do
|
||||||
vim.g["loaded_" .. plugin] = 1
|
vim.g["loaded_" .. plugin] = 1
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Opening a file from its last left off position
|
-- Don't show status line on vim terminals
|
||||||
--vim.cmd(
|
vim.cmd [[ au TermOpen term://* setlocal nonumber laststatus=0 ]]
|
||||||
-- [[au BufReadPost * if expand('%:p') !~# '\m/\.git/' && line("'\"") > 1 && line("'\"") <= line("$") | exe "normal! g'\"" | endif]]
|
|
||||||
--)
|
|
||||||
|
|
||||||
-- file extension specific tabbing
|
-- Open a file from its last left off position
|
||||||
-- vim.cmd([[autocmd Filetype python setlocal expandtab tabstop=4 shiftwidth=4 softtabstop=4]])
|
-- vim.cmd [[ au BufReadPost * if expand('%:p') !~# '\m/\.git/' && line("'\"") > 1 && line("'\"") <= line("$") | exe "normal! g'\"" | endif ]]
|
||||||
|
-- File extension specific tabbing
|
||||||
|
-- vim.cmd [[ autocmd Filetype python setlocal expandtab tabstop=4 shiftwidth=4 softtabstop=4 ]]
|
||||||
|
|
|
@ -109,7 +109,6 @@ vim.lsp.handlers["textDocument/publishDiagnostics"] =
|
||||||
},
|
},
|
||||||
signs = true,
|
signs = true,
|
||||||
underline = true,
|
underline = true,
|
||||||
|
|
||||||
-- set this to true if you want diagnostics to show in insert mode
|
-- set this to true if you want diagnostics to show in insert mode
|
||||||
update_in_insert = false
|
update_in_insert = false
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,3 +93,6 @@ g.nvim_tree_bindings = {
|
||||||
{key = "q", cb = tree_cb("close")},
|
{key = "q", cb = tree_cb("close")},
|
||||||
{key = "g?", cb = tree_cb("toggle_help")}
|
{key = "g?", cb = tree_cb("toggle_help")}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
-- hide statusline when nvim tree is opened
|
||||||
|
vim.cmd [[au BufEnter,BufWinEnter,WinEnter,CmdwinEnter * if bufname('%') == "NvimTree" | set laststatus=0 | else | set laststatus=2 | endif]]
|
||||||
|
|
|
@ -67,6 +67,9 @@ telescope.setup(
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
-- load the theme_switcher extension
|
||||||
|
require("telescope").load_extension("themes")
|
||||||
|
|
||||||
if
|
if
|
||||||
not pcall(
|
not pcall(
|
||||||
function()
|
function()
|
||||||
|
|
185
lua/telescope/_extensions/themes.lua
Normal file
185
lua/telescope/_extensions/themes.lua
Normal file
|
@ -0,0 +1,185 @@
|
||||||
|
-- This file can be loaded as a telescope extension
|
||||||
|
local M = {}
|
||||||
|
|
||||||
|
-- reload themes without restarting vim
|
||||||
|
-- if no theme name given then reload the current theme
|
||||||
|
M.reload_theme = function(theme_name)
|
||||||
|
local reload_plugin = require("utils").reload_plugin
|
||||||
|
|
||||||
|
-- if theme name is empty or nil, then reload the current theme
|
||||||
|
if (theme_name == nil or theme_name == "") then
|
||||||
|
theme_name = vim.g.nvchad_theme
|
||||||
|
end
|
||||||
|
|
||||||
|
if not pcall(require, "themes/" .. theme_name) then
|
||||||
|
error("No such theme ( " .. theme_name .. " )")
|
||||||
|
end
|
||||||
|
|
||||||
|
vim.g.nvchad_theme = theme_name
|
||||||
|
|
||||||
|
-- reload the base16 theme
|
||||||
|
local ok, base16 = pcall(require, "base16")
|
||||||
|
if not ok then
|
||||||
|
error("Error: Cannot load base16 plugin!")
|
||||||
|
end
|
||||||
|
base16(base16.themes[theme_name], true)
|
||||||
|
|
||||||
|
reload_plugin {
|
||||||
|
"highlights",
|
||||||
|
"plugins.bufferline",
|
||||||
|
"galaxyline",
|
||||||
|
"plugins.statusline"
|
||||||
|
}
|
||||||
|
|
||||||
|
-- now send the provider info to actual refresh
|
||||||
|
require("galaxyline.provider").async_load_providers:send()
|
||||||
|
|
||||||
|
return true
|
||||||
|
-- open a buffer and close it to reload the statusline
|
||||||
|
-- vim.cmd("new|bwipeout")
|
||||||
|
-- commented out here as it will not work with telescope picker
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Custom theme picker
|
||||||
|
-- Most of the code is copied from telescope colorscheme plugin, mostly for preview creation
|
||||||
|
M.theme_switcher = function(opts)
|
||||||
|
local pickers, finders, previewers, actions, action_state, utils, conf
|
||||||
|
if pcall(require, "telescope") then
|
||||||
|
pickers = require "telescope.pickers"
|
||||||
|
finders = require "telescope.finders"
|
||||||
|
previewers = require "telescope.previewers"
|
||||||
|
|
||||||
|
actions = require "telescope.actions"
|
||||||
|
action_state = require "telescope.actions.state"
|
||||||
|
utils = require "telescope.utils"
|
||||||
|
conf = require("telescope.config").values
|
||||||
|
else
|
||||||
|
error "Cannot find telescope!"
|
||||||
|
end
|
||||||
|
|
||||||
|
local local_utils = require "utils"
|
||||||
|
local reload_theme = M.reload_theme
|
||||||
|
|
||||||
|
-- get a table of available themes
|
||||||
|
local themes = local_utils.list_themes()
|
||||||
|
if next(themes) ~= nil then
|
||||||
|
-- save this to use it for later to restore if theme not changed
|
||||||
|
local current_theme = vim.g.nvchad_theme
|
||||||
|
local new_theme = ""
|
||||||
|
local change = false
|
||||||
|
|
||||||
|
-- buffer number and name
|
||||||
|
local bufnr = vim.api.nvim_get_current_buf()
|
||||||
|
local bufname = vim.api.nvim_buf_get_name(bufnr)
|
||||||
|
|
||||||
|
local previewer
|
||||||
|
|
||||||
|
-- in case its not a normal buffer
|
||||||
|
if vim.fn.buflisted(bufnr) ~= 1 then
|
||||||
|
local deleted = false
|
||||||
|
local function del_win(win_id)
|
||||||
|
if win_id and vim.api.nvim_win_is_valid(win_id) then
|
||||||
|
utils.buf_delete(vim.api.nvim_win_get_buf(win_id))
|
||||||
|
pcall(vim.api.nvim_win_close, win_id, true)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
previewer =
|
||||||
|
previewers.new {
|
||||||
|
preview_fn = function(_, entry, status)
|
||||||
|
if not deleted then
|
||||||
|
deleted = true
|
||||||
|
del_win(status.preview_win)
|
||||||
|
del_win(status.preview_border_win)
|
||||||
|
end
|
||||||
|
reload_theme(entry.value)
|
||||||
|
end
|
||||||
|
}
|
||||||
|
else
|
||||||
|
-- show current buffer content in previewer
|
||||||
|
previewer =
|
||||||
|
previewers.new_buffer_previewer {
|
||||||
|
get_buffer_by_name = function()
|
||||||
|
return bufname
|
||||||
|
end,
|
||||||
|
define_preview = function(self, entry)
|
||||||
|
if vim.loop.fs_stat(bufname) then
|
||||||
|
conf.buffer_previewer_maker(bufname, self.state.bufnr, {bufname = self.state.bufname})
|
||||||
|
else
|
||||||
|
local lines = vim.api.nvim_buf_get_lines(bufnr, 0, -1, false)
|
||||||
|
vim.api.nvim_buf_set_lines(self.state.bufnr, 0, -1, false, lines)
|
||||||
|
end
|
||||||
|
reload_theme(entry.value)
|
||||||
|
end
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
local picker =
|
||||||
|
pickers.new(
|
||||||
|
{
|
||||||
|
prompt_title = "Set NvChad color",
|
||||||
|
finder = finders.new_table(themes),
|
||||||
|
previewer = previewer,
|
||||||
|
sorter = conf.generic_sorter(opts),
|
||||||
|
attach_mappings = function()
|
||||||
|
actions.select_default:replace(
|
||||||
|
-- if a entry is selected, change current_theme to that
|
||||||
|
function(prompt_bufnr)
|
||||||
|
local selection = action_state.get_selected_entry()
|
||||||
|
new_theme = selection.value
|
||||||
|
change = true
|
||||||
|
actions.close(prompt_bufnr)
|
||||||
|
end
|
||||||
|
)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
-- rewrite picker.close_windows
|
||||||
|
local close_windows = picker.close_windows
|
||||||
|
picker.close_windows = function(status)
|
||||||
|
close_windows(status)
|
||||||
|
-- now apply the theme, if success, then ask for default theme change
|
||||||
|
local final_theme
|
||||||
|
if change then
|
||||||
|
final_theme = new_theme
|
||||||
|
else
|
||||||
|
final_theme = current_theme
|
||||||
|
end
|
||||||
|
|
||||||
|
if reload_theme(final_theme) then
|
||||||
|
if change then
|
||||||
|
-- ask for confirmation to set as default theme
|
||||||
|
local ans = string.lower(vim.fn.input("Set " .. new_theme .. " as default theme ? [y/N] ")) == "y"
|
||||||
|
if ans then
|
||||||
|
local_utils.change_theme(current_theme, final_theme)
|
||||||
|
else
|
||||||
|
-- will be used in restoring nvchad theme var
|
||||||
|
final_theme = current_theme
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- open a buffer and close it to reload the statusline
|
||||||
|
vim.cmd("new|bwipeout")
|
||||||
|
end
|
||||||
|
-- set nvchad_theme global var
|
||||||
|
vim.g.nvchad_theme = current_theme
|
||||||
|
end
|
||||||
|
-- launch the telescope picker
|
||||||
|
picker:find()
|
||||||
|
else
|
||||||
|
print("No themes found in " .. themes_folder)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- register theme swticher as themes to telescope
|
||||||
|
local present, telescope = pcall(require, "telescope")
|
||||||
|
if present then
|
||||||
|
return telescope.register_extension {
|
||||||
|
exports = {
|
||||||
|
themes = M.theme_switcher
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
error "Cannot find telescope!"
|
||||||
|
end
|
|
@ -1,9 +1,9 @@
|
||||||
local chad_theme = require("user_config").ui.theme
|
local chad_theme = require("user_config").ui.theme
|
||||||
|
|
||||||
vim.g.nvchad_theme = chad_theme
|
vim.g.nvchad_theme = chad_theme
|
||||||
local present2, base16 = pcall(require, "base16")
|
local present, base16 = pcall(require, "base16")
|
||||||
|
|
||||||
if present2 then
|
if present then
|
||||||
base16(base16.themes[chad_theme], true)
|
base16(base16.themes[chad_theme], true)
|
||||||
require "highlights"
|
require "highlights"
|
||||||
return true
|
return true
|
||||||
|
|
104
lua/utils.lua
104
lua/utils.lua
|
@ -1,8 +1,96 @@
|
||||||
-- hide line numbers , statusline in specific buffers!
|
local M = {}
|
||||||
vim.api.nvim_exec(
|
|
||||||
[[
|
-- reload a plugin ( will try to load even if not loaded)
|
||||||
au TermOpen term://* setlocal nonumber laststatus=0
|
-- can take a string or list ( table )
|
||||||
au BufEnter,BufWinEnter,WinEnter,CmdwinEnter * if bufname('%') == "NvimTree" | set laststatus=0 | else | set laststatus=2 | endif
|
M.reload_plugin = function(plugins)
|
||||||
]],
|
local function _reload_plugin(plugin)
|
||||||
false
|
local loaded = package.loaded[plugin]
|
||||||
)
|
if loaded then
|
||||||
|
package.loaded[plugin] = nil
|
||||||
|
end
|
||||||
|
if not pcall(require, plugin) then
|
||||||
|
error("Error: Cannot load " .. plugin .. " plugin!")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if type(plugins) == "string" then
|
||||||
|
_reload_plugin(plugins)
|
||||||
|
elseif type(plugins) == "table" then
|
||||||
|
for _, plugin in ipairs(plugins) do
|
||||||
|
_reload_plugin(plugin)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- return a table of available themes
|
||||||
|
M.list_themes = function(return_type)
|
||||||
|
local themes = {}
|
||||||
|
-- folder where theme files are stored
|
||||||
|
local themes_folder = vim.fn.stdpath("config") .. "/lua/themes"
|
||||||
|
-- list all the contents of the folder and filter out files with .lua extension, then append to themes table
|
||||||
|
local fd = vim.loop.fs_scandir(themes_folder)
|
||||||
|
if fd then
|
||||||
|
while true do
|
||||||
|
local name, typ = vim.loop.fs_scandir_next(fd)
|
||||||
|
if name == nil then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
if typ ~= "directory" and string.find(name, ".lua") then
|
||||||
|
-- return the table values as keys if specified
|
||||||
|
if return_type == "keys_as_value" then
|
||||||
|
themes[vim.fn.fnamemodify(name, ":r")] = true
|
||||||
|
else
|
||||||
|
table.insert(themes, vim.fn.fnamemodify(name, ":r"))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return themes
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 1st arg - r or w
|
||||||
|
-- 2nd arg - file path
|
||||||
|
-- 3rd arg - content if 1st arg is w
|
||||||
|
-- return file data on read, nothing on write
|
||||||
|
M.file = function(mode, filepath, content)
|
||||||
|
local data
|
||||||
|
local fd = assert(vim.loop.fs_open(filepath, mode, 438))
|
||||||
|
local stat = assert(vim.loop.fs_fstat(fd))
|
||||||
|
if stat.type ~= "file" then
|
||||||
|
data = false
|
||||||
|
else
|
||||||
|
if mode == "r" then
|
||||||
|
data = assert(vim.loop.fs_read(fd, stat.size, 0))
|
||||||
|
else
|
||||||
|
assert(vim.loop.fs_write(fd, content, 0))
|
||||||
|
data = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
assert(vim.loop.fs_close(fd))
|
||||||
|
return data
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 1st arg as current theme, 2nd as new theme
|
||||||
|
M.change_theme = function(current_theme, new_theme)
|
||||||
|
if current_theme == nil or new_theme == nil then
|
||||||
|
error "Provide current and new theme name"
|
||||||
|
end
|
||||||
|
if current_theme == new_theme then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local file = vim.fn.stdpath("config") .. "/lua/user_config.lua"
|
||||||
|
-- store in data variable
|
||||||
|
local data = assert(M.file("r", file))
|
||||||
|
local find = "theme = .?" .. current_theme .. ".?"
|
||||||
|
local replace = 'theme = "' .. new_theme .. '"'
|
||||||
|
local content = string.gsub(data, find, replace)
|
||||||
|
-- see if the find string exists in file
|
||||||
|
if content == data then
|
||||||
|
error("Cannot change default theme with " .. new_theme .. ", edit " .. file .. " manually")
|
||||||
|
else
|
||||||
|
assert(M.file("w", file, content))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return M
|
||||||
|
|
Loading…
Reference in a new issue