From 6c6f3e1db690e123d8edb9d74700397d2989579b Mon Sep 17 00:00:00 2001 From: Tony Banh Date: Tue, 21 Apr 2026 17:30:46 -0700 Subject: [PATCH 01/28] misc nvim changes --- dot_config/nvim/lua/config/autocmds.lua | 8 ++------ dot_config/nvim/lua/plugins/ai/sidekick.lua | 9 +++++++++ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/dot_config/nvim/lua/config/autocmds.lua b/dot_config/nvim/lua/config/autocmds.lua index 971928e..4eed155 100644 --- a/dot_config/nvim/lua/config/autocmds.lua +++ b/dot_config/nvim/lua/config/autocmds.lua @@ -68,9 +68,7 @@ end, { usercmd("Btop", function() if vim.fn.executable("btop") == 1 then Snacks.terminal.toggle("btop", { - win = vim.g.floating_terminal and { - style = "float", - } or { + win = { style = "terminal", width = 0, height = 0, @@ -88,9 +86,7 @@ end, { usercmd("Gh", function() if vim.fn.executable("gh") == 1 then Snacks.terminal.toggle({ "gh", "dash" }, { - win = vim.g.floating_terminal and { - style = "float", - } or { + win = { style = "terminal", width = 0, height = 0, diff --git a/dot_config/nvim/lua/plugins/ai/sidekick.lua b/dot_config/nvim/lua/plugins/ai/sidekick.lua index 6e52761..c014df7 100644 --- a/dot_config/nvim/lua/plugins/ai/sidekick.lua +++ b/dot_config/nvim/lua/plugins/ai/sidekick.lua @@ -11,11 +11,20 @@ return { enabled = vim.fn.executable("tmux") == 1, }, win = { + wo = { + scrolloff = 0, -- prevent global scrolloff from shifting terminal view on toggle + }, layout = vim.g.floating_terminal and "float" or "right", ---@type "float"|"left"|"bottom"|"top"|"right" float = { width = 0.6, height = 0.6, }, + -- Options used when layout is "left"|"bottom"|"top"|"right" + ---@type vim.api.keyset.win_config + split = { + width = 0, -- set to 0 for default split width + height = 0, -- set to 0 for default split height + }, }, }, nes = { From 2fc247058b7d2d7bdb3a01bc2cd2febe0f6fa115 Mon Sep 17 00:00:00 2001 From: Tony Banh Date: Tue, 21 Apr 2026 17:31:44 -0700 Subject: [PATCH 02/28] forget opencode --- dot_config/opencode/dot_gitignore | 4 -- dot_config/opencode/opencode.jsonc | 13 ---- dot_config/opencode/themes/transparent.json | 79 --------------------- dot_config/opencode/tui.json | 14 ---- 4 files changed, 110 deletions(-) delete mode 100644 dot_config/opencode/dot_gitignore delete mode 100644 dot_config/opencode/opencode.jsonc delete mode 100644 dot_config/opencode/themes/transparent.json delete mode 100644 dot_config/opencode/tui.json diff --git a/dot_config/opencode/dot_gitignore b/dot_config/opencode/dot_gitignore deleted file mode 100644 index 25cb250..0000000 --- a/dot_config/opencode/dot_gitignore +++ /dev/null @@ -1,4 +0,0 @@ -node_modules -package.json -bun.lock -.gitignore \ No newline at end of file diff --git a/dot_config/opencode/opencode.jsonc b/dot_config/opencode/opencode.jsonc deleted file mode 100644 index 17ff5f3..0000000 --- a/dot_config/opencode/opencode.jsonc +++ /dev/null @@ -1,13 +0,0 @@ -// https://opencode.ai/docs/config/ -{ - "$schema": "https://opencode.ai/config.json", - "plugin": ["opencode-anthropic-auth@latest"], - - "permission": { - "external_directory": { - "~/.config/opencode/**": "allow", - "~/obsidian-vault/**": "allow", - "~/.claude/agents/**": "allow", - }, - }, -} diff --git a/dot_config/opencode/themes/transparent.json b/dot_config/opencode/themes/transparent.json deleted file mode 100644 index f1b1e82..0000000 --- a/dot_config/opencode/themes/transparent.json +++ /dev/null @@ -1,79 +0,0 @@ -{ - "$schema": "https://opencode.ai/theme.json", - "defs": { - "fg": "#d3c6aa", - "fgMuted": "#7a8478", - "green": "#83c092", - "blue": "#7393b3", - "red": "#e67e80", - "orange": "#e69875", - "yellow": "#dbbc7f", - "pink": "#d699b6", - "aqua": "#95d1c9", - "gutter": "#859289", - "gutterActive": "#9da9a0", - "panel": "#333c43", - "diffGreen": "#4fd6be", - "diffRed": "#c53b53", - "diffPurple": "#828bb8", - "diffGreenHighlight": "#b8db87", - "diffRedHighlight": "#e26a75", - "diffGreenBg": "#20303b", - "diffRedBg": "#37222c", - "diffLineNum": "#a0a5a7", - "diffGreenLineNumBg": "#1b2b34", - "diffRedLineNumBg": "#2d1f26" - }, - "theme": { - "primary": "green", - "secondary": "blue", - "accent": "pink", - "error": "red", - "warning": "orange", - "success": "green", - "info": "aqua", - "text": "fg", - "textMuted": "fgMuted", - "background": "transparent", - "backgroundPanel": "transparent", - "backgroundElement": "transparent", - "border": "gutter", - "borderActive": "gutterActive", - "borderSubtle": "fgMuted", - "diffAdded": "diffGreen", - "diffRemoved": "diffRed", - "diffContext": "diffPurple", - "diffHunkHeader": "diffPurple", - "diffHighlightAdded": "diffGreenHighlight", - "diffHighlightRemoved": "diffRedHighlight", - "diffAddedBg": "diffGreenBg", - "diffRemovedBg": "diffRedBg", - "diffContextBg": "transparent", - "diffLineNumber": "diffLineNum", - "diffAddedLineNumberBg": "diffGreenLineNumBg", - "diffRemovedLineNumberBg": "diffRedLineNumBg", - "markdownText": "fg", - "markdownHeading": "pink", - "markdownLink": "green", - "markdownLinkText": "aqua", - "markdownCode": "green", - "markdownBlockQuote": "yellow", - "markdownEmph": "yellow", - "markdownStrong": "orange", - "markdownHorizontalRule": "fgMuted", - "markdownListItem": "green", - "markdownListEnumeration": "aqua", - "markdownImage": "green", - "markdownImageText": "aqua", - "markdownCodeBlock": "fg", - "syntaxComment": "fgMuted", - "syntaxKeyword": "pink", - "syntaxFunction": "green", - "syntaxVariable": "red", - "syntaxString": "green", - "syntaxNumber": "orange", - "syntaxType": "yellow", - "syntaxOperator": "aqua", - "syntaxPunctuation": "fg" - } -} diff --git a/dot_config/opencode/tui.json b/dot_config/opencode/tui.json deleted file mode 100644 index 9df60ef..0000000 --- a/dot_config/opencode/tui.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "https://opencode.ai/tui.json", - "theme": "transparent", - "keybinds": { - "leader": "ctrl+o", - "command_list": ":", - "history_previous": "up,ctrl+p", - "history_next": "down,ctrl+n", - "messages_line_up": "ctrl+y", - "messages_line_down": "ctrl+e", - "messages_half_page_up": "ctrl+u", - "messages_half_page_down": "ctrl+d" - } -} From d81a5cf38890524d06f9b654f0d31997eb9cf51c Mon Sep 17 00:00:00 2001 From: Tony Banh Date: Tue, 21 Apr 2026 17:37:33 -0700 Subject: [PATCH 03/28] re-add opencode --- dot_config/opencode/dot_gitignore | 4 + dot_config/opencode/opencode.jsonc | 21 +++++ .../opencode/skills/grill-plan/SKILL.md | 16 ++++ dot_config/opencode/themes/transparent.json | 79 +++++++++++++++++++ dot_config/opencode/tui.json | 14 ++++ 5 files changed, 134 insertions(+) create mode 100644 dot_config/opencode/dot_gitignore create mode 100644 dot_config/opencode/opencode.jsonc create mode 100644 dot_config/opencode/skills/grill-plan/SKILL.md create mode 100644 dot_config/opencode/themes/transparent.json create mode 100644 dot_config/opencode/tui.json diff --git a/dot_config/opencode/dot_gitignore b/dot_config/opencode/dot_gitignore new file mode 100644 index 0000000..25cb250 --- /dev/null +++ b/dot_config/opencode/dot_gitignore @@ -0,0 +1,4 @@ +node_modules +package.json +bun.lock +.gitignore \ No newline at end of file diff --git a/dot_config/opencode/opencode.jsonc b/dot_config/opencode/opencode.jsonc new file mode 100644 index 0000000..a7faf05 --- /dev/null +++ b/dot_config/opencode/opencode.jsonc @@ -0,0 +1,21 @@ +// https://opencode.ai/docs/config/ +{ + "$schema": "https://opencode.ai/config.json", + "plugin": ["opencode-anthropic-auth@latest"], + + "mcp": { + }, + "permission": { + "external_directory": { + "~/.config/opencode/**": "allow", + "~/obsidian-vault/**": "allow", + "~/.claude/agents/**": "allow", + "~/.local/share/nvim/**": "allow", + }, + "edit": { + "~/.local/share/nvim/**": "deny", + }, + }, + "agent": { + }, +} diff --git a/dot_config/opencode/skills/grill-plan/SKILL.md b/dot_config/opencode/skills/grill-plan/SKILL.md new file mode 100644 index 0000000..8e4387f --- /dev/null +++ b/dot_config/opencode/skills/grill-plan/SKILL.md @@ -0,0 +1,16 @@ +--- +name: grill-plan +description: Interview the user relentlessly about a plan or design until reaching shared understanding, resolving each branch of the decision tree. Use when user wants to stress-test a plan, get grilled on their design, or mentions "grill plan". +--- + +## What I do + +Interview me relentlessly about every aspect of this plan until we reach a shared understanding. Walk down each branch of the design tree, resolving dependencies between decisions one-by-one. For each question, provide your recommended answer. + +Ask the questions one at a time. + +If a question can be answered by exploring the codebase, explore the codebase instead. + +## When to use me + +Use when user wants to stress-test a plan, get grilled on their design, or mentions "grill plan". diff --git a/dot_config/opencode/themes/transparent.json b/dot_config/opencode/themes/transparent.json new file mode 100644 index 0000000..f1b1e82 --- /dev/null +++ b/dot_config/opencode/themes/transparent.json @@ -0,0 +1,79 @@ +{ + "$schema": "https://opencode.ai/theme.json", + "defs": { + "fg": "#d3c6aa", + "fgMuted": "#7a8478", + "green": "#83c092", + "blue": "#7393b3", + "red": "#e67e80", + "orange": "#e69875", + "yellow": "#dbbc7f", + "pink": "#d699b6", + "aqua": "#95d1c9", + "gutter": "#859289", + "gutterActive": "#9da9a0", + "panel": "#333c43", + "diffGreen": "#4fd6be", + "diffRed": "#c53b53", + "diffPurple": "#828bb8", + "diffGreenHighlight": "#b8db87", + "diffRedHighlight": "#e26a75", + "diffGreenBg": "#20303b", + "diffRedBg": "#37222c", + "diffLineNum": "#a0a5a7", + "diffGreenLineNumBg": "#1b2b34", + "diffRedLineNumBg": "#2d1f26" + }, + "theme": { + "primary": "green", + "secondary": "blue", + "accent": "pink", + "error": "red", + "warning": "orange", + "success": "green", + "info": "aqua", + "text": "fg", + "textMuted": "fgMuted", + "background": "transparent", + "backgroundPanel": "transparent", + "backgroundElement": "transparent", + "border": "gutter", + "borderActive": "gutterActive", + "borderSubtle": "fgMuted", + "diffAdded": "diffGreen", + "diffRemoved": "diffRed", + "diffContext": "diffPurple", + "diffHunkHeader": "diffPurple", + "diffHighlightAdded": "diffGreenHighlight", + "diffHighlightRemoved": "diffRedHighlight", + "diffAddedBg": "diffGreenBg", + "diffRemovedBg": "diffRedBg", + "diffContextBg": "transparent", + "diffLineNumber": "diffLineNum", + "diffAddedLineNumberBg": "diffGreenLineNumBg", + "diffRemovedLineNumberBg": "diffRedLineNumBg", + "markdownText": "fg", + "markdownHeading": "pink", + "markdownLink": "green", + "markdownLinkText": "aqua", + "markdownCode": "green", + "markdownBlockQuote": "yellow", + "markdownEmph": "yellow", + "markdownStrong": "orange", + "markdownHorizontalRule": "fgMuted", + "markdownListItem": "green", + "markdownListEnumeration": "aqua", + "markdownImage": "green", + "markdownImageText": "aqua", + "markdownCodeBlock": "fg", + "syntaxComment": "fgMuted", + "syntaxKeyword": "pink", + "syntaxFunction": "green", + "syntaxVariable": "red", + "syntaxString": "green", + "syntaxNumber": "orange", + "syntaxType": "yellow", + "syntaxOperator": "aqua", + "syntaxPunctuation": "fg" + } +} diff --git a/dot_config/opencode/tui.json b/dot_config/opencode/tui.json new file mode 100644 index 0000000..9df60ef --- /dev/null +++ b/dot_config/opencode/tui.json @@ -0,0 +1,14 @@ +{ + "$schema": "https://opencode.ai/tui.json", + "theme": "transparent", + "keybinds": { + "leader": "ctrl+o", + "command_list": ":", + "history_previous": "up,ctrl+p", + "history_next": "down,ctrl+n", + "messages_line_up": "ctrl+y", + "messages_line_down": "ctrl+e", + "messages_half_page_up": "ctrl+u", + "messages_half_page_down": "ctrl+d" + } +} From 75bce4aec1aa5f405083b6d1eb656ef23c672c05 Mon Sep 17 00:00:00 2001 From: Tony Banh Date: Tue, 21 Apr 2026 22:00:48 -0700 Subject: [PATCH 04/28] misc --- dot_config/sesh/sesh.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dot_config/sesh/sesh.toml b/dot_config/sesh/sesh.toml index c5d48f5..bacfbe6 100644 --- a/dot_config/sesh/sesh.toml +++ b/dot_config/sesh/sesh.toml @@ -1,4 +1,4 @@ -blacklist = ['sidekick claude', 'floating-tmux', 'claude '] +blacklist = ['sidekick claude', 'floating-tmux', 'claude ', 'opencode '] [[window]] name = "opencode" From 9c0ce068ffb67f48080952665af32849f351e4d5 Mon Sep 17 00:00:00 2001 From: Tony Banh Date: Tue, 21 Apr 2026 22:53:21 -0700 Subject: [PATCH 05/28] yazi: update colors for custom everforest --- dot_config/yazi/init.lua | 4 +- dot_config/yazi/theme.toml | 119 +++++++++++++++++++++++++++++++++++-- 2 files changed, 117 insertions(+), 6 deletions(-) diff --git a/dot_config/yazi/init.lua b/dot_config/yazi/init.lua index 20ab9ec..99c9094 100644 --- a/dot_config/yazi/init.lua +++ b/dot_config/yazi/init.lua @@ -67,8 +67,8 @@ Status:children_add(function(self) local files_selected = #cx.active.selected local files_cut = cx.yanked.is_cut - local selected_fg = files_selected > 0 and "yellow" or "grey" - local yanked_fg = files_yanked > 0 and (files_cut and "magenta" or "green") or "grey" + local selected_fg = files_selected > 0 and "#dbbc7f" or "#9DA9A0" + local yanked_fg = files_yanked > 0 and (files_cut and "#e67e80" or "#83c092") or "#9DA9A0" local selected_text = files_selected > 0 and "󰼢 " .. files_selected or "󰼢 " .. "0" local yanked_text = files_yanked > 0 and "󱉨 " .. files_yanked or "󱉨 " .. "0" diff --git a/dot_config/yazi/theme.toml b/dot_config/yazi/theme.toml index 7fd4288..67555b6 100644 --- a/dot_config/yazi/theme.toml +++ b/dot_config/yazi/theme.toml @@ -2,15 +2,126 @@ # dark = "kanagawa" [mgr] -marker_selected = { fg = "yellow", bg = 'yellow' } -marker_copied = { fg = "green", bg = 'green' } -marker_cut = { fg = "magenta", bg = 'magenta' } +cwd = { fg = "#7393b3" } + +# Find +find_keyword = { fg = "#dbbc7f", bold = true, italic = true, underline = true } +find_position = { fg = "#d699b6", bg = "reset", bold = true, italic = true } + +# Marker +marker_copied = { fg = "#83c092", bg = "#83c092" } +marker_cut = { fg = "#e67e80", bg = "#e67e80" } +marker_marked = { fg = "#7393b3", bg = "#7393b3" } +marker_selected = { fg = "#dbbc7f", bg = "#dbbc7f" } + +# Count +count_copied = { fg = "#343f44", bg = "#83c092" } +count_cut = { fg = "#343f44", bg = "#e67e80" } +count_selected = { fg = "#343f44", bg = "#dbbc7f" } + +# Border +border_symbol = "│" +border_style = { fg = "#4f585e" } + +[tabs] +active = { fg = "#343f44", bg = "#83c092", bold = true } +inactive = { fg = "#83c092", bg = "#3d484d" } + +[mode] + +normal_main = { fg = "#3d484d", bg = "#83c092", bold = true } +normal_alt = { fg = "#9DA9A0", bg = "#4f585e", bold = true } + +# Select mode +select_main = { fg = "#3d484d", bg = "#e67e80", bold = true } +select_alt = { fg = "#9DA9A0", bg = "#4f585e", bold = true } + +# Unset mode +unset_main = { fg = "#3d484d", bg = "#7393b3", bold = true } +unset_alt = { fg = "#9DA9A0", bg = "#4f585e", bold = true } [status] -overall = { fg = "gray" } +overall = { fg = "#9DA9A0" } sep_left = { open = "", close = "" } sep_right = { open = "", close = "" } +# Permissions +perm_sep = { fg = "#9DA9A0" } +perm_type = { fg = "#83c092" } +perm_read = { fg = "#dbbc7f" } +perm_write = { fg = "#e67e80" } +perm_exec = { fg = "#7393b3" } + +# Progress +progress_label = { bold = true } +progress_normal = { fg = "#7393b3", bg = "#232a2e" } +progress_error = { fg = "#e67e80", bg = "#232a2e" } + +[pick] +border = { fg = "#7393b3" } +active = { fg = "#d699b6", bold = true } +inactive = {} + +[input] +border = { fg = "#7393b3" } +title = {} +value = {} +selected = { reversed = true } + +[cmp] +border = { fg = "#7393b3" } + +[tasks] +border = { fg = "#7393b3" } +title = {} +hovered = { fg = "#d699b6", underline = true } [which] mask = { bg = "reset" } +cand = { fg = "#e67e80" } +rest = { fg = "#2d353b" } +desc = { fg = "#7393b3" } +separator = "  " +separator_style = { fg = "#83c092" } + +[help] +on = { fg = "#7393b3" } +run = { fg = "#d699b6" } +hovered = { reversed = true, bold = true } +footer = { fg = "#2d353b", bg = "#d3c6aa" } + +[spot] +border = { fg = "#7393b3" } +title = { fg = "#7393b3" } +tbl_col = { fg = "#7393b3" } +tbl_cell = { fg = "#dbbc7f", reversed = true } + +[notify] +title_info = { fg = "#83c092" } +title_warn = { fg = "#dbbc7f" } +title_error = { fg = "#e67e80" } + +[indicator] +current = { bg = '#2e383c' } + +[icon] +prepend_conds = [ + { if = "dir", text = "󰉋", fg = "#7393b3" }, # Directories +] + +[filetype] + +rules = [ + # Images + { mime = "image/*", fg = "#7393b3" }, + # Media + { mime = "{audio,video}/*", fg = "#d699b6" }, + # Archives + { mime = "application/{zip,rar,7z*,tar,gzip,xz,zstd,bzip*,lzma,compress,archive,cpio,arj,xar,ms-cab*}", fg = "#e67e80" }, + # Documents + { mime = "application/{pdf,doc,rtf}", fg = "#7393b3" }, + # Virtual file system + { mime = "vfs/{absent,stale}", fg = "#4f585e" }, + # Fallback + { url = "*/", fg = "#83c092" }, +] From a8fb8a7421390ccef7e18839e3b164f1e190b7c2 Mon Sep 17 00:00:00 2001 From: Tony Banh Date: Tue, 21 Apr 2026 23:25:13 -0700 Subject: [PATCH 06/28] sidekick: add keybindings to A and --- dot_config/nvim/lua/plugins/ai/sidekick.lua | 71 +++++++++++++++++---- 1 file changed, 58 insertions(+), 13 deletions(-) diff --git a/dot_config/nvim/lua/plugins/ai/sidekick.lua b/dot_config/nvim/lua/plugins/ai/sidekick.lua index c014df7..050e700 100644 --- a/dot_config/nvim/lua/plugins/ai/sidekick.lua +++ b/dot_config/nvim/lua/plugins/ai/sidekick.lua @@ -42,24 +42,69 @@ return { }, }, }, - -- Disable cli keybindings, only keeping nes keys = function() + local keymap_prefix = "A" return { + -- nes { "", LazyVim.cmp.map({ "ai_nes" }, ""), mode = { "n" }, expr = true }, + + -- cli { - "", - false, + "", + function() + require("sidekick.cli").toggle() + end, + desc = "Sidekick Toggle", + mode = { "n", "t", "i", "x" }, + }, + { keymap_prefix, "", desc = "+ai Sidekick cli", mode = { "n", "v" } }, + { + keymap_prefix .. "s", + function() + require("sidekick.cli").select() + end, + -- Or to select only installed tools: + -- require("sidekick.cli").select({ filter = { installed = true } }) + desc = "Select CLI", + }, + { + keymap_prefix .. "d", + function() + require("sidekick.cli").close() + end, + desc = "Detach a CLI Session", + }, + { + keymap_prefix .. "t", + function() + require("sidekick.cli").send({ msg = "{this}" }) + end, + mode = { "x", "n" }, + desc = "Send This", + }, + { + keymap_prefix .. "f", + function() + require("sidekick.cli").send({ msg = "{file}" }) + end, + desc = "Send File", + }, + { + keymap_prefix .. "v", + function() + require("sidekick.cli").send({ msg = "{selection}" }) + end, + mode = { "x" }, + desc = "Send Visual Selection", + }, + { + keymap_prefix .. "p", + function() + require("sidekick.cli").prompt() + end, + mode = { "n", "x" }, + desc = "Sidekick Select Prompt", }, } end, - -- keys = { - -- { - -- "", - -- function() - -- require("sidekick.cli").toggle() - -- end, - -- desc = "Sidekick Toggle", - -- mode = { "n", "t", "i", "x" }, - -- }, - -- }, } From a50d4a7884e76fd44e49af2824622d4c46530c72 Mon Sep 17 00:00:00 2001 From: Tony Banh Date: Wed, 22 Apr 2026 21:27:30 -0700 Subject: [PATCH 07/28] sidekick/opencode - update keymaps controlled by vim.g.ai_cli --- dot_config/nvim/lua/config/options.lua | 6 ++++++ dot_config/nvim/lua/plugins/ai/opencode.lua | 20 ++++++++++--------- dot_config/nvim/lua/plugins/ai/sidekick.lua | 18 +++++++++++------ .../nvim/lua/plugins/editor/which-key.lua | 4 ---- 4 files changed, 29 insertions(+), 19 deletions(-) diff --git a/dot_config/nvim/lua/config/options.lua b/dot_config/nvim/lua/config/options.lua index b8c964a..3d30958 100644 --- a/dot_config/nvim/lua/config/options.lua +++ b/dot_config/nvim/lua/config/options.lua @@ -13,6 +13,8 @@ vim.cmd("autocmd InsertLeave * set nu rnu") -- Minimal number of screen lines to keep above and below the cursor. vim.opt.scrolloff = 10 +vim.o.scrollback = 0 + -- Keep system clipboard separate from vim clipboard vim.opt.clipboard = "" @@ -52,6 +54,10 @@ vim.o.autoread = true -- Personal - controls floating terminal for various plugins. vim.g.floating_terminal = false +-- Controls which ai cli tool to use +---@type "sidekick"|"opencode" +vim.g.ai_cli = "sidekick" + -- Plugin/distro specific -- -- LazyVim: use ai suggestion in cmp, false shows inline suggestion diff --git a/dot_config/nvim/lua/plugins/ai/opencode.lua b/dot_config/nvim/lua/plugins/ai/opencode.lua index edf6515..8c75e4a 100644 --- a/dot_config/nvim/lua/plugins/ai/opencode.lua +++ b/dot_config/nvim/lua/plugins/ai/opencode.lua @@ -1,4 +1,5 @@ -local keymap_prefix = "a" +local keymap_prefix = vim.g.ai_cli == "opencode" and "a" or "A" +local toggle = vim.g.ai_cli == "opencode" and "" or "" return { "sudo-tee/opencode.nvim", @@ -47,11 +48,6 @@ return { ["oT"] = false, ["ost"] = { "timeline", desc = "Session timeline" }, -- Display timeline picker to navigate/undo/redo/fork messages - -- Mentions - ["@/"] = { "quick_chat", mode = { "n", "x" } }, - ["@v"] = { "paste_image" }, - ["@y"] = { "add_visual_selection", mode = { "v" } }, - -- Toggle ["ox"] = false, ["otx"] = { "swap_position", desc = "Toggle Opencode pane left/right" }, @@ -115,12 +111,18 @@ return { config = function(_, opts) require("opencode").setup(opts) - -- does not work when passed into keymap config - vim.keymap.set({ "n", "t", "i", "x" }, "", function() + -- does not work when passed into keymap config + vim.keymap.set({ "n", "t", "i", "x" }, toggle, function() require("opencode.api").toggle() end, { desc = "Opencode Toggle" }) - vim.keymap.set({ "n", "v" }, "@", "", { desc = "+ai mentions" }) + require("which-key").add({ + { + keymap_prefix, + group = "ai/opencode", + icon = { icon = " ", color = "green" }, + }, + }) vim.keymap.set({ "n", "v" }, keymap_prefix .. "c", "", { desc = "+configure models" }) vim.keymap.set({ "n", "v" }, keymap_prefix .. "d", "", { desc = "+diff" }) vim.keymap.set({ "n", "v" }, keymap_prefix .. "r", "", { desc = "+revert" }) diff --git a/dot_config/nvim/lua/plugins/ai/sidekick.lua b/dot_config/nvim/lua/plugins/ai/sidekick.lua index 050e700..a77412e 100644 --- a/dot_config/nvim/lua/plugins/ai/sidekick.lua +++ b/dot_config/nvim/lua/plugins/ai/sidekick.lua @@ -1,3 +1,6 @@ +local keymap_prefix = vim.g.ai_cli == "sidekick" and "a" or "A" +local toggle = vim.g.ai_cli == "sidekick" and "" or "" + return { "folke/sidekick.nvim", opts = { @@ -43,28 +46,31 @@ return { }, }, keys = function() - local keymap_prefix = "A" + require("which-key").add({ + { + keymap_prefix, + group = "ai/sidekick", + }, + }) + return { -- nes { "", LazyVim.cmp.map({ "ai_nes" }, ""), mode = { "n" }, expr = true }, -- cli { - "", + toggle, function() require("sidekick.cli").toggle() end, desc = "Sidekick Toggle", mode = { "n", "t", "i", "x" }, }, - { keymap_prefix, "", desc = "+ai Sidekick cli", mode = { "n", "v" } }, { keymap_prefix .. "s", function() - require("sidekick.cli").select() + require("sidekick.cli").select({ filter = { installed = true } }) end, - -- Or to select only installed tools: - -- require("sidekick.cli").select({ filter = { installed = true } }) desc = "Select CLI", }, { diff --git a/dot_config/nvim/lua/plugins/editor/which-key.lua b/dot_config/nvim/lua/plugins/editor/which-key.lua index f5e24dc..a09b92f 100644 --- a/dot_config/nvim/lua/plugins/editor/which-key.lua +++ b/dot_config/nvim/lua/plugins/editor/which-key.lua @@ -9,10 +9,6 @@ return { local wk = require("which-key") wk.setup(opts) wk.add({ - { - "a", - group = "ai", - }, { "n", group = "Notes/New...", From 63ccef1edadc398f92b4886cbc6def86bc4ba61c Mon Sep 17 00:00:00 2001 From: Tony Banh Date: Wed, 22 Apr 2026 21:27:47 -0700 Subject: [PATCH 08/28] sidekick: fix opencode cli rendering after terminal hide/show --- dot_config/nvim/lua/plugins/ai/sidekick.lua | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/dot_config/nvim/lua/plugins/ai/sidekick.lua b/dot_config/nvim/lua/plugins/ai/sidekick.lua index a77412e..87c194f 100644 --- a/dot_config/nvim/lua/plugins/ai/sidekick.lua +++ b/dot_config/nvim/lua/plugins/ai/sidekick.lua @@ -17,6 +17,24 @@ return { wo = { scrolloff = 0, -- prevent global scrolloff from shifting terminal view on toggle }, + -- Force opencode to redraw when sidekick re-opens the terminal window. + -- Without this, the window-pty association is lost during hide() and the + -- TUI never receives SIGWINCH, so stale content from the previous render + -- stays visible until the user manually resizes the split. + config = function(terminal) + local orig = terminal.open_win + terminal.open_win = function(self) + orig(self) + vim.defer_fn(function() + if self:win_valid() and self:is_running() then + local w = vim.api.nvim_win_get_width(self.win) + local h = vim.api.nvim_win_get_height(self.win) + pcall(vim.fn.jobresize, self.job, w - 1, h) + pcall(vim.fn.jobresize, self.job, w, h) + end + end, 30) + end + end, layout = vim.g.floating_terminal and "float" or "right", ---@type "float"|"left"|"bottom"|"top"|"right" float = { width = 0.6, @@ -25,7 +43,7 @@ return { -- Options used when layout is "left"|"bottom"|"top"|"right" ---@type vim.api.keyset.win_config split = { - width = 0, -- set to 0 for default split width + width = 0.5, -- set to 0 for default split width height = 0, -- set to 0 for default split height }, }, From b29669f5869b57e80186c2626abd71ee49bb6929 Mon Sep 17 00:00:00 2001 From: Tony Banh Date: Wed, 22 Apr 2026 21:28:37 -0700 Subject: [PATCH 09/28] fix(temp): refactoring.nvim clear debug, also use latest LazyVim which fixes refactoring.nvim dep --- dot_config/nvim/lua/config/lazy.lua | 2 +- .../nvim/lua/plugins/editor/refactoring.lua | 44 +++++++++++++++---- 2 files changed, 37 insertions(+), 9 deletions(-) diff --git a/dot_config/nvim/lua/config/lazy.lua b/dot_config/nvim/lua/config/lazy.lua index 448d374..f59ae29 100644 --- a/dot_config/nvim/lua/config/lazy.lua +++ b/dot_config/nvim/lua/config/lazy.lua @@ -17,7 +17,7 @@ vim.opt.rtp:prepend(lazypath) require("lazy").setup({ spec = { -- add LazyVim and import its plugins - { "LazyVim/LazyVim", import = "lazyvim.plugins" }, + { "LazyVim/LazyVim", import = "lazyvim.plugins", version = false }, -- import/override with your plugins { import = "plugins" }, }, diff --git a/dot_config/nvim/lua/plugins/editor/refactoring.lua b/dot_config/nvim/lua/plugins/editor/refactoring.lua index 779a21e..cb9b8ff 100644 --- a/dot_config/nvim/lua/plugins/editor/refactoring.lua +++ b/dot_config/nvim/lua/plugins/editor/refactoring.lua @@ -1,18 +1,46 @@ -local js_ts_print_var_statements = { - 'console.log("[LOGS] %s → ", %s);', -} +local function js_ts_print_var(opts) + local name = opts.identifier_str:gsub("╎", "") + return string.format('console.log("[LOGS] %s → ", %s);', name, opts.identifier) +end return { "ThePrimeagen/refactoring.nvim", dependencies = { "lewis6991/async.nvim", }, + -- https://github.com/ThePrimeagen/refactoring.nvim/blob/master/lua/refactoring/config.lua + keys = { + -- LazyVim's default binding feeds `g@ag`, where `ag` is mini.ai's custom + -- "around buffer" textobject. It can fail when mini.ai hasn't finished + -- registering. Here we bypass the operator-pending dance: call cleanup() + -- to set operatorfunc + internal state, set the `[` / `]` marks to the + -- whole buffer, then invoke the operatorfunc directly. + { + "rc", + function() + require("refactoring.debug").cleanup({ restore_view = true }) + local buf = vim.api.nvim_get_current_buf() + local last_line = vim.api.nvim_buf_line_count(buf) + local last_line_text = vim.api.nvim_buf_get_lines(buf, last_line - 1, last_line, true)[1] or "" + local last_col = math.max(0, #last_line_text - 1) + vim.api.nvim_buf_set_mark(buf, "[", 1, 0, {}) + vim.api.nvim_buf_set_mark(buf, "]", last_line, last_col, {}) + require("refactoring.debug").debug_operatorfunc("line") + end, + desc = "Debug Cleanup (whole buffer)", + }, + }, opts = { - print_var_statements = { - javascript = js_ts_print_var_statements, - javascriptreact = js_ts_print_var_statements, - typescript = js_ts_print_var_statements, - typescriptreact = js_ts_print_var_statements, + debug = { + print_var = { + code_generation = { + print_var = { + javascript = js_ts_print_var, + typescript = js_ts_print_var, + tsx = js_ts_print_var, + }, + }, + }, }, }, } From caaad2787c06e7c7ef4884fdb35366aa47f6cc9a Mon Sep 17 00:00:00 2001 From: Tony Banh Date: Thu, 23 Apr 2026 02:19:34 -0700 Subject: [PATCH 10/28] fix: refactoring.nvim's print_var and print_loc for js/ts/tsx --- .../nvim/lua/plugins/editor/refactoring.lua | 45 ++++++++++++++----- 1 file changed, 34 insertions(+), 11 deletions(-) diff --git a/dot_config/nvim/lua/plugins/editor/refactoring.lua b/dot_config/nvim/lua/plugins/editor/refactoring.lua index cb9b8ff..4855e89 100644 --- a/dot_config/nvim/lua/plugins/editor/refactoring.lua +++ b/dot_config/nvim/lua/plugins/editor/refactoring.lua @@ -1,14 +1,39 @@ -local function js_ts_print_var(opts) - local name = opts.identifier_str:gsub("╎", "") - return string.format('console.log("[LOGS] %s → ", %s);', name, opts.identifier) +---@param opts refactor.print_var.code_generation.Opts +local js_ts_print_var = function(opts) + return ([[console.log("[LOGS] %s %s %s → ", %s)]]):format( + opts.debug_path:gsub('"', '\\"'), + opts.identifier_str:gsub('"', '\\"'), + opts.count, + opts.identifier + ) end +local print_var_code_generation = { + print_var = { + javascript = js_ts_print_var, + typescript = js_ts_print_var, + tsx = js_ts_print_var, + }, +} + +---@param opts refactor.print_loc.code_generation.Opts +local js_ts_print_loc = function(opts) + return ([[console.log("[LOGS] %s %s -------------")]]):format(opts.debug_path, opts.count) +end + +local print_loc_code_generation = { + print_loc = { + javascript = js_ts_print_loc, + typescript = js_ts_print_loc, + tsx = js_ts_print_loc, + }, +} + return { "ThePrimeagen/refactoring.nvim", dependencies = { "lewis6991/async.nvim", }, - -- https://github.com/ThePrimeagen/refactoring.nvim/blob/master/lua/refactoring/config.lua keys = { -- LazyVim's default binding feeds `g@ag`, where `ag` is mini.ai's custom -- "around buffer" textobject. It can fail when mini.ai hasn't finished @@ -31,15 +56,13 @@ return { }, }, opts = { + -- https://github.com/ThePrimeagen/refactoring.nvim/blob/master/lua/refactoring/config.lua debug = { print_var = { - code_generation = { - print_var = { - javascript = js_ts_print_var, - typescript = js_ts_print_var, - tsx = js_ts_print_var, - }, - }, + code_generation = print_var_code_generation, + }, + print_loc = { + code_generation = print_loc_code_generation, }, }, }, From 3f98a98e338c39e0ad2bb25158359e3947f909f7 Mon Sep 17 00:00:00 2001 From: Tony Banh Date: Thu, 23 Apr 2026 21:18:05 -0700 Subject: [PATCH 11/28] sidekick: sort keybindings --- dot_config/nvim/lua/plugins/ai/sidekick.lua | 48 ++++++++++++--------- 1 file changed, 28 insertions(+), 20 deletions(-) diff --git a/dot_config/nvim/lua/plugins/ai/sidekick.lua b/dot_config/nvim/lua/plugins/ai/sidekick.lua index 87c194f..de92124 100644 --- a/dot_config/nvim/lua/plugins/ai/sidekick.lua +++ b/dot_config/nvim/lua/plugins/ai/sidekick.lua @@ -84,13 +84,6 @@ return { desc = "Sidekick Toggle", mode = { "n", "t", "i", "x" }, }, - { - keymap_prefix .. "s", - function() - require("sidekick.cli").select({ filter = { installed = true } }) - end, - desc = "Select CLI", - }, { keymap_prefix .. "d", function() @@ -99,28 +92,20 @@ return { desc = "Detach a CLI Session", }, { - keymap_prefix .. "t", + keymap_prefix .. "f", function() - require("sidekick.cli").send({ msg = "{this}" }) + require("sidekick.cli").focus() end, - mode = { "x", "n" }, - desc = "Send This", + desc = "Sidekick Focus", + mode = { "n", "t", "i", "x" }, }, { - keymap_prefix .. "f", + keymap_prefix .. "g", function() require("sidekick.cli").send({ msg = "{file}" }) end, desc = "Send File", }, - { - keymap_prefix .. "v", - function() - require("sidekick.cli").send({ msg = "{selection}" }) - end, - mode = { "x" }, - desc = "Send Visual Selection", - }, { keymap_prefix .. "p", function() @@ -129,6 +114,29 @@ return { mode = { "n", "x" }, desc = "Sidekick Select Prompt", }, + { + keymap_prefix .. "s", + function() + require("sidekick.cli").select({ filter = { installed = true } }) + end, + desc = "Select CLI", + }, + { + keymap_prefix .. "t", + function() + require("sidekick.cli").send({ msg = "{this}" }) + end, + mode = { "x", "n" }, + desc = "Send This", + }, + { + keymap_prefix .. "v", + function() + require("sidekick.cli").send({ msg = "{selection}" }) + end, + mode = { "x" }, + desc = "Send Visual Selection", + }, } end, } From 8aad9561e520d007cc4b2345ee8a4a13df10f432 Mon Sep 17 00:00:00 2001 From: Tony Banh Date: Thu, 23 Apr 2026 21:19:37 -0700 Subject: [PATCH 12/28] use builtin vim.lsp.codelens, delete symbol-usage.nvim --- dot_config/nvim/lua/config/options.lua | 3 + .../plugins/ui/colorschemes/everforest.lua | 1 + .../nvim/lua/plugins/ui/symbol-usage.lua | 71 ------------------- 3 files changed, 4 insertions(+), 71 deletions(-) delete mode 100644 dot_config/nvim/lua/plugins/ui/symbol-usage.lua diff --git a/dot_config/nvim/lua/config/options.lua b/dot_config/nvim/lua/config/options.lua index 3d30958..9a403a6 100644 --- a/dot_config/nvim/lua/config/options.lua +++ b/dot_config/nvim/lua/config/options.lua @@ -51,6 +51,9 @@ vim.opt.shadafile = shadafile vim.o.autoread = true +-- LSP +vim.lsp.codelens.enable() + -- Personal - controls floating terminal for various plugins. vim.g.floating_terminal = false diff --git a/dot_config/nvim/lua/plugins/ui/colorschemes/everforest.lua b/dot_config/nvim/lua/plugins/ui/colorschemes/everforest.lua index 2affe01..42f634d 100644 --- a/dot_config/nvim/lua/plugins/ui/colorschemes/everforest.lua +++ b/dot_config/nvim/lua/plugins/ui/colorschemes/everforest.lua @@ -81,6 +81,7 @@ return { LspReferenceText = { bg = palette.bg1 }, LspReferenceRead = { link = "LspReferenceText" }, + LspCodeLens = { fg = palette.grey1, bg = palette.bg1, italic = true }, RenderMarkdownH1Bg = { link = "RenderMarkdownHeadingBG" }, RenderMarkdownH2Bg = { link = "RenderMarkdownHeadingBG" }, diff --git a/dot_config/nvim/lua/plugins/ui/symbol-usage.lua b/dot_config/nvim/lua/plugins/ui/symbol-usage.lua deleted file mode 100644 index 0d16d32..0000000 --- a/dot_config/nvim/lua/plugins/ui/symbol-usage.lua +++ /dev/null @@ -1,71 +0,0 @@ -local SymbolKind = vim.lsp.protocol.SymbolKind - -return { - "Wansmer/symbol-usage.nvim", - event = "LspAttach", -- need run before LspAttach if you use nvim 0.9. On 0.10 use 'LspAttach' - config = function() - local function h(name) - return vim.api.nvim_get_hl(0, { name = name }) - end - - -- hl-groups can have any name - vim.api.nvim_set_hl(0, "SymbolUsageRounding", { fg = h("CursorLine").bg, italic = true }) - vim.api.nvim_set_hl(0, "SymbolUsageContent", { bg = h("CursorLine").bg, fg = h("Comment").fg, italic = true }) - vim.api.nvim_set_hl(0, "SymbolUsageRef", { fg = h("Function").fg, bg = h("CursorLine").bg, italic = true }) - vim.api.nvim_set_hl(0, "SymbolUsageDef", { fg = h("Type").fg, bg = h("CursorLine").bg, italic = true }) - vim.api.nvim_set_hl(0, "SymbolUsageImpl", { fg = h("@keyword").fg, bg = h("CursorLine").bg, italic = true }) - - local function text_format(symbol) - local res = {} - - -- local round_start = { "", "SymbolUsageRounding" } - -- local round_end = { "", "SymbolUsageRounding" } - - -- Indicator that shows if there are any other symbols in the same line - local stacked_functions_content = symbol.stacked_count > 0 and ("+%s"):format(symbol.stacked_count) or "" - - if symbol.references then - local usage = symbol.references <= 1 and "usage" or "usages" - local num = symbol.references == 0 and "no" or symbol.references - table.insert(res, { "󰌹 ", "SymbolUsageRef" }) - table.insert(res, { ("%s %s"):format(num, usage), "SymbolUsageContent" }) - end - - if symbol.definition then - if #res > 0 then - table.insert(res, { " ", "NonText" }) - end - table.insert(res, { "󰳽 ", "SymbolUsageDef" }) - table.insert(res, { symbol.definition .. " defs", "SymbolUsageContent" }) - end - - if symbol.implementation then - if #res > 0 then - table.insert(res, { " ", "NonText" }) - end - table.insert(res, { "󰡱 ", "SymbolUsageImpl" }) - table.insert(res, { symbol.implementation .. " impls", "SymbolUsageContent" }) - end - - if stacked_functions_content ~= "" then - if #res > 0 then - table.insert(res, { " ", "NonText" }) - end - table.insert(res, { " ", "SymbolUsageImpl" }) - table.insert(res, { stacked_functions_content, "SymbolUsageContent" }) - end - - return res - end - - ---@diagnostic disable: missing-fields - require("symbol-usage").setup({ - text_format = text_format, - disable = { - filetypes = { - "markdown", - }, - }, - }) - end, -} From d43df4341aa2299c6b7f6a67264aa67074beafc7 Mon Sep 17 00:00:00 2001 From: Tony Banh Date: Thu, 23 Apr 2026 21:24:57 -0700 Subject: [PATCH 13/28] tmux: set tmux-256color to properly render italics and gui color --- dot_config/nvim/lua/plugins/editor/stay-centered.lua | 1 + dot_config/nvim/lua/plugins/ui/colorschemes/everforest.lua | 2 +- dot_config/tmux/tmux.conf | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/dot_config/nvim/lua/plugins/editor/stay-centered.lua b/dot_config/nvim/lua/plugins/editor/stay-centered.lua index d5f7385..940ae7e 100644 --- a/dot_config/nvim/lua/plugins/editor/stay-centered.lua +++ b/dot_config/nvim/lua/plugins/editor/stay-centered.lua @@ -1,3 +1,4 @@ +-- TODO: remove plugin once neovim release has `scrolloffpad` return { "arnamak/stay-centered.nvim", config = function() diff --git a/dot_config/nvim/lua/plugins/ui/colorschemes/everforest.lua b/dot_config/nvim/lua/plugins/ui/colorschemes/everforest.lua index 42f634d..d40ec98 100644 --- a/dot_config/nvim/lua/plugins/ui/colorschemes/everforest.lua +++ b/dot_config/nvim/lua/plugins/ui/colorschemes/everforest.lua @@ -13,7 +13,7 @@ return { ---components be transparent (e.g. status line background) transparent_background_level = 2, ---Whether italics should be used for keywords and more. - italics = true, + italics = false, ---Disable italic fonts for comments. Comments are in italics by default, set ---this to `true` to make them _not_ italic! disable_italic_comments = false, diff --git a/dot_config/tmux/tmux.conf b/dot_config/tmux/tmux.conf index 3766ff0..4fccf5a 100644 --- a/dot_config/tmux/tmux.conf +++ b/dot_config/tmux/tmux.conf @@ -26,7 +26,7 @@ setw -g mouse on set -g set-clipboard on -# set-option -g default-terminal "screen-256color" +set -g default-terminal "tmux-256color" set -as terminal-features ',*:RGB' bind-key : command-prompt From 044ab569395d0836869995f55fbfb5a5cee64099 Mon Sep 17 00:00:00 2001 From: Tony Banh Date: Thu, 23 Apr 2026 21:30:57 -0700 Subject: [PATCH 14/28] remove opencode.nvim --- dot_config/nvim/lua/config/options.lua | 4 - dot_config/nvim/lua/plugins/ai/opencode.lua | 132 ------------------ dot_config/nvim/lua/plugins/ai/sidekick.lua | 4 +- .../nvim/lua/plugins/editor/autopairs.lua | 1 - .../lua/plugins/editor/nvim-treesitter.lua | 1 - dot_config/nvim/lua/plugins/ui/lualine.lua | 2 - dot_config/nvim/lua/plugins/ui/markdown.lua | 2 +- .../nvim/lua/plugins/ui/nvim-colorizer.lua | 2 - 8 files changed, 3 insertions(+), 145 deletions(-) delete mode 100644 dot_config/nvim/lua/plugins/ai/opencode.lua diff --git a/dot_config/nvim/lua/config/options.lua b/dot_config/nvim/lua/config/options.lua index 9a403a6..09a1ac2 100644 --- a/dot_config/nvim/lua/config/options.lua +++ b/dot_config/nvim/lua/config/options.lua @@ -57,10 +57,6 @@ vim.lsp.codelens.enable() -- Personal - controls floating terminal for various plugins. vim.g.floating_terminal = false --- Controls which ai cli tool to use ----@type "sidekick"|"opencode" -vim.g.ai_cli = "sidekick" - -- Plugin/distro specific -- -- LazyVim: use ai suggestion in cmp, false shows inline suggestion diff --git a/dot_config/nvim/lua/plugins/ai/opencode.lua b/dot_config/nvim/lua/plugins/ai/opencode.lua deleted file mode 100644 index 8c75e4a..0000000 --- a/dot_config/nvim/lua/plugins/ai/opencode.lua +++ /dev/null @@ -1,132 +0,0 @@ -local keymap_prefix = vim.g.ai_cli == "opencode" and "a" or "A" -local toggle = vim.g.ai_cli == "opencode" and "" or "" - -return { - "sudo-tee/opencode.nvim", - dependencies = { - "nvim-lua/plenary.nvim", - "saghen/blink.cmp", - "folke/snacks.nvim", - { "MeanderingProgrammer/render-markdown.nvim", optional = true }, - { "OXY2DEV/markview.nvim", optional = true }, - }, - opts = { - keymap_prefix = keymap_prefix, -- Default keymap prefix for global keymaps change to your preferred prefix and it will be applied to all keymaps starting with o - keymap = { - editor = { - ["oq"] = false, - - ["og"] = false, - ["oa"] = { "toggle" }, -- Open opencode. Close if opened - - ["ot"] = false, - ["of"] = { "toggle_focus" }, -- Toggle focus between opencode and last window - - -- Diff - ["od"] = false, - ["odd"] = { "diff_open", desc = "Open diff view" }, - ["o]"] = false, - ["od]"] = { "diff_next", desc = "Next diff" }, - ["o["] = false, - ["od["] = { "diff_prev", desc = "Previous diff" }, - ["oc"] = false, - ["odq"] = { "diff_close", desc = "Close diff view" }, - - -- Configure providers & variants - ["op"] = false, - ["ocp"] = { "configure_provider", desc = "Configure provider" }, - ["oV"] = false, - ["ocv"] = { "configure_variant", desc = "Configure variant" }, - - -- Sessions - ["oI"] = false, - ["osn"] = { "open_input_new_session", desc = "Open input (new session)" }, - ["os"] = false, - ["oss"] = { "select_session", desc = "Select and load a session" }, - ["oR"] = false, - ["osr"] = { "rename_session", desc = "Rename current session" }, - ["oT"] = false, - ["ost"] = { "timeline", desc = "Session timeline" }, -- Display timeline picker to navigate/undo/redo/fork messages - - -- Toggle - ["ox"] = false, - ["otx"] = { "swap_position", desc = "Toggle Opencode pane left/right" }, - ["oz"] = false, - ["otz"] = { "toggle_zoom", desc = "Toggle Zoom in/out on the Opencode windows" }, - }, - input_window = { - ["~"] = false, - [""] = false, - [""] = false, - [""] = false, - [""] = false, - [""] = false, - - ["q"] = { "close", mode = { "n" } }, -- Close UI windows - [""] = { "close" }, - [""] = { "cancel" }, - - ["@f"] = { "mention_file", mode = { "n", "i" } }, -- Pick a file and add to context. - ["@v"] = { "paste_image", mode = { "n", "i" }, desc = "Paste image from clipboard" }, - - [""] = { "switch_mode", mode = { "n", "v", "i" } }, -- build/plan - [""] = { "cycle_variant", mode = { "n", "v", "i" } }, -- model variants - [""] = { "next_prompt_history", mode = { "n", "i" } }, -- Navigate to next prompt in history - [""] = { "prev_prompt_history", mode = { "n", "i" } }, -- Navigate to previous prompt in history - [""] = { "submit_input_prompt", mode = { "n", "i" } }, -- Submit prompt (normal mode and insert mode) - }, - output_window = { - ["q"] = { "close" }, -- Close UI windows - [""] = { "close" }, - [""] = { "cancel" }, - - [""] = { "switch_mode", mode = { "n", "v" } }, - [""] = { "cycle_variant", mode = { "n", "v" } }, - }, - session_picker = { - delete_session = { "" }, -- Delete selected session in the session picker - }, - history_picker = { - delete_entry = { "", mode = { "i", "n" } }, -- Delete selected entry in the history picker - clear_all = { "", mode = { "i", "n" } }, -- Clear all entries in the history picker - }, - }, - ui = { - window_width = 0.50, - input = { - text = { - wrap = false, - }, - }, - output = { - filetype = "markdown", -- Filetype assigned to the output buffer (default: 'opencode_output') - }, - picker = { - snacks_layout = { - preset = "select", - }, - }, - }, - }, - config = function(_, opts) - require("opencode").setup(opts) - - -- does not work when passed into keymap config - vim.keymap.set({ "n", "t", "i", "x" }, toggle, function() - require("opencode.api").toggle() - end, { desc = "Opencode Toggle" }) - - require("which-key").add({ - { - keymap_prefix, - group = "ai/opencode", - icon = { icon = " ", color = "green" }, - }, - }) - vim.keymap.set({ "n", "v" }, keymap_prefix .. "c", "", { desc = "+configure models" }) - vim.keymap.set({ "n", "v" }, keymap_prefix .. "d", "", { desc = "+diff" }) - vim.keymap.set({ "n", "v" }, keymap_prefix .. "r", "", { desc = "+revert" }) - vim.keymap.set({ "n", "v" }, keymap_prefix .. "s", "", { desc = "+session management" }) - vim.keymap.set({ "n", "v" }, keymap_prefix .. "t", "", { desc = "+toggle" }) - end, -} diff --git a/dot_config/nvim/lua/plugins/ai/sidekick.lua b/dot_config/nvim/lua/plugins/ai/sidekick.lua index de92124..dd103be 100644 --- a/dot_config/nvim/lua/plugins/ai/sidekick.lua +++ b/dot_config/nvim/lua/plugins/ai/sidekick.lua @@ -1,5 +1,5 @@ -local keymap_prefix = vim.g.ai_cli == "sidekick" and "a" or "A" -local toggle = vim.g.ai_cli == "sidekick" and "" or "" +local keymap_prefix = "a" +local toggle = "" return { "folke/sidekick.nvim", diff --git a/dot_config/nvim/lua/plugins/editor/autopairs.lua b/dot_config/nvim/lua/plugins/editor/autopairs.lua index 9e0947a..0f1996f 100644 --- a/dot_config/nvim/lua/plugins/editor/autopairs.lua +++ b/dot_config/nvim/lua/plugins/editor/autopairs.lua @@ -12,7 +12,6 @@ return { "codecompanion", "grug-far", "markdown", - "opencode", "snacks_input", "snacks_picker_input", "spectre_panel", diff --git a/dot_config/nvim/lua/plugins/editor/nvim-treesitter.lua b/dot_config/nvim/lua/plugins/editor/nvim-treesitter.lua index 4e1960c..6190d4a 100644 --- a/dot_config/nvim/lua/plugins/editor/nvim-treesitter.lua +++ b/dot_config/nvim/lua/plugins/editor/nvim-treesitter.lua @@ -3,7 +3,6 @@ return { "nvim-treesitter/nvim-treesitter", opts = {}, config = function(_, opts) - vim.treesitter.language.register("markdown", "opencode") vim.filetype.add({ extension = { lyaml = "yaml", git = "git", keymap = "dts" }, }) diff --git a/dot_config/nvim/lua/plugins/ui/lualine.lua b/dot_config/nvim/lua/plugins/ui/lualine.lua index f197c52..8aa05fb 100644 --- a/dot_config/nvim/lua/plugins/ui/lualine.lua +++ b/dot_config/nvim/lua/plugins/ui/lualine.lua @@ -12,8 +12,6 @@ local disabled_filetypes = { "dap-repl", "leetcode.nvim", "sidekick_terminal", - "opencode", - "opencode_output", "codecompanion", } diff --git a/dot_config/nvim/lua/plugins/ui/markdown.lua b/dot_config/nvim/lua/plugins/ui/markdown.lua index 72f686f..b681f12 100644 --- a/dot_config/nvim/lua/plugins/ui/markdown.lua +++ b/dot_config/nvim/lua/plugins/ui/markdown.lua @@ -1,4 +1,4 @@ -local ft = { "md", "markdown", "opencode_output", "codecompanion" } +local ft = { "md", "markdown" } return { -- visual keybinds for markdown, C-b for bold, C-k for link, etc diff --git a/dot_config/nvim/lua/plugins/ui/nvim-colorizer.lua b/dot_config/nvim/lua/plugins/ui/nvim-colorizer.lua index 6b27ec7..22a519a 100644 --- a/dot_config/nvim/lua/plugins/ui/nvim-colorizer.lua +++ b/dot_config/nvim/lua/plugins/ui/nvim-colorizer.lua @@ -6,8 +6,6 @@ return { "*", "!grug-far", "!lazy", - "!opencode", - "!opencode_output", "!sidekick_terminal", "!snacks_input", "!snacks_picker_input", From f36eacedf74229436e0b070de5def874a06dc626 Mon Sep 17 00:00:00 2001 From: Tony Banh Date: Sat, 25 Apr 2026 00:10:03 -0700 Subject: [PATCH 15/28] vtsls: add removeUUnused code action --- dot_config/nvim/lua/plugins/mason/lsp.lua | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/dot_config/nvim/lua/plugins/mason/lsp.lua b/dot_config/nvim/lua/plugins/mason/lsp.lua index 77014fd..67db81c 100644 --- a/dot_config/nvim/lua/plugins/mason/lsp.lua +++ b/dot_config/nvim/lua/plugins/mason/lsp.lua @@ -116,6 +116,13 @@ return { servers = { vtsls = { enabled = ts_lsp == "vtsls", + keys = { + { + "cu", + LazyVim.lsp.action["source.removeUnused.ts"], + desc = "Remove unused", + }, + }, }, }, }, From 625015809bee02fdc4de0e283fc052d01b723d8c Mon Sep 17 00:00:00 2001 From: Tony Banh Date: Sat, 25 Apr 2026 00:10:24 -0700 Subject: [PATCH 16/28] refactoring: revert to older commit and use previous configuration --- dot_config/nvim/lazyvim.json | 1 - dot_config/nvim/lua/config/lazy.lua | 2 +- .../nvim/lua/plugins/editor/refactoring.lua | 188 +++++++++++++----- 3 files changed, 140 insertions(+), 51 deletions(-) diff --git a/dot_config/nvim/lazyvim.json b/dot_config/nvim/lazyvim.json index 79c25b2..986a44c 100644 --- a/dot_config/nvim/lazyvim.json +++ b/dot_config/nvim/lazyvim.json @@ -9,7 +9,6 @@ "lazyvim.plugins.extras.dap.nlua", "lazyvim.plugins.extras.editor.dial", "lazyvim.plugins.extras.editor.outline", - "lazyvim.plugins.extras.editor.refactoring", "lazyvim.plugins.extras.formatting.prettier", "lazyvim.plugins.extras.lang.astro", "lazyvim.plugins.extras.lang.clangd", diff --git a/dot_config/nvim/lua/config/lazy.lua b/dot_config/nvim/lua/config/lazy.lua index f59ae29..448d374 100644 --- a/dot_config/nvim/lua/config/lazy.lua +++ b/dot_config/nvim/lua/config/lazy.lua @@ -17,7 +17,7 @@ vim.opt.rtp:prepend(lazypath) require("lazy").setup({ spec = { -- add LazyVim and import its plugins - { "LazyVim/LazyVim", import = "lazyvim.plugins", version = false }, + { "LazyVim/LazyVim", import = "lazyvim.plugins" }, -- import/override with your plugins { import = "plugins" }, }, diff --git a/dot_config/nvim/lua/plugins/editor/refactoring.lua b/dot_config/nvim/lua/plugins/editor/refactoring.lua index 4855e89..d9fb533 100644 --- a/dot_config/nvim/lua/plugins/editor/refactoring.lua +++ b/dot_config/nvim/lua/plugins/editor/refactoring.lua @@ -1,69 +1,159 @@ ----@param opts refactor.print_var.code_generation.Opts -local js_ts_print_var = function(opts) - return ([[console.log("[LOGS] %s %s %s → ", %s)]]):format( - opts.debug_path:gsub('"', '\\"'), - opts.identifier_str:gsub('"', '\\"'), - opts.count, - opts.identifier - ) -end - -local print_var_code_generation = { - print_var = { - javascript = js_ts_print_var, - typescript = js_ts_print_var, - tsx = js_ts_print_var, - }, -} +local pick = function() + local refactoring = require("refactoring") + if LazyVim.pick.picker.name == "telescope" then + return require("telescope").extensions.refactoring.refactors() + elseif LazyVim.pick.picker.name == "fzf" then + local fzf_lua = require("fzf-lua") + local results = refactoring.get_refactors() ----@param opts refactor.print_loc.code_generation.Opts -local js_ts_print_loc = function(opts) - return ([[console.log("[LOGS] %s %s -------------")]]):format(opts.debug_path, opts.count) + local opts = { + fzf_opts = {}, + fzf_colors = true, + actions = { + ["default"] = function(selected) + refactoring.refactor(selected[1]) + end, + }, + } + fzf_lua.fzf_exec(results, opts) + else + refactoring.select_refactor() + end end -local print_loc_code_generation = { - print_loc = { - javascript = js_ts_print_loc, - typescript = js_ts_print_loc, - tsx = js_ts_print_loc, - }, +local js_ts_print_var_statements = { + 'console.log("[LOGS] %s → ", %s);', } return { "ThePrimeagen/refactoring.nvim", + commit = "6784b54587e6d8a6b9ea199318512170ffb9e418", + event = { "BufReadPre", "BufNewFile" }, dependencies = { - "lewis6991/async.nvim", + "nvim-lua/plenary.nvim", + "nvim-treesitter/nvim-treesitter", }, keys = { - -- LazyVim's default binding feeds `g@ag`, where `ag` is mini.ai's custom - -- "around buffer" textobject. It can fail when mini.ai hasn't finished - -- registering. Here we bypass the operator-pending dance: call cleanup() - -- to set operatorfunc + internal state, set the `[` / `]` marks to the - -- whole buffer, then invoke the operatorfunc directly. + { "r", "", desc = "+refactor", mode = { "n", "x" } }, + { + "rs", + pick, + mode = { "n", "x" }, + desc = "Refactor", + }, + { + "ri", + function() + return require("refactoring").refactor("Inline Variable") + end, + mode = { "n", "x" }, + desc = "Inline Variable", + expr = true, + }, + { + "rb", + function() + return require("refactoring").refactor("Extract Block") + end, + mode = { "n", "x" }, + desc = "Extract Block", + expr = true, + }, + { + "rf", + function() + return require("refactoring").refactor("Extract Block To File") + end, + mode = { "n", "x" }, + desc = "Extract Block To File", + expr = true, + }, + { + "rP", + function() + require("refactoring").debug.printf({ below = false }) + end, + desc = "Debug Print", + }, + { + "rp", + function() + require("refactoring").debug.print_var({ normal = true }) + end, + mode = { "n", "x" }, + desc = "Debug Print Variable", + }, { "rc", function() - require("refactoring.debug").cleanup({ restore_view = true }) - local buf = vim.api.nvim_get_current_buf() - local last_line = vim.api.nvim_buf_line_count(buf) - local last_line_text = vim.api.nvim_buf_get_lines(buf, last_line - 1, last_line, true)[1] or "" - local last_col = math.max(0, #last_line_text - 1) - vim.api.nvim_buf_set_mark(buf, "[", 1, 0, {}) - vim.api.nvim_buf_set_mark(buf, "]", last_line, last_col, {}) - require("refactoring.debug").debug_operatorfunc("line") + require("refactoring").debug.cleanup({}) + end, + desc = "Debug Cleanup", + }, + { + "rf", + function() + return require("refactoring").refactor("Extract Function") + end, + mode = { "n", "x" }, + desc = "Extract Function", + expr = true, + }, + { + "rF", + function() + return require("refactoring").refactor("Extract Function To File") + end, + mode = { "n", "x" }, + desc = "Extract Function To File", + expr = true, + }, + { + "rx", + function() + return require("refactoring").refactor("Extract Variable") + end, + mode = { "n", "x" }, + desc = "Extract Variable", + expr = true, + }, + { + "rp", + function() + require("refactoring").debug.print_var({}) end, - desc = "Debug Cleanup (whole buffer)", + mode = { "n", "x" }, + desc = "Debug Print Variable", }, }, opts = { - -- https://github.com/ThePrimeagen/refactoring.nvim/blob/master/lua/refactoring/config.lua - debug = { - print_var = { - code_generation = print_var_code_generation, - }, - print_loc = { - code_generation = print_loc_code_generation, - }, + prompt_func_return_type = { + go = false, + java = false, + cpp = false, + c = false, + h = false, + hpp = false, + cxx = false, + }, + prompt_func_param_type = { + go = false, + java = false, + cpp = false, + c = false, + h = false, + hpp = false, + cxx = false, + }, + printf_statements = {}, + print_var_statements = { + + javascript = js_ts_print_var_statements, + javascriptreact = js_ts_print_var_statements, + typescript = js_ts_print_var_statements, + typescriptreact = js_ts_print_var_statements, }, + show_success_message = true, -- shows a message with information about the refactor on success + -- i.e. [Refactor] Inlined 3 variable occurrences }, } From 37b1c7f9504ee42dda503fa71e1aded3cfdafc84 Mon Sep 17 00:00:00 2001 From: Tony Banh Date: Sat, 25 Apr 2026 00:11:03 -0700 Subject: [PATCH 17/28] misc --- dot_config/opencode/opencode.jsonc | 1 + 1 file changed, 1 insertion(+) diff --git a/dot_config/opencode/opencode.jsonc b/dot_config/opencode/opencode.jsonc index a7faf05..3cbf768 100644 --- a/dot_config/opencode/opencode.jsonc +++ b/dot_config/opencode/opencode.jsonc @@ -10,6 +10,7 @@ "~/.config/opencode/**": "allow", "~/obsidian-vault/**": "allow", "~/.claude/agents/**": "allow", + "/tmp/**": "allow", "~/.local/share/nvim/**": "allow", }, "edit": { From bc95c26dab18b9e0fc45b54bc1db98c1b0dda8c7 Mon Sep 17 00:00:00 2001 From: Tony Banh Date: Sat, 25 Apr 2026 04:44:59 -0700 Subject: [PATCH 18/28] replace refactoring.nvim with debugprint.nvim debugprint focuses on the print-debugging workflow we actually used from refactoring.nvim and ships its own keymap config, so drop the heavier plugin in favor of it. --- .../nvim/lua/plugins/editor/debugprint.lua | 47 ++++++ .../nvim/lua/plugins/editor/refactoring.lua | 159 ------------------ 2 files changed, 47 insertions(+), 159 deletions(-) create mode 100644 dot_config/nvim/lua/plugins/editor/debugprint.lua delete mode 100644 dot_config/nvim/lua/plugins/editor/refactoring.lua diff --git a/dot_config/nvim/lua/plugins/editor/debugprint.lua b/dot_config/nvim/lua/plugins/editor/debugprint.lua new file mode 100644 index 0000000..e4f97b0 --- /dev/null +++ b/dot_config/nvim/lua/plugins/editor/debugprint.lua @@ -0,0 +1,47 @@ +local keymap_prefix = "p" + +return { + "andrewferrier/debugprint.nvim", + version = "*", + dependencies = { + "folke/snacks.nvim", + }, + opts = { + keymaps = { + normal = { + plain_below = keymap_prefix .. "p", + plain_above = keymap_prefix .. "P", + variable_below = keymap_prefix .. "v", + variable_above = keymap_prefix .. "V", + variable_below_alwaysprompt = "", + variable_above_alwaysprompt = "", + surround_plain = keymap_prefix .. "sp", + surround_variable = keymap_prefix .. "sv", + surround_variable_alwaysprompt = "", + textobj_below = keymap_prefix .. "o", + textobj_above = keymap_prefix .. "O", + textobj_surround = keymap_prefix .. "so", + toggle_comment_debug_prints = keymap_prefix .. "c", + delete_debug_prints = keymap_prefix .. "d", + }, + insert = { + plain = "p", + variable = "v", + }, + visual = { + variable_below = keymap_prefix .. "v", + variable_above = keymap_prefix .. "V", + }, + }, + }, + config = function(_, opts) + require("debugprint").setup(opts) + require("which-key").add({ + { + keymap_prefix, + group = "print", + icon = { icon = "󱞆 " }, + }, + }) + end, +} diff --git a/dot_config/nvim/lua/plugins/editor/refactoring.lua b/dot_config/nvim/lua/plugins/editor/refactoring.lua deleted file mode 100644 index d9fb533..0000000 --- a/dot_config/nvim/lua/plugins/editor/refactoring.lua +++ /dev/null @@ -1,159 +0,0 @@ -local pick = function() - local refactoring = require("refactoring") - if LazyVim.pick.picker.name == "telescope" then - return require("telescope").extensions.refactoring.refactors() - elseif LazyVim.pick.picker.name == "fzf" then - local fzf_lua = require("fzf-lua") - local results = refactoring.get_refactors() - - local opts = { - fzf_opts = {}, - fzf_colors = true, - actions = { - ["default"] = function(selected) - refactoring.refactor(selected[1]) - end, - }, - } - fzf_lua.fzf_exec(results, opts) - else - refactoring.select_refactor() - end -end - -local js_ts_print_var_statements = { - 'console.log("[LOGS] %s → ", %s);', -} - -return { - "ThePrimeagen/refactoring.nvim", - commit = "6784b54587e6d8a6b9ea199318512170ffb9e418", - event = { "BufReadPre", "BufNewFile" }, - dependencies = { - "nvim-lua/plenary.nvim", - "nvim-treesitter/nvim-treesitter", - }, - keys = { - { "r", "", desc = "+refactor", mode = { "n", "x" } }, - { - "rs", - pick, - mode = { "n", "x" }, - desc = "Refactor", - }, - { - "ri", - function() - return require("refactoring").refactor("Inline Variable") - end, - mode = { "n", "x" }, - desc = "Inline Variable", - expr = true, - }, - { - "rb", - function() - return require("refactoring").refactor("Extract Block") - end, - mode = { "n", "x" }, - desc = "Extract Block", - expr = true, - }, - { - "rf", - function() - return require("refactoring").refactor("Extract Block To File") - end, - mode = { "n", "x" }, - desc = "Extract Block To File", - expr = true, - }, - { - "rP", - function() - require("refactoring").debug.printf({ below = false }) - end, - desc = "Debug Print", - }, - { - "rp", - function() - require("refactoring").debug.print_var({ normal = true }) - end, - mode = { "n", "x" }, - desc = "Debug Print Variable", - }, - { - "rc", - function() - require("refactoring").debug.cleanup({}) - end, - desc = "Debug Cleanup", - }, - { - "rf", - function() - return require("refactoring").refactor("Extract Function") - end, - mode = { "n", "x" }, - desc = "Extract Function", - expr = true, - }, - { - "rF", - function() - return require("refactoring").refactor("Extract Function To File") - end, - mode = { "n", "x" }, - desc = "Extract Function To File", - expr = true, - }, - { - "rx", - function() - return require("refactoring").refactor("Extract Variable") - end, - mode = { "n", "x" }, - desc = "Extract Variable", - expr = true, - }, - { - "rp", - function() - require("refactoring").debug.print_var({}) - end, - mode = { "n", "x" }, - desc = "Debug Print Variable", - }, - }, - opts = { - prompt_func_return_type = { - go = false, - java = false, - cpp = false, - c = false, - h = false, - hpp = false, - cxx = false, - }, - prompt_func_param_type = { - go = false, - java = false, - cpp = false, - c = false, - h = false, - hpp = false, - cxx = false, - }, - printf_statements = {}, - print_var_statements = { - - javascript = js_ts_print_var_statements, - javascriptreact = js_ts_print_var_statements, - typescript = js_ts_print_var_statements, - typescriptreact = js_ts_print_var_statements, - }, - show_success_message = true, -- shows a message with information about the refactor on success - -- i.e. [Refactor] Inlined 3 variable occurrences - }, -} From a63fb9713e0288a6a30eb6de75cf8d424f5503c3 Mon Sep 17 00:00:00 2001 From: Tony Banh Date: Sat, 25 Apr 2026 04:45:22 -0700 Subject: [PATCH 19/28] move n group definition into obsidian plugin The notes/new prefix only exists because of obsidian, so register the which-key group from the obsidian spec itself rather than declaring it globally in which-key.lua. --- dot_config/nvim/lua/plugins/editor/which-key.lua | 5 ----- dot_config/nvim/lua/plugins/misc/obsidian.lua | 9 +++++++++ 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/dot_config/nvim/lua/plugins/editor/which-key.lua b/dot_config/nvim/lua/plugins/editor/which-key.lua index a09b92f..8a40850 100644 --- a/dot_config/nvim/lua/plugins/editor/which-key.lua +++ b/dot_config/nvim/lua/plugins/editor/which-key.lua @@ -9,11 +9,6 @@ return { local wk = require("which-key") wk.setup(opts) wk.add({ - { - "n", - group = "Notes/New...", - icon = { icon = "󰎝 ", color = "purple", cat = "extension" }, - }, { "N", group = "News...", diff --git a/dot_config/nvim/lua/plugins/misc/obsidian.lua b/dot_config/nvim/lua/plugins/misc/obsidian.lua index 7e36b7a..8824160 100644 --- a/dot_config/nvim/lua/plugins/misc/obsidian.lua +++ b/dot_config/nvim/lua/plugins/misc/obsidian.lua @@ -8,6 +8,15 @@ return { lazy = true, ft = "markdown", cmd = { "Obsidian" }, + init = function() + require("which-key").add({ + { + "n", + group = "Notes/New...", + icon = { icon = "󰎝 " }, + }, + }) + end, keys = { { "nd", ":Obsidian dailies -7 7", mode = { "n", "v" }, desc = "Obsidian daily" }, { "ng", ":Obsidian search", mode = { "n", "v" }, desc = "Obsidian search" }, From e9a0bd960b5516f4c10f8f9f5348b177133d0886 Mon Sep 17 00:00:00 2001 From: Tony Banh Date: Sat, 25 Apr 2026 04:45:34 -0700 Subject: [PATCH 20/28] register clipboard yank keymaps via which-key Use wk.add for y and Y so they pick up an icon and keep their descriptions consistent with the rest of the leader map. --- dot_config/nvim/lua/config/keymaps.lua | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/dot_config/nvim/lua/config/keymaps.lua b/dot_config/nvim/lua/config/keymaps.lua index a1e6454..254b908 100644 --- a/dot_config/nvim/lua/config/keymaps.lua +++ b/dot_config/nvim/lua/config/keymaps.lua @@ -1,6 +1,7 @@ -- Keymaps are automatically loaded on the VeryLazy event -- Default keymaps that are always set: https://github.com/LazyVim/LazyVim/blob/main/lua/lazyvim/config/keymaps.lua +local wk = require("which-key") local set = vim.keymap.set local del = vim.keymap.del local opts = { noremap = true, silent = true } @@ -43,8 +44,22 @@ set("c", [[\\-]], [[\(.\{-}\)]], { desc = "Inserts \\(.{-})" }) set("x", "/", "/\\%V", opts) -- Yank to clipboard -set({ "n", "v" }, "y", [["+y]], vim.tbl_extend("force", opts, { desc = "[Y]ank to clipboard" })) -set({ "n", "v" }, "Y", [["+y$]], vim.tbl_extend("force", opts, { desc = "[Y]ank to end of line to clipboard" })) +wk.add({ + { + "y", + [["+y]], + desc = "yank to clipboard", + mode = { "n", "v" }, + icon = { icon = " " }, + }, + { + "Y", + [["+y$]], + desc = "yank to end of line to clipboard", + mode = { "n", "v" }, + icon = { icon = " " }, + }, +}) -- exit terminal mode while in terminal set("t", "[", "", vim.tbl_extend("force", opts, { desc = "terminal escape terminal mode" })) From 7aa33b71a5cb6f15ff672460bfd0c33bbee5f190 Mon Sep 17 00:00:00 2001 From: Tony Banh Date: Sat, 25 Apr 2026 04:45:42 -0700 Subject: [PATCH 21/28] tweak which-key sort order and lowercase group labels Add an explicit sort order so locally-defined mappings show first, and lowercase the News/MultiCursor group labels for visual consistency with the other groups. --- dot_config/nvim/lua/plugins/editor/multicursor.lua | 2 +- dot_config/nvim/lua/plugins/editor/which-key.lua | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/dot_config/nvim/lua/plugins/editor/multicursor.lua b/dot_config/nvim/lua/plugins/editor/multicursor.lua index ed0f098..1609496 100644 --- a/dot_config/nvim/lua/plugins/editor/multicursor.lua +++ b/dot_config/nvim/lua/plugins/editor/multicursor.lua @@ -4,7 +4,7 @@ return { config = function() require("which-key").add({ "m", - group = "MultiCursor", + group = "multiCursor", icon = { icon = "󰆿 " }, }) diff --git a/dot_config/nvim/lua/plugins/editor/which-key.lua b/dot_config/nvim/lua/plugins/editor/which-key.lua index 8a40850..1b509f9 100644 --- a/dot_config/nvim/lua/plugins/editor/which-key.lua +++ b/dot_config/nvim/lua/plugins/editor/which-key.lua @@ -3,6 +3,7 @@ return { lazy = false, opts = { preset = "classic", + sort = { "local", "order", "alphanum", "mod" }, }, config = function(_, opts) @@ -11,7 +12,7 @@ return { wk.add({ { "N", - group = "News...", + group = "news...", icon = { icon = "󰅸 " }, }, { From 5efd0b30ceba9c482458779713e3b53b40bd9e04 Mon Sep 17 00:00:00 2001 From: Tony Banh Date: Sat, 25 Apr 2026 04:45:46 -0700 Subject: [PATCH 22/28] yanky: also disable p in visual mode The unmap only covered normal mode, leaving the visual-mode binding to shadow the new debugprint p prefix. --- dot_config/nvim/lua/plugins/editor/yanky.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/dot_config/nvim/lua/plugins/editor/yanky.lua b/dot_config/nvim/lua/plugins/editor/yanky.lua index 7e05cbf..624ef54 100644 --- a/dot_config/nvim/lua/plugins/editor/yanky.lua +++ b/dot_config/nvim/lua/plugins/editor/yanky.lua @@ -11,6 +11,7 @@ return { { "p", nil, + mode = { "n", "x" }, }, }, } From 3946363300d0eee521c3276618e0ce3133f56d03 Mon Sep 17 00:00:00 2001 From: Tony Banh Date: Sat, 25 Apr 2026 04:45:52 -0700 Subject: [PATCH 23/28] tiny-code-action: silence noisy preview errors and add keymaps Patch safe_buf_op and the buffer previewer to swallow the debug notify and the multi-line stack trace surfaced when an LSP can't resolve a code action. Also wire up explicit preview/select/close keymaps and switch the lsp keys binding from v to x mode. --- .../nvim/lua/plugins/ui/tiny-code-action.lua | 36 +++++++++++++++++-- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/dot_config/nvim/lua/plugins/ui/tiny-code-action.lua b/dot_config/nvim/lua/plugins/ui/tiny-code-action.lua index 67687c6..3f45260 100644 --- a/dot_config/nvim/lua/plugins/ui/tiny-code-action.lua +++ b/dot_config/nvim/lua/plugins/ui/tiny-code-action.lua @@ -2,8 +2,6 @@ return { { "rachartier/tiny-code-action.nvim", dependencies = { - -- {"nvim-telescope/telescope.nvim"}, - -- { "ibhagwan/fzf-lua" }, -- { "folke/snacks.nvim" }, }, event = "LspAttach", @@ -29,9 +27,41 @@ return { auto_preview = true, -- Enable auto preview of the code action position = "cursor", -- "cursor" or "center" winborder = "rounded", -- Set the window border style ("single", "rounded", "solid", etc.) + keymaps = { + preview = "", -- Key to show preview + preview_close = "", -- Keys to return from preview to main window (can be string or table) + select = "", + close = { "q", "" }, + }, }, }, }, + config = function(_, opts) + require("tiny-code-action").setup(opts) + + -- The plugin's safe_buf_op pcalls preview rendering and emits a DEBUG + -- vim.notify on failure ("Buffer operation failed: ..."). The preview + -- still works (or just stays blank), but the notification is noisy. + -- Drop the notify; keep the pcall. + ---@diagnostic disable-next-line: duplicate-set-field + require("tiny-code-action.utils").safe_buf_op = function(fn) + return pcall(fn) + end + + -- When the LSP fails to resolve an action the previewer surfaces a + -- multi-line stack trace ("Unable to preview code action.\nError: ..."). + -- Replace it with a quiet placeholder. + local prev = require("tiny-code-action.previewers.buffer") + local orig_resolve = prev.preview_with_resolve + ---@diagnostic disable-next-line: duplicate-set-field + prev.preview_with_resolve = function(...) + local content = orig_resolve(...) + if type(content) == "table" and content[1] == "Unable to preview code action." then + return { "No preview available for this action" } + end + return content + end + end, }, { "neovim/nvim-lspconfig", @@ -45,7 +75,7 @@ return { require("tiny-code-action").code_action({}) end, desc = "Code Action", - mode = { "n", "v" }, + mode = { "n", "x" }, has = "codeAction", }, }, From fafcc5d30d1d6b7041af952a77f976db7b4a67d0 Mon Sep 17 00:00:00 2001 From: Tony Banh Date: Sat, 25 Apr 2026 04:48:33 -0700 Subject: [PATCH 24/28] misc --- dot_config/opencode/opencode.jsonc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dot_config/opencode/opencode.jsonc b/dot_config/opencode/opencode.jsonc index 3cbf768..1df719d 100644 --- a/dot_config/opencode/opencode.jsonc +++ b/dot_config/opencode/opencode.jsonc @@ -17,6 +17,5 @@ "~/.local/share/nvim/**": "deny", }, }, - "agent": { - }, + "agent": {}, } From 51913b65cb71ae95f7188833543928f921861130 Mon Sep 17 00:00:00 2001 From: Tony Banh Date: Sat, 25 Apr 2026 21:25:31 -0700 Subject: [PATCH 25/28] replace debugprint with nvim-chainsaw for logging --- .../nvim/lua/plugins/editor/debugprint.lua | 47 ------------ .../nvim/lua/plugins/editor/logging.lua | 75 +++++++++++++++++++ 2 files changed, 75 insertions(+), 47 deletions(-) delete mode 100644 dot_config/nvim/lua/plugins/editor/debugprint.lua create mode 100644 dot_config/nvim/lua/plugins/editor/logging.lua diff --git a/dot_config/nvim/lua/plugins/editor/debugprint.lua b/dot_config/nvim/lua/plugins/editor/debugprint.lua deleted file mode 100644 index e4f97b0..0000000 --- a/dot_config/nvim/lua/plugins/editor/debugprint.lua +++ /dev/null @@ -1,47 +0,0 @@ -local keymap_prefix = "p" - -return { - "andrewferrier/debugprint.nvim", - version = "*", - dependencies = { - "folke/snacks.nvim", - }, - opts = { - keymaps = { - normal = { - plain_below = keymap_prefix .. "p", - plain_above = keymap_prefix .. "P", - variable_below = keymap_prefix .. "v", - variable_above = keymap_prefix .. "V", - variable_below_alwaysprompt = "", - variable_above_alwaysprompt = "", - surround_plain = keymap_prefix .. "sp", - surround_variable = keymap_prefix .. "sv", - surround_variable_alwaysprompt = "", - textobj_below = keymap_prefix .. "o", - textobj_above = keymap_prefix .. "O", - textobj_surround = keymap_prefix .. "so", - toggle_comment_debug_prints = keymap_prefix .. "c", - delete_debug_prints = keymap_prefix .. "d", - }, - insert = { - plain = "p", - variable = "v", - }, - visual = { - variable_below = keymap_prefix .. "v", - variable_above = keymap_prefix .. "V", - }, - }, - }, - config = function(_, opts) - require("debugprint").setup(opts) - require("which-key").add({ - { - keymap_prefix, - group = "print", - icon = { icon = "󱞆 " }, - }, - }) - end, -} diff --git a/dot_config/nvim/lua/plugins/editor/logging.lua b/dot_config/nvim/lua/plugins/editor/logging.lua new file mode 100644 index 0000000..28aa106 --- /dev/null +++ b/dot_config/nvim/lua/plugins/editor/logging.lua @@ -0,0 +1,75 @@ +local keymap_prefix = "p" + +local function chainsaw(name) + return function() + require("chainsaw")[name]() + end +end + +return { + "chrisgrieser/nvim-chainsaw", + event = "VeryLazy", + -- required even if left empty + opts = { + marker = "LOG 🪵", + visuals = { + icon = "󱂅", ---@type string|false + }, + logStatements = { + variableLog = { + javascript = { + "/* prettier-ignore */ // {{marker}}", + 'console.log("[{{marker}}] {{filename}}:{{lnum}} - {{var}} → ", {{var}});', + }, + nvim_lua = "Chainsaw({{var}}) -- {{marker}}", + }, + }, + }, + keys = { + -- variable / value inspection + { keymap_prefix .. "a", chainsaw("assertLog"), mode = { "n", "x" }, desc = "assert log" }, + { keymap_prefix .. "o", chainsaw("objectLog"), mode = { "n", "x" }, desc = "object log" }, + { keymap_prefix .. "p", chainsaw("variableLog"), mode = { "n", "x" }, desc = "variable log" }, + { keymap_prefix .. "t", chainsaw("typeLog"), mode = { "n", "x" }, desc = "type log" }, + + -- control-flow / freeform + { keymap_prefix .. "e", chainsaw("emojiLog"), desc = "Emoji log" }, + { keymap_prefix .. "m", chainsaw("messageLog"), desc = "Message log" }, + + -- diagnostics + { keymap_prefix .. "b", chainsaw("debugLog"), desc = "debugger / breakpoint" }, + { keymap_prefix .. "s", chainsaw("stacktraceLog"), desc = "stacktrace log" }, + { keymap_prefix .. "S", chainsaw("sound"), desc = "sound log" }, + { keymap_prefix .. "T", chainsaw("timeLog"), desc = "time log" }, + + -- Search + { + keymap_prefix .. "g", + function() + local marker = require("chainsaw.config.config").config.marker + require("snacks").picker.grep_word({ + title = marker .. " log statements", + cmd = "rg", + args = { "--trim" }, + search = "[" .. marker .. "]", + regex = false, + live = false, + }) + end, + desc = "Find logs", + }, + + -- maintenance + { keymap_prefix .. "C", chainsaw("clearLog"), desc = "clearing statement, e.g. console.clear()" }, + { keymap_prefix .. "d", chainsaw("removeLogs"), mode = { "n", "x" }, desc = "Remove logs" }, + }, + config = function(_, opts) + require("chainsaw").setup(opts) + local ok, wk = pcall(require, "which-key") + if ok then + wk.add({ + { keymap_prefix, group = "print log", icon = { icon = "󱞆 " } }, + }) + end + end, +} From 5c89576ed64531fc4adf8b37dddc8d8eef146013 Mon Sep 17 00:00:00 2001 From: Tony Banh Date: Tue, 28 Apr 2026 00:06:43 -0700 Subject: [PATCH 26/28] gh-dash: update theme colors to everforest --- dot_config/gh-dash/config.yml | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/dot_config/gh-dash/config.yml b/dot_config/gh-dash/config.yml index c074cbb..d29448d 100644 --- a/dot_config/gh-dash/config.yml +++ b/dot_config/gh-dash/config.yml @@ -114,20 +114,20 @@ theme: compact: false # compact table rows colors: text: - primary: "#cdcecf" - secondary: "#71839b" - inverted: "#131a24" - faint: "#71839b" - warning: "#dbc074" - success: "#81b29a" - error: "#c94f6d" - actor: "#63cdcf" + primary: "#d3c6aa" + secondary: "#83c092" + inverted: "#2b3339" + faint: "#7393b3" + warning: "#dbbc7f" + success: "#83c092" + error: "#e67e80" + actor: "#7fbbb3" background: - selected: "#2b3b51" + selected: "#2E383C" border: - primary: "#2b3b51" - secondary: "#393b44" - faint: "#2b3b51" + primary: "#2E383C" + secondary: "#4e565c" + faint: "#2E383C" pager: diff: "" From d929ac362e6476fc5c9eb2bbbb2201c3dbe270d3 Mon Sep 17 00:00:00 2001 From: Tony Banh Date: Tue, 28 Apr 2026 00:07:01 -0700 Subject: [PATCH 27/28] remove vim.o.scrollback, which causes an issue with scrolling up in nvim terminal --- dot_config/nvim/lua/config/options.lua | 2 -- 1 file changed, 2 deletions(-) diff --git a/dot_config/nvim/lua/config/options.lua b/dot_config/nvim/lua/config/options.lua index 09a1ac2..9619409 100644 --- a/dot_config/nvim/lua/config/options.lua +++ b/dot_config/nvim/lua/config/options.lua @@ -13,8 +13,6 @@ vim.cmd("autocmd InsertLeave * set nu rnu") -- Minimal number of screen lines to keep above and below the cursor. vim.opt.scrolloff = 10 -vim.o.scrollback = 0 - -- Keep system clipboard separate from vim clipboard vim.opt.clipboard = "" From 21cb3bdde188e661ad2c13cd8a7b3d4f5b6cf838 Mon Sep 17 00:00:00 2001 From: Tony Banh Date: Tue, 28 Apr 2026 00:07:28 -0700 Subject: [PATCH 28/28] remove logging's statuslihne icon --- dot_config/nvim/lua/plugins/editor/logging.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dot_config/nvim/lua/plugins/editor/logging.lua b/dot_config/nvim/lua/plugins/editor/logging.lua index 28aa106..134983c 100644 --- a/dot_config/nvim/lua/plugins/editor/logging.lua +++ b/dot_config/nvim/lua/plugins/editor/logging.lua @@ -13,7 +13,7 @@ return { opts = { marker = "LOG 🪵", visuals = { - icon = "󱂅", ---@type string|false + icon = false, ---@type string|false }, logStatements = { variableLog = {