From f27115f7c053d1d8e4b2af4b7506210fffc51c95 Mon Sep 17 00:00:00 2001 From: Elvis Claros Castro Date: Thu, 9 Jan 2025 10:33:28 -0300 Subject: =?UTF-8?q?Feat:=20agrego=20m=C3=A1s=20plugins?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lua/config/codecompanion-save.lua | 60 ++++++++++++++++ lua/config/init.lua | 2 +- lua/config/keymaps.lua | 10 +++ lua/pi/dap/configs/python.lua | 13 ++++ lua/plugins/codecompanion.lua | 146 +++++++++++++++++++++++++++++++++++--- lua/plugins/copilot-chat.lua | 95 ++++++++++++++++++++++++- lua/plugins/markdown-render.lua | 5 ++ lua/plugins/nvim-dap-python.lua | 3 + 8 files changed, 319 insertions(+), 15 deletions(-) create mode 100644 lua/config/codecompanion-save.lua create mode 100644 lua/pi/dap/configs/python.lua create mode 100644 lua/plugins/markdown-render.lua create mode 100644 lua/plugins/nvim-dap-python.lua (limited to 'lua') diff --git a/lua/config/codecompanion-save.lua b/lua/config/codecompanion-save.lua new file mode 100644 index 0000000..46f2d94 --- /dev/null +++ b/lua/config/codecompanion-save.lua @@ -0,0 +1,60 @@ +-- add 2 commands: +-- CodeCompanionSave [space delimited args] +-- CodeCompanionLoad +-- Save will save current chat in a md file named 'space-delimited-args.md' +-- Load will use a telescope filepicker to open a previously saved chat + +-- create a folder to store our chats +local Path = require("plenary.path") +local data_path = vim.fn.stdpath("data") +local save_folder = Path:new(data_path, "cc_saves") +if not save_folder:exists() then + save_folder:mkdir({ parents = true }) +end + +-- telescope picker for our saved chats +vim.api.nvim_create_user_command("CodeCompanionLoad", function() + local t_builtin = require("telescope.builtin") + local t_actions = require("telescope.actions") + local t_action_state = require("telescope.actions.state") + + local function start_picker() + t_builtin.find_files({ + prompt_title = "Saved CodeCompanion Chats | : delete", + cwd = save_folder:absolute(), + attach_mappings = function(_, map) + map("i", "", function(prompt_bufnr) + local selection = t_action_state.get_selected_entry() + local filepath = selection.path or selection.filename + os.remove(filepath) + t_actions.close(prompt_bufnr) + start_picker() + end) + return true + end, + }) + end + start_picker() +end, {}) + +-- save current chat, `CodeCompanionSave foo bar baz` will save as 'foo-bar-baz.md' +vim.api.nvim_create_user_command("CodeCompanionSave", function(opts) + local codecompanion = require("codecompanion") + local success, chat = pcall(function() + return codecompanion.buf_get_chat(0) + end) + if not success or chat == nil then + vim.notify( + "CodeCompanionSave should only be called from CodeCompanion chat buffers", + vim.log.levels.ERROR + ) + return + end + if #opts.fargs == 0 then + vim.notify("CodeCompanionSave requires at least 1 arg to make a file name", vim.log.levels.ERROR) + end + local save_name = table.concat(opts.fargs, "-") .. ".md" + local save_path = Path:new(save_folder, save_name) + local lines = vim.api.nvim_buf_get_lines(0, 0, -1, false) + save_path:write(table.concat(lines, "\n"), "w") +end, { nargs = "*" }) diff --git a/lua/config/init.lua b/lua/config/init.lua index b84221f..b666da3 100644 --- a/lua/config/init.lua +++ b/lua/config/init.lua @@ -9,7 +9,7 @@ vim.api.nvim_create_autocmd("User", { require "config.keymaps" require "config.diagnostic" require "config.composer" - require "config.copilot" + require "config.codecompanion-save" end, }) require "config.lazy" diff --git a/lua/config/keymaps.lua b/lua/config/keymaps.lua index cd6dfb0..c42bf71 100644 --- a/lua/config/keymaps.lua +++ b/lua/config/keymaps.lua @@ -153,4 +153,14 @@ map( ':RustLsp runnables', {desc = "run rust"} ) +vim.keymap.set('n', 'pdm', function() + require('dap-python').test_method() +end) + +vim.keymap.set('n', 'pdc', function() + require('dap-python').test_class() +end) +vim.keymap.set('n', 'pdf', function() + require('dap-python').test_file() +end) diff --git a/lua/pi/dap/configs/python.lua b/lua/pi/dap/configs/python.lua new file mode 100644 index 0000000..2e7fea7 --- /dev/null +++ b/lua/pi/dap/configs/python.lua @@ -0,0 +1,13 @@ +local dap = require "dap" +require("dap-python").setup "python" +require('dap-python').test_runner = 'pytest' +-- dap.configurations.python = { +-- { +-- type = "python", +-- request = "launch", +-- name = "My custom launch configuration", +-- program = "${file}", +-- projectDir = "${workspaceRoot}" +-- -- ... more options, see https://github.com/microsoft/debugpy/wiki/Debug-configuration-settings +-- }, +-- } diff --git a/lua/plugins/codecompanion.lua b/lua/plugins/codecompanion.lua index a98a7af..324f4d2 100644 --- a/lua/plugins/codecompanion.lua +++ b/lua/plugins/codecompanion.lua @@ -1,15 +1,139 @@ +local IS_DEV = false return { - "olimorris/codecompanion.nvim", - dependencies = { - "nvim-lua/plenary.nvim", + { "nvim-treesitter/nvim-treesitter", - "hrsh7th/nvim-cmp", -- Optional: For using slash commands and variables in the chat buffer - "nvim-telescope/telescope.nvim", -- Optional: For using slash commands - { - "MeanderingProgrammer/render-markdown.nvim", - ft = { "markdown", "codecompanion" }, - }, -- Optional: For prettier markdown rendering - { "stevearc/dressing.nvim", opts = {} }, -- Optional: Improves `vim.ui.select` + opts = { ensure_installed = { "yaml", "markdown" } }, + }, + { + dir = IS_DEV and "~/Projects/research/codecompanion.nvim" or nil, + "olimorris/codecompanion.nvim", + dependencies = { + "nvim-lua/plenary.nvim", + "nvim-treesitter/nvim-treesitter", + "ibhagwan/fzf-lua", -- For fzf provider, file or buffer picker + "jellydn/spinner.nvim", -- Show loading spinner when request is started + }, + opts = { + adapters = { + ollama = function() + return require("codecompanion.adapters").extend("ollama", { + name = "tinyllama", + env = { + url = "http://127.0.0.1:11434", + -- api_key = "", + }, + headers = { + ["Content-Type"] = "application/json", + -- ["Authorization"] = "Bearer ${api_key}", + }, + parameters = { + sync = true, + }, + schema = { + model = { + default = "tinyllama:1.1b", + }, + }, + }) + end, + anthropic = function() + return require("codecompanion.adapters").extend("anthropic", { + env = { + api_key = "cmd:echo $ANTHROPIC_API_KEY", + }, + schema = { + model = { + default = "claude-3-opus-20240229", + }, + }, + }) + end, + copilot = function() + return require("codecompanion.adapters").extend("copilot", { + schema = { + model = { + default = "claude-3.5-sonnet", + }, + }, + }) + end, + gemini = function() + return require("codecompanion.adapters").extend("gemini", { + env = { + api_key = "cmd:op read op://personal/Gemini_API/credential --no-newline", + }, + }) + end, + openai = function() + return require("codecompanion.adapters").extend("openai", { + env = { + api_key = "cmd:echo $OPENAI_API_KEY", + chat_url = "/v1/chat/completions", + url = "https://api.openai.com", + }, + schema = { + model = { + default = function() + return "gpt-4o-mini" + end, + }, + }, + }) + end, + openai_compatible = function() + return require("codecompanion.adapters").extend("openai_compatible", { + env = { + api_key = "cmd:echo $OPENAI_API_KEY", + chat_url = "/v1/chat/completions", + url = "http://127.0.0.1:8080", + }, + headers = { + ["Content-Type"] = "application/json", + }, + schema = { + model = { + default = function() + return "davinci" + end, + }, + }, + }) + end, + xai = function() + return require("codecompanion.adapters").extend("xai", { + env = { + api_key = "cmd:op read op://personal/xAI_API/credential --no-newline", + }, + }) + end, + }, + strategies = { + chat = { + adapter = "copilot", + -- roles = { llm = " Copilot Chat", user = "IT Man" }, + }, + inline = { adapter = "copilot" }, + agent = { adapter = "copilot" }, + }, + }, + config = function(_, options) + require("codecompanion").setup(options) + + -- Show loading spinner when request is started + local spinner = require("spinner") + local group = vim.api.nvim_create_augroup("CodeCompanionHooks", {}) + vim.api.nvim_create_autocmd({ "User" }, { + pattern = "CodeCompanionRequest*", + group = group, + callback = function(request) + if request.match == "CodeCompanionRequestStarted" then + spinner.show() + end + if request.match == "CodeCompanionRequestFinished" then + spinner.hide() + end + end, + }) + end, }, - config = true, } diff --git a/lua/plugins/copilot-chat.lua b/lua/plugins/copilot-chat.lua index dc31b32..d389d2f 100644 --- a/lua/plugins/copilot-chat.lua +++ b/lua/plugins/copilot-chat.lua @@ -1,8 +1,35 @@ +local IS_DEV = false + +local prompts = { + -- Code related prompts + Explain = "Please explain how the following code works.", + Review = "Please review the following code and provide suggestions for improvement.", + Tests = "Please explain how the selected code works, then generate unit tests for it.", + Refactor = "Please refactor the following code to improve its clarity and readability.", + FixCode = "Please fix the following code to make it work as intended.", + FixError = "Please explain the error in the following text and provide a solution.", + BetterNamings = "Please provide better names for the following variables and functions.", + Documentation = "Please provide documentation for the following code.", + SwaggerApiDocs = "Please provide documentation for the following API using Swagger.", + SwaggerJsDocs = "Please write JSDoc for the following API using Swagger.", + -- Text related prompts + Summarize = "Please summarize the following text.", + Spelling = "Please correct any grammar and spelling errors in the following text.", + Wording = "Please improve the grammar and wording of the following text.", + Concise = "Please rewrite the following text to make it more concise.", +} + return { { + "nvim-treesitter/nvim-treesitter", + opts = { ensure_installed = { "diff", "markdown" } }, + }, + { + dir = IS_DEV and "~/research/CopilotChat.nvim" or nil, "CopilotC-Nvim/CopilotChat.nvim", + -- version = "v3.3.0", dependencies = { - { "nvim-lua/plenary.nvim", branch = "master" }, -- for curl, log and async functions + { "nvim-lua/plenary.nvim" }, { "ibhagwan/fzf-lua", config = function() @@ -11,8 +38,70 @@ return { }, }, opts = { - -- See Configuration section for options + model = 'claude-3.5-sonnet', + -- question_header = "## User ", + -- answer_header = "## Copilot ", + -- error_header = "## Error ", + prompts = prompts, + -- Turn off Claude model as it's not working well + -- model = "claude-3.5-sonnet", + auto_follow_cursor = false, -- Don't follow the cursor after getting response + }, - -- See Commands section for default commands if you want to lazy load on them + config = function(_, opts) + local chat = require("CopilotChat") + local select = require("CopilotChat.select") + -- Use unnamed register for the selection + opts.selection = select.unnamed + + -- local hostname = io.popen("hostname"):read("*a"):gsub("%s+", "") + -- local user = hostname or vim.env.USER or "User" + -- opts.question_header = " " .. user .. " " + -- opts.answer_header = " Copilot " + -- Override the git prompts message + opts.prompts.Commit = { + prompt = '> #git:staged\n\nWrite commit message with commitizen convention. Write clear, informative commit messages that explain the "what" and "why" behind changes, not just the "how".', + } + + chat.setup(opts) + + vim.api.nvim_create_user_command("CopilotChatVisual", function(args) + chat.ask(args.args, { selection = select.visual }) + end, { nargs = "*", range = true }) + + -- Inline chat with Copilot + vim.api.nvim_create_user_command("CopilotChatInline", function(args) + chat.ask(args.args, { + selection = select.visual, + window = { + layout = "float", + relative = "cursor", + width = 1, + height = 0.4, + row = 1, + }, + }) + end, { nargs = "*", range = true }) + + -- Restore CopilotChatBuffer + vim.api.nvim_create_user_command("CopilotChatBuffer", function(args) + chat.ask(args.args, { selection = select.buffer }) + end, { nargs = "*", range = true }) + + -- Custom buffer for CopilotChat + vim.api.nvim_create_autocmd("BufEnter", { + pattern = "copilot-*", + callback = function() + vim.opt_local.relativenumber = true + vim.opt_local.number = true + + -- Get current filetype and set it to markdown if the current filetype is copilot-chat + local ft = vim.bo.filetype + if ft == "copilot-chat" then + vim.bo.filetype = "markdown" + end + end, + }) + end, }, } diff --git a/lua/plugins/markdown-render.lua b/lua/plugins/markdown-render.lua new file mode 100644 index 0000000..6263fd9 --- /dev/null +++ b/lua/plugins/markdown-render.lua @@ -0,0 +1,5 @@ +return { + "MeanderingProgrammer/render-markdown.nvim", + ft = { "markdown", "codecompanion", "copilot-chat" }, +} + diff --git a/lua/plugins/nvim-dap-python.lua b/lua/plugins/nvim-dap-python.lua new file mode 100644 index 0000000..da973e4 --- /dev/null +++ b/lua/plugins/nvim-dap-python.lua @@ -0,0 +1,3 @@ +return { + "mfussenegger/nvim-dap-python", +} -- cgit v1.2.3