adding all my latest changes

This commit is contained in:
Arnold 2025-11-25 13:54:47 -07:00
parent afafe9735c
commit 276aea77a5
13 changed files with 769 additions and 62 deletions

View File

@ -407,11 +407,30 @@ require('lazy').setup({
-- You can put your default mappings / updates / etc. in here
-- All the info you're looking for is in `:help telescope.setup()`
--
-- defaults = {
-- mappings = {
-- i = { ['<c-enter>'] = 'to_fuzzy_refine' },
-- },
-- },
defaults = {
mappings = {
i = {
['<C-j>'] = 'move_selection_next',
['<C-k>'] = 'move_selection_previous',
},
},
file_ignore_patterns = { '.git/' },
},
pickers = {
find_files = {
hidden = true,
},
live_grep = {
additional_args = function()
return { '--hidden' }
end,
},
grep_string = {
additional_args = function()
return { '--hidden' }
end,
},
},
-- pickers = {}
extensions = {
['ui-select'] = {
@ -432,14 +451,14 @@ require('lazy').setup({
vim.keymap.set('n', '<leader>fs', builtin.builtin, { desc = '[F]ind [S]elect Telescope' })
vim.keymap.set('n', '<leader>fw', builtin.grep_string, { desc = '[F]ind current [W]ord' })
vim.keymap.set('n', '<leader>fg', builtin.live_grep, { desc = '[F]ind by [G]rep' })
vim.keymap.set('n', '<leader>/', builtin.live_grep, { desc = '[F]ind by [G]rep' })
vim.keymap.set('n', '<leader>fd', builtin.diagnostics, { desc = '[F]ind [D]iagnostics' })
vim.keymap.set('n', '<leader>fr', builtin.resume, { desc = '[F]ind [R]esume' })
vim.keymap.set('n', '<leader>f.', builtin.oldfiles, { desc = '[F]ind Recent Files ("." for repeat)' })
vim.keymap.set('n', '<leader><leader>', builtin.buffers, { desc = '[ ] Find existing buffers' })
-- vim.api.nvim_set_keymap('n', 'gd', '<cmd>lua vim.lsp.buf.definition()<CR>', { noremap = true, silent = true })
-- Slightly advanced example of overriding default behavior and theme
vim.keymap.set('n', '<leader>/', function()
vim.keymap.set('n', '<leader>f/', function()
-- You can pass additional configuration to Telescope to change the theme, layout, etc.
builtin.current_buffer_fuzzy_find(require('telescope.themes').get_dropdown {
winblend = 10,
@ -688,6 +707,7 @@ require('lazy').setup({
--
-- But for many setups, the LSP (`ts_ls`) will work just fine
ts_ls = {},
cssls = {},
--
lua_ls = {
@ -819,7 +839,7 @@ require('lazy').setup({
-- Disable "format_on_save lsp_fallback" for languages that don't
-- have a well standardized coding style. You can add additional
-- languages here or re-enable it for the disabled ones.
local disable_filetypes = { c = true, cpp = true, vue = true }
local disable_filetypes = { c = true, cpp = true }
if disable_filetypes[vim.bo[bufnr].filetype] then
return nil
else
@ -831,11 +851,17 @@ require('lazy').setup({
end,
formatters_by_ft = {
lua = { 'stylua' },
-- Conform can also run multiple formatters sequentially
-- python = { "isort", "black" },
--
-- You can use 'stop_after_first' to run the first available formatter from the list
-- javascript = { "prettierd", "prettier", stop_after_first = true },
javascript = { 'prettierd', 'prettier', stop_after_first = true },
typescript = { 'prettierd', 'prettier', stop_after_first = true },
javascriptreact = { 'prettierd', 'prettier', stop_after_first = true },
typescriptreact = { 'prettierd', 'prettier', stop_after_first = true },
vue = { 'prettierd', 'prettier', stop_after_first = true },
css = { 'prettierd', 'prettier', stop_after_first = true },
scss = { 'prettierd', 'prettier', stop_after_first = true },
html = { 'prettierd', 'prettier', stop_after_first = true },
json = { 'prettierd', 'prettier', stop_after_first = true },
yaml = { 'prettierd', 'prettier', stop_after_first = true },
markdown = { 'prettierd', 'prettier', stop_after_first = true },
},
},
},
@ -895,10 +921,11 @@ require('lazy').setup({
-- <c-space>: Open menu or open docs if already open
-- <c-n>/<c-p> or <up>/<down>: Select next/previous item
-- <c-e>: Hide menu
-- <c-k>: Toggle signature help
--
-- See :h blink-cmp-config-keymap for defining your own keymap
preset = 'super-tab',
['<C-j>'] = { 'select_next', 'fallback' },
['<C-k>'] = { 'select_prev', 'fallback' },
-- For more advanced Luasnip keymaps (e.g. selecting choice nodes, expansion) see:
-- https://github.com/L3MON4D3/LuaSnip?tab=readme-ov-file#keymaps
@ -944,28 +971,6 @@ require('lazy').setup({
},
},
{ -- You can easily change to a different colorscheme.
-- Change the name of the colorscheme plugin below, and then
-- change the command in the config to whatever the name of that colorscheme is.
--
-- If you want to see what colorschemes are already installed, you can use `:Telescope colorscheme`.
'folke/tokyonight.nvim',
priority = 1000, -- Make sure to load this before all the other start plugins.
config = function()
---@diagnostic disable-next-line: missing-fields
require('tokyonight').setup {
styles = {
comments = { italic = false }, -- Disable italics in comments
},
}
-- Load the colorscheme here.
-- Like many other themes, this one has different styles, and you could load
-- any other, such as 'tokyonight-storm', 'tokyonight-moon', or 'tokyonight-day'.
vim.cmd.colorscheme 'tokyonight-night'
end,
},
-- Highlight todo, notes, etc in comments
{ 'folke/todo-comments.nvim', event = 'VimEnter', dependencies = { 'nvim-lua/plenary.nvim' }, opts = { signs = false } },
@ -1053,7 +1058,9 @@ require('lazy').setup({
--
-- Uncomment the following line and add your plugins to `lua/custom/plugins/*.lua` to get going.
{ import = 'custom.plugins' },
{ import = 'custom.themes' },
--
-- For additional information with loading, sourcing and examples see `:help lazy.nvim-🔌-plugin-spec`
-- Or use telescope!
-- In normal mode type `<space>sh` then write `lazy.nvim-plugin`

View File

@ -1,23 +1,36 @@
{
"Comment.nvim": { "branch": "master", "commit": "e30b7f2008e52442154b66f7c519bfd2f1e32acb" },
"LuaSnip": { "branch": "master", "commit": "73813308abc2eaeff2bc0d3f2f79270c491be9d7" },
"blink.cmp": { "branch": "main", "commit": "327fff91fe6af358e990be7be1ec8b78037d2138" },
"conform.nvim": { "branch": "master", "commit": "9d859cbfbde7a1bd1770e7c97aef30ec5a237a71" },
"fidget.nvim": { "branch": "main", "commit": "0ba1e16d07627532b6cae915cc992ecac249fb97" },
"gitsigns.nvim": { "branch": "main", "commit": "1ee5c1fd068c81f9dd06483e639c2aa4587dc197" },
"catppuccin": { "branch": "main", "commit": "da33755d00e09bff2473978910168ff9ea5dc453" },
"conform.nvim": { "branch": "master", "commit": "cde4da5c1083d3527776fee69536107d98dae6c9" },
"curl.nvim": { "branch": "main", "commit": "3ee14fbafc8169fc803e80562ce7ac5b4474bdff" },
"fidget.nvim": { "branch": "main", "commit": "e32b672d8fd343f9d6a76944fedb8c61d7d8111a" },
"git-blame.nvim": { "branch": "master", "commit": "9874ec1ec8bc53beb33b7cd82c092b85271a578b" },
"github-theme": { "branch": "main", "commit": "c106c9472154d6b2c74b74565616b877ae8ed31d" },
"gitsigns.nvim": { "branch": "main", "commit": "20ad4419564d6e22b189f6738116b38871082332" },
"guess-indent.nvim": { "branch": "main", "commit": "84a4987ff36798c2fc1169cbaff67960aed9776f" },
"lazy.nvim": { "branch": "main", "commit": "59334064f8604ca073791c25dcc5c9698865406e" },
"lazydev.nvim": { "branch": "main", "commit": "258d2a5ef4a3e3d6d9ba9da72c9725c53e9afcbd" },
"mason-lspconfig.nvim": { "branch": "main", "commit": "155eac5d8609a2f110041f8ac3491664cc126354" },
"harpoon": { "branch": "harpoon2", "commit": "87b1a3506211538f460786c23f98ec63ad9af4e5" },
"lazy.nvim": { "branch": "main", "commit": "85c7ff3711b730b4030d03144f6db6375044ae82" },
"lazydev.nvim": { "branch": "main", "commit": "5231c62aa83c2f8dc8e7ba957aa77098cda1257d" },
"lazygit.nvim": { "branch": "main", "commit": "2305deed25bc61b866d5d39189e9105a45cf1cfb" },
"mason-lspconfig.nvim": { "branch": "main", "commit": "b1d9a914b02ba5660f1e272a03314b31d4576fe2" },
"mason-tool-installer.nvim": { "branch": "main", "commit": "517ef5994ef9d6b738322664d5fdd948f0fdeb46" },
"mason.nvim": { "branch": "main", "commit": "ad7146aa61dcaeb54fa900144d768f040090bff0" },
"mini.nvim": { "branch": "main", "commit": "61a5d44a8f31370710e6a998c5a8ee7e61c7e576" },
"nvim-lspconfig": { "branch": "master", "commit": "e688b486fe9291f151eae7e5c0b5a5c4ef980847" },
"mason.nvim": { "branch": "main", "commit": "57e5a8addb8c71fb063ee4acda466c7cf6ad2800" },
"mini.icons": { "branch": "main", "commit": "ff2e4f1d29f659cc2bad0f9256f2f6195c6b2428" },
"mini.nvim": { "branch": "main", "commit": "dce9bc4e19d02d5c37fe71c16f40f8a5536b0386" },
"monokai-pro.nvim": { "branch": "master", "commit": "1ac671f6da720cba967d28d25c2f16b8b4e18808" },
"nightfox.nvim": { "branch": "main", "commit": "ba47d4b4c5ec308718641ba7402c143836f35aa9" },
"nvim-lspconfig": { "branch": "master", "commit": "95fe3c170753238d3ca4f760e79a991400677abc" },
"nvim-treesitter": { "branch": "master", "commit": "42fc28ba918343ebfd5565147a42a26580579482" },
"oil.nvim": { "branch": "master", "commit": "7e1cd7703ff2924d7038476dcbc04b950203b902" },
"onedark.nvim": { "branch": "master", "commit": "6c10964f91321c6a0f09bcc41dd64e7a6602bc4f" },
"oxocarbon.nvim": { "branch": "main", "commit": "9f85f6090322f39b11ae04a343d4eb9d12a86897" },
"plenary.nvim": { "branch": "master", "commit": "b9fd5226c2f76c951fc8ed5923d85e4de065e509" },
"telescope-fzf-native.nvim": { "branch": "main", "commit": "1f08ed60cafc8f6168b72b80be2b2ea149813e55" },
"telescope-fzf-native.nvim": { "branch": "main", "commit": "6fea601bd2b694c6f2ae08a6c6fab14930c60e2c" },
"telescope-ui-select.nvim": { "branch": "master", "commit": "6e51d7da30bd139a6950adf2a47fda6df9fa06d2" },
"telescope.nvim": { "branch": "master", "commit": "a0bbec21143c7bc5f8bb02e0005fa0b982edc026" },
"todo-comments.nvim": { "branch": "main", "commit": "304a8d204ee787d2544d8bc23cd38d2f929e7cc5" },
"tokyonight.nvim": { "branch": "main", "commit": "4d159616aee17796c2c94d2f5f87d2ee1a3f67c7" },
"which-key.nvim": { "branch": "main", "commit": "904308e6885bbb7b60714c80ab3daf0c071c1492" }
"telescope.nvim": { "branch": "master", "commit": "3a12a853ebf21ec1cce9a92290e3013f8ae75f02" },
"todo-comments.nvim": { "branch": "main", "commit": "31e3c38ce9b29781e4422fc0322eb0a21f4e8668" },
"tokyonight.nvim": { "branch": "main", "commit": "5da1b76e64daf4c5d410f06bcb6b9cb640da7dfd" },
"which-key.nvim": { "branch": "main", "commit": "3aab2147e74890957785941f0c1ad87d0a44c15a" }
}

View File

@ -7,10 +7,10 @@ vim.keymap.set('n', '|', '<cmd>vsplit<CR>', { desc = 'Split window vertically' }
vim.keymap.set('n', '_', '<cmd>split<CR>', { desc = 'Split window horizontally' })
-- Window navigation
vim.keymap.set('n', '<C-h>', '<C-w>h', { desc = 'Move to left window' })
vim.keymap.set('n', '<C-j>', '<C-w>j', { desc = 'Move to window below' })
vim.keymap.set('n', '<C-k>', '<C-w>k', { desc = 'Move to window above' })
vim.keymap.set('n', '<C-l>', '<C-w>l', { desc = 'Move to right window' })
-- vim.keymap.set('n', '<C-h>', '<C-w>h', { desc = 'Move to left window' })
-- vim.keymap.set('n', '<C-j>', '<C-w>j', { desc = 'Move to window below' })
-- vim.keymap.set('n', '<C-k>', '<C-w>k', { desc = 'Move to window above' })
-- vim.keymap.set('n', '<C-l>', '<C-w>l', { desc = 'Move to right window' })
vim.keymap.set('v', 'J', ":m '>+1<CR>gv=gv")
vim.keymap.set('v', 'K', ":m '<-2<CR>gv=gv")
@ -50,10 +50,17 @@ vim.keymap.set('n', '<leader>mr', '<cmd>CellularAutomaton make_it_rain<CR>')
vim.keymap.set('n', '<leader>sf', ':source $HOME/.config/nvim/init.lua <CR>', { desc = 'Source Neovim config' })
vim.keymap.set('n', '<leader><leader>', function()
vim.cmd 'so'
end)
-- Jump to beginning/end of method
vim.keymap.set('n', '[m', '[m', { desc = 'Jump to beginning of method' })
vim.keymap.set('n', ']m', ']m', { desc = 'Jump to end of method' })
-- Diagnostic navigation with float
vim.keymap.set('n', '[d', function()
vim.diagnostic.goto_prev()
vim.diagnostic.open_float()
end, { desc = 'Go to previous diagnostic' })
vim.keymap.set('n', ']d', function()
vim.diagnostic.goto_next()
vim.diagnostic.open_float()
end, { desc = 'Go to next diagnostic' })

View File

@ -0,0 +1 @@
[a relative link](../../../README.md.md)

View File

@ -18,19 +18,19 @@ return {
harpoon.ui:toggle_quick_menu(harpoon:list())
end, { desc = 'Harpoon: Toggle quick menu' })
vim.keymap.set('n', '<leader>h1', function()
vim.keymap.set('n', '<C-j>', function()
harpoon:list():select(1)
end, { desc = 'Harpoon: Go to file 1' })
vim.keymap.set('n', '<leader>h2', function()
vim.keymap.set('n', '<C-k>', function()
harpoon:list():select(2)
end, { desc = 'Harpoon: Go to file 2' })
vim.keymap.set('n', '<leader>h3', function()
vim.keymap.set('n', '<C-l>', function()
harpoon:list():select(3)
end, { desc = 'Harpoon: Go to file 3' })
vim.keymap.set('n', '<leader>h4', function()
vim.keymap.set('n', '<C-h>', function()
harpoon:list():select(4)
end, { desc = 'Harpoon: Go to file 4' })

View File

@ -0,0 +1,22 @@
return {
'kdheepak/lazygit.nvim',
lazy = false,
cmd = {
'LazyGit',
'LazyGitConfig',
'LazyGitCurrentFile',
'LazyGitFilter',
'LazyGitFilterCurrentFile',
},
-- optional for floating window border decoration
dependencies = {
'nvim-telescope/telescope.nvim',
'nvim-lua/plenary.nvim',
},
config = function()
require('telescope').load_extension 'lazygit'
end,
keys = {
{ '<leader>gh', '<cmd>LazyGit<cr>', desc = 'LazyGit' },
},
}

View File

@ -0,0 +1,18 @@
return {
dir = vim.fn.stdpath 'config' .. '/lua/theme-switcher',
name = 'theme-switcher',
lazy = false,
priority = 100,
config = function()
require('theme-switcher').setup {
save_on_select = true,
preview_on_navigate = true,
restore_on_startup = true,
}
-- Keybindings (global, not buffer-specific)
vim.keymap.set('n', '<leader>tt', function()
require('theme-switcher').open()
end, { desc = '[T]heme [T]oggle', noremap = true, silent = true })
end,
}

117
lua/custom/themes/theme.lua Normal file
View File

@ -0,0 +1,117 @@
-- Default theme to load on startup
local DEFAULT_THEME = 'nightfox'
return {
{
'projekt0n/github-nvim-theme',
name = 'github-theme',
lazy = false, -- make sure we load this during startup if it is your main colorscheme
priority = 1000, -- make sure to load this before all the other start plugins
config = function()
require('github-theme').setup {
-- ...
}
vim.cmd 'colorscheme github_dark'
end,
},
-- Nightfox theme
{
'EdenEast/nightfox.nvim',
lazy = false,
priority = 1000,
config = function()
require('nightfox').setup {
options = {
compile_path = vim.fn.stdpath 'cache' .. '/nightfox',
compile_file_suffix = '_compiled',
transparent = false,
terminal_colors = true,
dim_inactive = false,
module_default = true,
colorblind = {
enable = false,
simulate_only = false,
severity = {
protan = 0,
deutan = 0,
tritan = 0,
},
},
styles = {
comments = 'NONE',
conditionals = 'NONE',
constants = 'NONE',
functions = 'NONE',
keywords = 'NONE',
numbers = 'NONE',
operators = 'NONE',
strings = 'NONE',
types = 'NONE',
variables = 'NONE',
},
inverse = {
match_paren = false,
visual = false,
search = false,
},
modules = {},
},
palettes = {},
specs = {},
groups = {},
}
end,
},
-- Oxocarbon theme
{
'nyoom-engineering/oxocarbon.nvim',
lazy = false,
priority = 1000,
},
-- Tokyo Night theme
{
'folke/tokyonight.nvim',
lazy = false,
priority = 1000,
config = function()
---@diagnostic disable-next-line: missing-fields
require('tokyonight').setup {
styles = {
comments = { italic = false },
},
}
-- Set default colorscheme on startup
vim.cmd.colorscheme(DEFAULT_THEME)
end,
},
{
'catppuccin/nvim',
name = 'catppuccin',
lazy = false,
priority = 1000,
config = function()
require('catppuccin').setup {
flavour = 'mocha', -- latte, frappe, macchiato, mocha
}
end,
},
{
'loctvl842/monokai-pro.nvim',
lazy = false,
priority = 1000,
},
{
'navarasu/onedark.nvim',
lazy = false,
priority = 1000,
config = function()
require('onedark').setup {
style = 'dark', -- dark, darker, cool, deep, warm, warmer
}
end,
},
}

View File

@ -0,0 +1,101 @@
local M = {}
-- Simple fuzzy match algorithm
-- Returns score (higher is better) or nil if no match
function M.fuzzy_match(str, pattern)
if pattern == '' then
return 1000 -- Empty pattern matches everything with high score
end
str = str:lower()
pattern = pattern:lower()
local str_idx = 1
local pattern_idx = 1
local score = 0
local consecutive = 0
local last_match_idx = 0
while pattern_idx <= #pattern do
local pattern_char = pattern:sub(pattern_idx, pattern_idx)
local found = false
-- Search for pattern character in remaining string
while str_idx <= #str do
local str_char = str:sub(str_idx, str_idx)
if str_char == pattern_char then
found = true
-- Score bonuses
score = score + 1
-- Bonus for consecutive matches
if str_idx == last_match_idx + 1 then
consecutive = consecutive + 1
score = score + consecutive * 5
else
consecutive = 0
end
-- Bonus for matching at start
if str_idx == 1 then
score = score + 10
end
-- Bonus for matching after separator
if str_idx > 1 then
local prev_char = str:sub(str_idx - 1, str_idx - 1)
if prev_char == '-' or prev_char == '_' or prev_char == ' ' then
score = score + 8
end
end
last_match_idx = str_idx
str_idx = str_idx + 1
break
end
str_idx = str_idx + 1
end
if not found then
return nil -- Pattern doesn't match
end
pattern_idx = pattern_idx + 1
end
return score
end
-- Filter and sort themes by fuzzy match
function M.filter_themes(themes, query)
if query == '' then
return themes
end
local matches = {}
for _, theme in ipairs(themes) do
local score = M.fuzzy_match(theme, query)
if score then
table.insert(matches, { theme = theme, score = score })
end
end
-- Sort by score (descending)
table.sort(matches, function(a, b)
return a.score > b.score
end)
-- Extract just the theme names
local filtered = {}
for _, match in ipairs(matches) do
table.insert(filtered, match.theme)
end
return filtered
end
return M

216
lua/theme-switcher/init.lua Normal file
View File

@ -0,0 +1,216 @@
local M = {}
-- Configuration
local config = {
save_on_select = true,
preview_on_navigate = true,
restore_on_startup = true,
}
-- Store original theme for preview cancellation
local original_theme = nil
local preview_enabled = false
local all_themes = {}
local filtered_themes = {}
local query = ''
-- Setup function
function M.setup(user_config)
config = vim.tbl_deep_extend('force', config, user_config or {})
-- Restore saved theme on startup
if config.restore_on_startup then
local persistence = require 'theme-switcher.persistence'
local themes = require 'theme-switcher.themes'
local saved_theme = persistence.load_theme()
if saved_theme then
themes.apply_theme(saved_theme)
end
end
-- Create user commands
vim.api.nvim_create_user_command('ThemeSwitcher', function()
M.open()
end, {})
vim.api.nvim_create_user_command('ThemeSwitcherSave', function()
local themes = require 'theme-switcher.themes'
local persistence = require 'theme-switcher.persistence'
local current = themes.get_current_theme()
persistence.save_theme(current)
vim.notify('Saved theme: ' .. current, vim.log.levels.INFO)
end, {})
end
-- Open theme switcher
function M.open()
local themes = require 'theme-switcher.themes'
local ui = require 'theme-switcher.ui'
all_themes = themes.get_available_themes()
filtered_themes = all_themes
query = ''
local current_theme = themes.get_current_theme()
-- Store original for preview cancellation
original_theme = current_theme
preview_enabled = config.preview_on_navigate
local buf, win = ui.create_window(filtered_themes, current_theme)
M.setup_keymaps(buf)
end
function M.setup_keymaps(buf)
local opts = { buffer = buf, nowait = true, silent = true }
-- Close and cancel
vim.keymap.set('n', 'q', function()
M.cancel()
end, opts)
vim.keymap.set('n', '<Esc>', function()
M.cancel()
end, opts)
-- Select and apply
vim.keymap.set('n', '<CR>', function()
M.select()
end, opts)
-- Navigation with preview
vim.keymap.set('n', 'j', function()
vim.cmd 'normal! j'
M.preview()
end, opts)
vim.keymap.set('n', 'k', function()
vim.cmd 'normal! k'
M.preview()
end, opts)
vim.keymap.set('n', '<Down>', function()
vim.cmd 'normal! j'
M.preview()
end, opts)
vim.keymap.set('n', '<Up>', function()
vim.cmd 'normal! k'
M.preview()
end, opts)
vim.keymap.set('n', '<C-j>', function()
vim.cmd 'normal! j'
M.preview()
end, opts)
vim.keymap.set('n', '<C-k>', function()
vim.cmd 'normal! k'
M.preview()
end, opts)
-- Text input - any printable character
for i = 32, 126 do
local char = string.char(i)
vim.keymap.set('n', char, function()
M.add_char(char)
end, opts)
end
-- Backspace
vim.keymap.set('n', '<BS>', function()
M.remove_char()
end, opts)
vim.keymap.set('n', '<C-h>', function()
M.remove_char()
end, opts)
-- Clear input
vim.keymap.set('n', '<C-u>', function()
M.clear_input()
end, opts)
-- Toggle preview
vim.keymap.set('n', '<C-p>', function()
preview_enabled = not preview_enabled
vim.notify(preview_enabled and 'Preview enabled' or 'Preview disabled', vim.log.levels.INFO)
end, opts)
end
function M.add_char(char)
query = query .. char
M.update_filter()
end
function M.remove_char()
if #query > 0 then
query = query:sub(1, -2)
M.update_filter()
end
end
function M.clear_input()
query = ''
M.update_filter()
end
function M.update_filter()
local fuzzy = require 'theme-switcher.fuzzy'
local ui = require 'theme-switcher.ui'
local themes = require 'theme-switcher.themes'
filtered_themes = fuzzy.filter_themes(all_themes, query)
ui.update_display(filtered_themes, themes.get_current_theme(), query)
end
-- Preview theme while navigating
function M.preview()
if not preview_enabled then
return
end
local ui = require 'theme-switcher.ui'
local themes = require 'theme-switcher.themes'
local selected = ui.get_selected_theme(filtered_themes)
if selected then
themes.apply_theme(selected)
end
end
-- Select and apply theme
function M.select()
local ui = require 'theme-switcher.ui'
local themes = require 'theme-switcher.themes'
local persistence = require 'theme-switcher.persistence'
local selected = ui.get_selected_theme(filtered_themes)
if selected then
themes.apply_theme(selected)
if config.save_on_select then
persistence.save_theme(selected)
end
vim.notify('Applied theme: ' .. selected, vim.log.levels.INFO)
end
ui.close_window()
end
-- Cancel and restore original theme
function M.cancel()
local ui = require 'theme-switcher.ui'
local themes = require 'theme-switcher.themes'
if preview_enabled and original_theme then
themes.apply_theme(original_theme)
end
ui.close_window()
end
return M

View File

@ -0,0 +1,33 @@
local M = {}
local config_dir = vim.fn.stdpath 'data'
local theme_file = config_dir .. '/theme_preference.txt'
-- Save theme preference
function M.save_theme(theme_name)
local file = io.open(theme_file, 'w')
if file then
file:write(theme_name)
file:close()
return true
end
return false
end
-- Load theme preference
function M.load_theme()
local file = io.open(theme_file, 'r')
if file then
local theme = file:read '*all'
file:close()
return theme:match '^%s*(.-)%s*$' -- trim whitespace
end
return nil
end
-- Delete preference
function M.clear_theme()
os.remove(theme_file)
end
return M

View File

@ -0,0 +1,48 @@
local M = {}
-- Automatically detect installed colorschemes
function M.get_available_themes()
local themes = {}
-- Get all available colorschemes from runtime paths
local colorscheme_files = vim.api.nvim_get_runtime_file('colors/*.vim', true)
local lua_colorschemes = vim.api.nvim_get_runtime_file('colors/*.lua', true)
-- Combine both vim and lua colorschemes
vim.list_extend(colorscheme_files, lua_colorschemes)
for _, file in ipairs(colorscheme_files) do
local name = vim.fn.fnamemodify(file, ':t:r')
table.insert(themes, name)
end
-- Remove duplicates and sort
local seen = {}
local unique = {}
for _, theme in ipairs(themes) do
if not seen[theme] then
seen[theme] = true
table.insert(unique, theme)
end
end
table.sort(unique)
return unique
end
-- Get current colorscheme
function M.get_current_theme()
return vim.g.colors_name or 'default'
end
-- Apply a theme
function M.apply_theme(theme_name)
local ok, err = pcall(vim.cmd.colorscheme, theme_name)
if not ok then
vim.notify('Failed to load theme: ' .. theme_name, vim.log.levels.ERROR)
return false
end
return true
end
return M

124
lua/theme-switcher/ui.lua Normal file
View File

@ -0,0 +1,124 @@
local M = {}
-- Store window and buffer IDs
local win_id = nil
local buf_id = nil
local input_ns = nil
-- Create floating window with search input
function M.create_window(themes, current_theme)
-- Calculate window size
local width = 60
local height = math.min(#themes + 4, 20) -- +4 for header and input
-- Calculate position (center of screen)
local row = math.floor((vim.o.lines - height) / 2)
local col = math.floor((vim.o.columns - width) / 2)
-- Create buffer
buf_id = vim.api.nvim_create_buf(false, true) -- No file, scratch buffer
-- Set buffer options
vim.api.nvim_buf_set_option(buf_id, 'bufhidden', 'wipe')
vim.api.nvim_buf_set_option(buf_id, 'filetype', 'theme-switcher')
vim.api.nvim_buf_set_option(buf_id, 'modifiable', false)
-- Window options
local opts = {
relative = 'editor',
width = width,
height = height,
row = row,
col = col,
style = 'minimal',
border = 'rounded',
title = ' Theme Switcher ',
title_pos = 'center',
}
-- Create window
win_id = vim.api.nvim_open_win(buf_id, true, opts)
-- Window-local options
vim.api.nvim_win_set_option(win_id, 'cursorline', true)
vim.api.nvim_win_set_option(win_id, 'number', false)
vim.api.nvim_win_set_option(win_id, 'relativenumber', false)
input_ns = vim.api.nvim_create_namespace 'theme-switcher-input'
M.update_display(themes, current_theme, '')
return buf_id, win_id
end
-- Update the display with filtered themes
function M.update_display(themes, current_theme, query)
if not buf_id or not vim.api.nvim_buf_is_valid(buf_id) then
return
end
vim.api.nvim_buf_set_option(buf_id, 'modifiable', true)
local lines = {}
-- Input line
table.insert(lines, '> ' .. query)
table.insert(lines, string.rep('', vim.api.nvim_win_get_width(win_id) - 2))
-- Theme list
local current_line = 3
for i, theme in ipairs(themes) do
local prefix = theme == current_theme and '' or ' '
table.insert(lines, prefix .. theme)
if theme == current_theme and query == '' then
current_line = i + 2
end
end
-- Handle empty results
if #themes == 0 then
table.insert(lines, ' No matches found')
end
vim.api.nvim_buf_set_lines(buf_id, 0, -1, false, lines)
vim.api.nvim_buf_set_option(buf_id, 'modifiable', false)
-- Set cursor to first theme (after separator)
if #themes > 0 then
vim.api.nvim_win_set_cursor(win_id, { query == '' and current_line or 3, 0 })
else
vim.api.nvim_win_set_cursor(win_id, { 3, 0 })
end
end
-- Close window
function M.close_window()
if win_id and vim.api.nvim_win_is_valid(win_id) then
vim.api.nvim_win_close(win_id, true)
end
win_id = nil
buf_id = nil
input_ns = nil
end
-- Get selected theme from cursor position
function M.get_selected_theme(themes)
if not win_id then
return nil
end
local cursor = vim.api.nvim_win_get_cursor(win_id)
local line_num = cursor[1]
-- Subtract 2 for input line and separator
local theme_idx = line_num - 2
if theme_idx >= 1 and theme_idx <= #themes then
return themes[theme_idx]
end
return nil
end
return M