From bc6898bb8d30a8ed5f6fff208ef91902084ddc53 Mon Sep 17 00:00:00 2001 From: PattyC Date: Mon, 10 Nov 2025 11:53:26 +0930 Subject: [PATCH 1/2] feat: add opencode and sidekick AI assistant plugins MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add opencode.nvim and sidekick.nvim plugins with default keybindings for AI-assisted coding workflows. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- nvim/lua/core/plugins.lua | 148 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 148 insertions(+) diff --git a/nvim/lua/core/plugins.lua b/nvim/lua/core/plugins.lua index 222f8ba..41d989b 100644 --- a/nvim/lua/core/plugins.lua +++ b/nvim/lua/core/plugins.lua @@ -154,6 +154,154 @@ if config.feature_config.use_copilot then event = "LspAttach", config = function() require("core.configs.copilot") end, } + plugins[#plugins + 1] = { + "NickvanDyke/opencode.nvim", + dependencies = { + { "folke/snacks.nvim", opts = { input = { enabled = true } } }, + }, + ---@type opencode.Opts + opts = { + -- Your configuration, if any — see lua/opencode/config.lua + }, + keys = { + -- Recommended keymaps + { + "oA", + function() require("opencode").ask() end, + desc = "Ask opencode", + }, + { + "oa", + function() require("opencode").ask("@cursor: ") end, + desc = "Ask opencode about this", + mode = "n", + }, + { + "oa", + function() require("opencode").ask("@selection: ") end, + desc = "Ask opencode about selection", + mode = "v", + }, + { + "ot", + function() require("opencode").toggle() end, + desc = "Toggle embedded opencode", + }, + { + "on", + function() require("opencode").command("session_new") end, + desc = "New session", + }, + { + "oy", + function() require("opencode").command("messages_copy") end, + desc = "Copy last message", + }, + { + "", + function() require("opencode").command("messages_half_page_up") end, + desc = "Scroll messages up", + }, + { + "", + function() require("opencode").command("messages_half_page_down") end, + desc = "Scroll messages down", + }, + { + "op", + function() require("opencode").select_prompt() end, + desc = "Select prompt", + mode = { "n", "v" }, + }, + -- Example: keymap for custom prompt + { + "oe", + function() + require("opencode").prompt("Explain @cursor and its context") + end, + desc = "Explain code near cursor", + }, + }, + } + plugins[#plugins + 1] = { + "folke/sidekick.nvim", + opts = { + -- add any options here + cli = { + mux = { + backend = "tmux", + enabled = true, + }, + }, + }, + keys = { + { + "", + function() + -- if there is a next edit, jump to it, otherwise apply it if any + if not require("sidekick").nes_jump_or_apply() then + return "" -- fallback to normal tab + end + end, + expr = true, + desc = "Goto/Apply Next Edit Suggestion", + }, + { + "", + function() require("sidekick.cli").toggle() end, + desc = "Sidekick Toggle", + mode = { "n", "t", "i", "x" }, + }, + { + "aa", + function() require("sidekick.cli").toggle() end, + desc = "Sidekick Toggle CLI", + }, + { + "as", + function() require("sidekick.cli").select() end, + -- Or to select only installed tools: + -- require("sidekick.cli").select({ filter = { installed = true } }) + desc = "Select CLI", + }, + { + "ad", + function() require("sidekick.cli").close() end, + desc = "Detach a CLI Session", + }, + { + "at", + function() require("sidekick.cli").send({ msg = "{this}" }) end, + mode = { "x", "n" }, + desc = "Send This", + }, + { + "af", + function() require("sidekick.cli").send({ msg = "{file}" }) end, + desc = "Send File", + }, + { + "av", + function() require("sidekick.cli").send({ msg = "{selection}" }) end, + mode = { "x" }, + desc = "Send Visual Selection", + }, + { + "ap", + function() require("sidekick.cli").prompt() end, + mode = { "n", "x" }, + desc = "Sidekick Select Prompt", + }, + -- Example of a keybinding to open Claude directly + { + "ac", + function() + require("sidekick.cli").toggle({ name = "claude", focus = true }) + end, + desc = "Sidekick Toggle Claude", + }, + }, + } end if config.feature_config.use_kraken then From f5f8aedef4f07429af26c74f3ed79ab264dc4b54 Mon Sep 17 00:00:00 2001 From: PattyC Date: Mon, 10 Nov 2025 11:57:53 +0930 Subject: [PATCH 2/2] refactor: move AI plugin keybindings to centralized keys config MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move opencode and sidekick keybindings from plugin definitions to the centralized nvim/lua/config/keys.lua file for consistency. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- nvim/lua/config/keys.lua | 132 ++++++++++++++++++++++++++++++++++++++ nvim/lua/core/plugins.lua | 126 ------------------------------------ 2 files changed, 132 insertions(+), 126 deletions(-) diff --git a/nvim/lua/config/keys.lua b/nvim/lua/config/keys.lua index 39b0f96..0797519 100644 --- a/nvim/lua/config/keys.lua +++ b/nvim/lua/config/keys.lua @@ -154,6 +154,138 @@ if config.use_kraken then }) end +-- add opencode.nvim keymaps +if config.use_copilot then + table.insert(M.keymaps, { + mode = "n", + keys = "oA", + command = function() require("opencode").ask() end, + opts = { desc = "Ask opencode" }, + }) + table.insert(M.keymaps, { + mode = "n", + keys = "oa", + command = function() require("opencode").ask("@cursor: ") end, + opts = { desc = "Ask opencode about this" }, + }) + table.insert(M.keymaps, { + mode = "v", + keys = "oa", + command = function() require("opencode").ask("@selection: ") end, + opts = { desc = "Ask opencode about selection" }, + }) + table.insert(M.keymaps, { + mode = "n", + keys = "ot", + command = function() require("opencode").toggle() end, + opts = { desc = "Toggle embedded opencode" }, + }) + table.insert(M.keymaps, { + mode = "n", + keys = "on", + command = function() require("opencode").command("session_new") end, + opts = { desc = "New session" }, + }) + table.insert(M.keymaps, { + mode = "n", + keys = "oy", + command = function() require("opencode").command("messages_copy") end, + opts = { desc = "Copy last message" }, + }) + table.insert(M.keymaps, { + mode = "n", + keys = "", + command = function() require("opencode").command("messages_half_page_up") end, + opts = { desc = "Scroll messages up" }, + }) + table.insert(M.keymaps, { + mode = "n", + keys = "", + command = function() require("opencode").command("messages_half_page_down") end, + opts = { desc = "Scroll messages down" }, + }) + table.insert(M.keymaps, { + mode = { "n", "v" }, + keys = "op", + command = function() require("opencode").select_prompt() end, + opts = { desc = "Select prompt" }, + }) + table.insert(M.keymaps, { + mode = "n", + keys = "oe", + command = function() require("opencode").prompt("Explain @cursor and its context") end, + opts = { desc = "Explain code near cursor" }, + }) +end + +-- add sidekick.nvim keymaps +if config.use_copilot then + table.insert(M.keymaps, { + mode = "n", + keys = "", + command = function() + if not require("sidekick").nes_jump_or_apply() then + return "" + end + end, + opts = { desc = "Goto/Apply Next Edit Suggestion", expr = true }, + }) + table.insert(M.keymaps, { + mode = { "n", "t", "i", "x" }, + keys = "", + command = function() require("sidekick.cli").toggle() end, + opts = { desc = "Sidekick Toggle" }, + }) + table.insert(M.keymaps, { + mode = "n", + keys = "aa", + command = function() require("sidekick.cli").toggle() end, + opts = { desc = "Sidekick Toggle CLI" }, + }) + table.insert(M.keymaps, { + mode = "n", + keys = "as", + command = function() require("sidekick.cli").select() end, + opts = { desc = "Select CLI" }, + }) + table.insert(M.keymaps, { + mode = "n", + keys = "ad", + command = function() require("sidekick.cli").close() end, + opts = { desc = "Detach a CLI Session" }, + }) + table.insert(M.keymaps, { + mode = { "x", "n" }, + keys = "at", + command = function() require("sidekick.cli").send({ msg = "{this}" }) end, + opts = { desc = "Send This" }, + }) + table.insert(M.keymaps, { + mode = "n", + keys = "af", + command = function() require("sidekick.cli").send({ msg = "{file}" }) end, + opts = { desc = "Send File" }, + }) + table.insert(M.keymaps, { + mode = "x", + keys = "av", + command = function() require("sidekick.cli").send({ msg = "{selection}" }) end, + opts = { desc = "Send Visual Selection" }, + }) + table.insert(M.keymaps, { + mode = { "n", "x" }, + keys = "ap", + command = function() require("sidekick.cli").prompt() end, + opts = { desc = "Sidekick Select Prompt" }, + }) + table.insert(M.keymaps, { + mode = "n", + keys = "ac", + command = function() require("sidekick.cli").toggle({ name = "claude", focus = true }) end, + opts = { desc = "Sidekick Toggle Claude" }, + }) +end + ---@type KeymapDefinition[] M.terminal_keymaps = { { diff --git a/nvim/lua/core/plugins.lua b/nvim/lua/core/plugins.lua index 41d989b..46849e2 100644 --- a/nvim/lua/core/plugins.lua +++ b/nvim/lua/core/plugins.lua @@ -163,65 +163,6 @@ if config.feature_config.use_copilot then opts = { -- Your configuration, if any — see lua/opencode/config.lua }, - keys = { - -- Recommended keymaps - { - "oA", - function() require("opencode").ask() end, - desc = "Ask opencode", - }, - { - "oa", - function() require("opencode").ask("@cursor: ") end, - desc = "Ask opencode about this", - mode = "n", - }, - { - "oa", - function() require("opencode").ask("@selection: ") end, - desc = "Ask opencode about selection", - mode = "v", - }, - { - "ot", - function() require("opencode").toggle() end, - desc = "Toggle embedded opencode", - }, - { - "on", - function() require("opencode").command("session_new") end, - desc = "New session", - }, - { - "oy", - function() require("opencode").command("messages_copy") end, - desc = "Copy last message", - }, - { - "", - function() require("opencode").command("messages_half_page_up") end, - desc = "Scroll messages up", - }, - { - "", - function() require("opencode").command("messages_half_page_down") end, - desc = "Scroll messages down", - }, - { - "op", - function() require("opencode").select_prompt() end, - desc = "Select prompt", - mode = { "n", "v" }, - }, - -- Example: keymap for custom prompt - { - "oe", - function() - require("opencode").prompt("Explain @cursor and its context") - end, - desc = "Explain code near cursor", - }, - }, } plugins[#plugins + 1] = { "folke/sidekick.nvim", @@ -234,73 +175,6 @@ if config.feature_config.use_copilot then }, }, }, - keys = { - { - "", - function() - -- if there is a next edit, jump to it, otherwise apply it if any - if not require("sidekick").nes_jump_or_apply() then - return "" -- fallback to normal tab - end - end, - expr = true, - desc = "Goto/Apply Next Edit Suggestion", - }, - { - "", - function() require("sidekick.cli").toggle() end, - desc = "Sidekick Toggle", - mode = { "n", "t", "i", "x" }, - }, - { - "aa", - function() require("sidekick.cli").toggle() end, - desc = "Sidekick Toggle CLI", - }, - { - "as", - function() require("sidekick.cli").select() end, - -- Or to select only installed tools: - -- require("sidekick.cli").select({ filter = { installed = true } }) - desc = "Select CLI", - }, - { - "ad", - function() require("sidekick.cli").close() end, - desc = "Detach a CLI Session", - }, - { - "at", - function() require("sidekick.cli").send({ msg = "{this}" }) end, - mode = { "x", "n" }, - desc = "Send This", - }, - { - "af", - function() require("sidekick.cli").send({ msg = "{file}" }) end, - desc = "Send File", - }, - { - "av", - function() require("sidekick.cli").send({ msg = "{selection}" }) end, - mode = { "x" }, - desc = "Send Visual Selection", - }, - { - "ap", - function() require("sidekick.cli").prompt() end, - mode = { "n", "x" }, - desc = "Sidekick Select Prompt", - }, - -- Example of a keybinding to open Claude directly - { - "ac", - function() - require("sidekick.cli").toggle({ name = "claude", focus = true }) - end, - desc = "Sidekick Toggle Claude", - }, - }, } end