return { { "robitx/gp.nvim", init = function() local wk = require("which-key") wk.add({ mode = { "n", "v", "x" }, { "G", group = "GPT" }, { "Gg", group = "Gp" }, { "GW", group = "Whisper" }, }) end, config = function() local function keymapOptions(desc) return { noremap = true, silent = true, nowait = true, desc = desc, } end local conf = { -- For customization, refer to Install > Configuration in the Documentation/Readme -- openai_api_key = { "pass", "show", "api/chatGPT/nvim" }, openai_api_key = { "pass", "show", "api/chatGPT/nvim" }, providers = { openai = { disable = false, endpoint = "https://api.openai.com/v1/chat/completions", -- secret = { "pass", "show", "api/chatGPT/nvim" }, }, }, hooks = { -- GpInspectPlugin provides a detailed inspection of the plugin state InspectPlugin = function(plugin, params) local bufnr = vim.api.nvim_create_buf(false, true) local copy = vim.deepcopy(plugin) local key = copy.config.openai_api_key or "" copy.config.openai_api_key = key:sub(1, 3) .. string.rep("*", #key - 6) .. key:sub(-3) local plugin_info = string.format("Plugin structure:\n%s", vim.inspect(copy)) local params_info = string.format("Command params:\n%s", vim.inspect(params)) local lines = vim.split(plugin_info .. "\n" .. params_info, "\n") vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, lines) vim.api.nvim_win_set_buf(0, bufnr) end, -- GpInspectLog for checking the log file InspectLog = function(plugin, params) local log_file = plugin.config.log_file local buffer = plugin.helpers.get_buffer(log_file) if not buffer then vim.cmd("e " .. log_file) else vim.cmd("buffer " .. buffer) end end, -- GpImplement rewrites the provided selection/range based on comments in it Implement = function(gp, params) local template = "Having following from {{filename}}:\n\n" .. "```{{filetype}}\n{{selection}}\n```\n\n" .. "Please rewrite this according to the contained instructions." .. "\n\nRespond exclusively with the snippet that should replace the selection above." local agent = gp.get_command_agent() gp.logger.info("Implementing selection with agent: " .. agent.name) gp.Prompt( params, gp.Target.rewrite, agent, template, nil, -- command will run directly without any prompting for user input nil -- no predefined instructions (e.g. speech-to-text from Whisper) ) end, -- your own functions can go here, see README for more examples like -- :GpExplain, :GpUnitTests.., :GpTranslator etc. -- example of making :%GpChatNew a dedicated command which -- opens new chat with the entire current buffer as a context BufferChatNew = function(gp, _) -- call GpChatNew command in range mode on whole buffer vim.api.nvim_command("%" .. gp.config.cmd_prefix .. "ChatNew") end, -- example of adding command which opens new chat dedicated for translation Translator = function(gp, params) local chat_system_prompt = "You are a Translator, please translate between English and Korean." gp.cmd.ChatNew(params, chat_system_prompt) -- -- you can also create a chat with a specific fixed agent like this: -- local agent = gp.get_chat_agent("ChatGPT4o") -- gp.cmd.ChatNew(params, chat_system_prompt, agent) end, -- example of adding command which writes unit tests for the selected code UnitTests = function(gp, params) local template = "I have the following code from {{filename}}:\n\n" .. "```{{filetype}}\n{{selection}}\n```\n\n" .. "Please respond by writing table driven unit tests for the code above." local agent = gp.get_command_agent() gp.Prompt(params, gp.Target.enew, agent, template) end, -- example of adding command which explains the selected code Explain = function(gp, params) local template = "I have the following code from {{filename}}:\n\n" .. "```{{filetype}}\n{{selection}}\n```\n\n" .. "Please respond by explaining the code above." local agent = gp.get_chat_agent() gp.Prompt(params, gp.Target.popup, agent, template) end, -- example of usig enew as a function specifying type for the new buffer CodeReview = function(gp, params) local template = "I have the following code from {{filename}}:\n\n" .. "```{{filetype}}\n{{selection}}\n```\n\n" .. "Please analyze for code smells and suggest improvements." local agent = gp.get_chat_agent() gp.Prompt(params, gp.Target.enew("markdown"), agent, template) end, }, } require("gp").setup(conf) -- Setup shortcuts here (see Usage > Shortcuts in the Documentation/Readme) vim.keymap.set({ "n", "i" }, "Gc", "GpChatNew", keymapOptions("New chat")) vim.keymap.set({ "n", "i" }, "Gb", "GpBufferChatNew", keymapOptions("New buffer chat")) vim.keymap.set({ "n", "i" }, "Gt", "GpChatToggle", keymapOptions("Toggle chat")) vim.keymap.set({ "n", "i" }, "Gf", "GpChatFinder", keymapOptions("Chat finder")) vim.keymap.set("v", "Gc", ":'<,'>GpChatNew", keymapOptions("Chat new")) vim.keymap.set("v", "Gb", ":'<,'>GpBufferChatNew", keymapOptions("Buffer chat new")) vim.keymap.set("v", "Gp", ":'<,'>GpChatPaste", keymapOptions("Chat paste")) vim.keymap.set("v", "Gt", ":'<,'>GpChatToggle", keymapOptions("Toggle chat")) vim.keymap.set({ "n", "i" }, "Gh", "gpchatnew split", keymapOptions("New chat split")) vim.keymap.set({ "n", "i" }, "Gv", "gpchatnew vsplit", keymapOptions("New chat vsplit")) vim.keymap.set({ "n", "i" }, "Gn", "gpchatnew tabnew", keymapOptions("New chat tabnew")) vim.keymap.set("v", "Gh", ":'<,'>GpChatNew split", keymapOptions("Chat new split")) vim.keymap.set("v", "Gv", ":'<,'>GpChatNew vsplit", keymapOptions("Chat new vsplit")) vim.keymap.set("v", "Gn", ":'<,'>GpChatNew tabnew", keymapOptions("Chat new tabnew")) -- Prompt commands vim.keymap.set({ "n", "i" }, "Gw", "GpRewrite", keymapOptions("Inline rewrite")) vim.keymap.set({ "n", "i" }, "Gr", "GpCodeReview", keymapOptions("Code review")) vim.keymap.set({ "n", "i" }, "G]", "GpAppend", keymapOptions("Append (after)")) vim.keymap.set({ "n", "i" }, "G[", "GpPrepend", keymapOptions("Prepend (before)")) vim.keymap.set("v", "Gw", ":'<,'>GpRewrite", keymapOptions("Rewrite")) vim.keymap.set("v", "Gr", ":'<,'>GpCodeReview", keymapOptions("Code review")) vim.keymap.set("v", "G]", ":'<,'>GpAppend", keymapOptions("Append (after)")) vim.keymap.set("v", "G[", ":'<,'>GpPrepend", keymapOptions("Prepend (before)")) vim.keymap.set("v", "Gi", ":'<,'>GpImplement", keymapOptions("Implement selection")) vim.keymap.set({ "n", "i" }, "Ggp", "GpPopup", keymapOptions("Popup")) vim.keymap.set({ "n", "i" }, "Gge", "GpEnew", keymapOptions("GpEnew")) vim.keymap.set({ "n", "i" }, "Ggc", "GpNew", keymapOptions("GpNew")) vim.keymap.set({ "n", "i" }, "Ggv", "GpVnew", keymapOptions("GpVnew")) vim.keymap.set({ "n", "i" }, "Ggn", "GpTabnew", keymapOptions("GpTabnew")) vim.keymap.set("v", "Ggp", ":'<,'>GpPopup", keymapOptions("Popup")) vim.keymap.set("v", "Gge", ":'<,'>GpEnew", keymapOptions("GpEnew")) vim.keymap.set("v", "Ggc", ":'<,'>GpNew", keymapOptions("GpNew")) vim.keymap.set("v", "Ggv", ":'<,'>GpVnew", keymapOptions("GpVnew")) vim.keymap.set("v", "Ggn", ":'<,'>GpTabnew", keymapOptions("GpTabnew")) vim.keymap.set({ "n", "i" }, "Gx", "GpContext", keymapOptions("Toggle context")) vim.keymap.set("v", "Gx", ":'<,'>GpContext", keymapOptions("Toggle context")) vim.keymap.set({ "n", "i", "v", "x" }, "Ggs", "GpStop", keymapOptions("Stop")) vim.keymap.set({ "n", "i", "v", "x" }, "Gg]", "GpNextAgent", keymapOptions("Next agent")) -- optional Whisper commands with prefix w vim.keymap.set({ "n", "i" }, "GWw", "GpWhisper", keymapOptions("Whisper")) vim.keymap.set("v", "GWw", ":'<,'>GpWhisper", keymapOptions("Whisper")) vim.keymap.set({ "n", "i" }, "GWr", "GpWhisperRewrite", keymapOptions("Inline rewrite")) vim.keymap.set({ "n", "i" }, "GW]", "GpWhisperAppend", keymapOptions("Append (after)")) vim.keymap.set({ "n", "i" }, "GW[", "GpWhisperPrepend", keymapOptions("Prepend (before) ")) vim.keymap.set("v", "GWr", ":'<,'>GpWhisperRewrite", keymapOptions("Rewrite")) vim.keymap.set("v", "GW]", ":'<,'>GpWhisperAppend", keymapOptions("Append (after)")) vim.keymap.set("v", "GW[", ":'<,'>GpWhisperPrepend", keymapOptions("Prepend (before)")) vim.keymap.set({ "n", "i" }, "GWp", "GpWhisperPopup", keymapOptions("Popup")) vim.keymap.set({ "n", "i" }, "GWe", "GpWhisperEnew", keymapOptions("Enew")) vim.keymap.set({ "n", "i" }, "GWc", "GpWhisperNew", keymapOptions("New")) vim.keymap.set({ "n", "i" }, "GWv", "GpWhisperVnew", keymapOptions("Vnew")) vim.keymap.set({ "n", "i" }, "GWn", "GpWhisperTabnew", keymapOptions("Tabnew")) vim.keymap.set("v", "GWp", ":'<,'>GpWhisperPopup", keymapOptions("Popup")) vim.keymap.set("v", "GWe", ":'<,'>GpWhisperEnew", keymapOptions("Enew")) vim.keymap.set("v", "GWc", ":'<,'>GpWhisperNew", keymapOptions("New")) vim.keymap.set("v", "GWv", ":'<,'>GpWhisperVnew", keymapOptions("Vnew")) vim.keymap.set("v", "GWn", ":'<,'>GpWhisperTabnew", keymapOptions("Tabnew")) end, }, -- { -- "zbirenbaum/copilot.lua", -- cmd = "Copilot", -- build = ":Copilot auth", -- event = "InsertEnter", -- dependencies = { -- "hrsh7th/nvim-cmp", -- { "AndreM222/copilot-lualine" }, -- { -- "zbirenbaum/copilot-cmp", -- config = function() -- require("copilot_cmp").setup() -- end, -- }, -- }, -- config = function() -- require("copilot").setup({ -- panel = { -- enabled = true, -- auto_refresh = true, -- keymap = { -- jump_prev = "[a", -- jump_next = "]a", -- accept = "", -- refresh = "gr", -- open = "", -- }, -- layout = { -- position = "right", -- | top | left | right -- ratio = 0.4, -- }, -- }, -- suggestion = { -- enabled = true, -- auto_trigger = true, -- hide_during_completion = true, -- debounce = 75, -- keymap = { -- accept = "", -- accept_word = false, -- accept_line = false, -- next = "", -- prev = "", -- dismiss = "", -- }, -- }, -- filetypes = { -- cvs = false, -- gitcommit = false, -- gitrebase = false, -- help = true, -- hgcommit = false, -- markdown = true, -- sh = function() -- if string.match(vim.fs.basename(vim.api.nvim_buf_get_name(0)), "^%.env.*") then -- -- disable for .env files -- return false -- end -- return true -- end, -- svn = false, -- yaml = false, -- ["."] = false, -- ["*"] = true, -- }, -- copilot_node_command = "node", -- Node.js version must be > 18.x -- server_opts_overrides = {}, -- }) -- -- local cmp = require("cmp") -- cmp.event:on("menu_opened", function() -- vim.b.copilot_suggestion_hidden = true -- end) -- -- cmp.event:on("menu_closed", function() -- vim.b.copilot_suggestion_hidden = false -- end) -- end, -- -- vim.keymap.set("n", "ct", function() -- require("copilot.suggestion").toggle_auto_trigger() -- end, { noremap = true, silent = true, desc = "Toggle copilot" }), -- }, }