diff --git a/CHANGELOG.md b/CHANGELOG.md index 7aa3208b..e1c4200e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## [1.4.0](https://github.com/CopilotC-Nvim/CopilotChat.nvim/compare/v1.3.0...v1.4.0) (2024-02-16) + + +### Features + +* add diagnostic troubleshooting command ([0e5eced](https://github.com/CopilotC-Nvim/CopilotChat.nvim/commit/0e5ecedda4d7a9cc6eeef1424889d8d9550bf4f3)) +* add toggle command for vertical split in CopilotChat ([48209d6](https://github.com/CopilotC-Nvim/CopilotChat.nvim/commit/48209d6b98cb50c9dae59da70ebda351282cf8f7)) +* **integration:** set filetype to 'copilot-chat' for support edgy.nvim ([60718ed](https://github.com/CopilotC-Nvim/CopilotChat.nvim/commit/60718ed6e806fa86fd78cb3bf55a05f1a74b257e)) + ## [1.3.0](https://github.com/CopilotC-Nvim/CopilotChat.nvim/compare/v1.2.0...v1.3.0) (2024-02-14) diff --git a/README.md b/README.md index 5a522b6d..48fd1ddb 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ Ensure you have the following installed: - Python 3.10 or later +- Enable `python3 provider` in Neovim. Testing by run `:echo has('python3')` in Neovim. If it returns `1`, then `python3 provider` is enabled. ## Authentication @@ -44,6 +45,11 @@ return { keys = { { "cce", "CopilotChatExplain", desc = "CopilotChat - Explain code" }, { "cct", "CopilotChatTests", desc = "CopilotChat - Generate tests" }, + { + "ccT", + "CopilotChatVsplitToggle", + desc = "CopilotChat - Toggle Vsplit", -- Toggle vertical split + }, { "ccv", ":CopilotChatVisual", @@ -56,6 +62,16 @@ return { mode = "x", desc = "CopilotChat - Run in-place code", }, + { + "ccf", + "CopilotChatFixDiagnostic", -- Get a fix for the diagnostic message under the cursor. + desc = "CopilotChat - Fix diagnostic", + }, + { + "ccr", + "CopilotChatReset", -- Reset chat history and clear buffer. + desc = "CopilotChat - Reset chat history and clear buffer", + } }, }, } @@ -69,7 +85,9 @@ For example: " python3 plugins call remote#host#RegisterPlugin('python3', '/Users/huynhdung/.local/share/nvim/lazy/CopilotChat.nvim/rplugin/python3/CopilotChat', [ \ {'sync': v:false, 'name': 'CopilotChat', 'type': 'command', 'opts': {'nargs': '1'}}, + \ {'sync': v:false, 'name': 'CopilotChatReset', 'type': 'command', 'opts': {}}, \ {'sync': v:false, 'name': 'CopilotChatVisual', 'type': 'command', 'opts': {'nargs': '1', 'range': ''}}, + \ {'sync': v:false, 'name': 'CopilotChatVsplitToggle', 'type': 'command', 'opts': {}}, \ {'sync': v:false, 'name': 'CopilotChatInPlace', 'type': 'command', 'opts': {'nargs': '*', 'range': ''}}, \ {'sync': v:false, 'name': 'CopilotChatAutocmd', 'type': 'command', 'opts': {'nargs': '*'}}, \ {'sync': v:false, 'name': 'CopilotChatMapping', 'type': 'command', 'opts': {'nargs': '*'}}, @@ -165,6 +183,13 @@ For further reference, you can view @jellydn's [configuration](https://github.co [![Generate tests](https://i.gyazo.com/f285467d4b8d8f8fd36aa777305312ae.gif)](https://gyazo.com/f285467d4b8d8f8fd36aa777305312ae) +### Troubleshoot and Fix Diagnostic + +1. Place your cursor on the line with the diagnostic message. +2. Run the command `:CopilotChatFixDiagnostic`. + +[![Fix diagnostic](https://i.gyazo.com/4aff3fdbc5c3eee59cb68939546fa2be.gif)](https://gyazo.com/4aff3fdbc5c3eee59cb68939546fa2be) + ### Token count & Fold with visual mode 1. Select some code using visual mode. @@ -181,8 +206,35 @@ For further reference, you can view @jellydn's [configuration](https://github.co [![In-place Demo](https://i.gyazo.com/4a5badaa109cd483c1fc23d296325cb0.gif)](https://gyazo.com/4a5badaa109cd483c1fc23d296325cb0) +### Toggle Vertical Split with `:CopilotChatVsplitToggle` + +[![Toggle](https://i.gyazo.com/db5af9e5d88cd2fd09f58968914fa521.gif)](https://gyazo.com/db5af9e5d88cd2fd09f58968914fa521) + ## Tips +### Integration with `edgy.nvim` + +Consider integrating this plugin with [`edgy.nvim`](https://github.com/folke/edgy.nvim). This will allow you to create a chat window on the right side of your screen, occupying 40% of the width, as illustrated below. + +```lua +{ + "folke/edgy.nvim", + event = "VeryLazy", + opts = { + -- Refer to my configuration here https://github.com/jellydn/lazy-nvim-ide/blob/main/lua/plugins/extras/edgy.lua + right = { + { + title = "CopilotChat.nvim", -- Title of the window + ft = "copilot-chat", -- This is custom file type from CopilotChat.nvim + size = { width = 0.4 }, -- Width of the window + }, + }, + }, +} +``` + +[![Layout](https://i.gyazo.com/550daf6cbb729027ca9bd703c21af53e.png)](https://gyazo.com/550daf6cbb729027ca9bd703c21af53e) + ### Debugging with `:messages` and `:CopilotChatDebugInfo` If you encounter any issues, you can run the command `:messages` to inspect the log. You can also run the command `:CopilotChatDebugInfo` to inspect the debug information. @@ -270,11 +322,11 @@ Follow the example below to create a simple input for CopilotChat. local my_prompts = { {prompt = "In Neovim.",desc = "Neovim",key = "n"}, {prompt = "Help with this",desc = "Help",key = "h"}, - {prompt = "Simplify and imporve readablilty",desc = "Simplify",key = "s"}, - {prompt = "Optimize the code to improve perfomance and readablilty.",desc = "Optimize",key = "o"}, + {prompt = "Simplify and improve readablilty",desc = "Simplify",key = "s"}, + {prompt = "Optimize the code to improve performance and readablilty.",desc = "Optimize",key = "o"}, {prompt = "Find possible errors and fix them for me",desc = "Fix",key = "f"}, {prompt = "Explain in detail",desc = "Explain",key = "e"}, - {prompt = "Write a shell scirpt",desc = "Shell",key = "S"}, + {prompt = "Write a shell script",desc = "Shell",key = "S"}, } -- you can change cc to your desired keybind prefix for _,v in pairs(my_prompts) do diff --git a/doc/CopilotChat.txt b/doc/CopilotChat.txt index e6a327ea..2146cc10 100644 --- a/doc/CopilotChat.txt +++ b/doc/CopilotChat.txt @@ -1,4 +1,4 @@ -*CopilotChat.txt* For NVIM v0.8.0 Last change: 2024 February 14 +*CopilotChat.txt* For NVIM v0.8.0 Last change: 2024 February 16 ============================================================================== Table of Contents *CopilotChat-table-of-contents* @@ -29,6 +29,7 @@ PREREQUISITES *CopilotChat-copilot-chat-for-neovim-prerequisites* Ensure you have the following installed: - Python 3.10 or later +- Enable `python3 provider` in Neovim. Testing by run `:echo has('python3')` in Neovim. If it returns `1`, then `python3 provider` is enabled. AUTHENTICATION *CopilotChat-copilot-chat-for-neovim-authentication* @@ -63,6 +64,11 @@ LAZY.NVIM ~ keys = { { "cce", "CopilotChatExplain", desc = "CopilotChat - Explain code" }, { "cct", "CopilotChatTests", desc = "CopilotChat - Generate tests" }, + { + "ccT", + "CopilotChatVsplitToggle", + desc = "CopilotChat - Toggle Vsplit", -- Toggle vertical split + }, { "ccv", ":CopilotChatVisual", @@ -75,6 +81,16 @@ LAZY.NVIM ~ mode = "x", desc = "CopilotChat - Run in-place code", }, + { + "ccf", + "CopilotChatFixDiagnostic", -- Get a fix for the diagnostic message under the cursor. + desc = "CopilotChat - Fix diagnostic", + }, + { + "ccr", + "CopilotChatReset", -- Reset chat history and clear buffer. + desc = "CopilotChat - Reset chat history and clear buffer", + } }, }, } @@ -88,7 +104,9 @@ For example: " python3 plugins call remote#host#RegisterPlugin('python3', '/Users/huynhdung/.local/share/nvim/lazy/CopilotChat.nvim/rplugin/python3/CopilotChat', [ \ {'sync': v:false, 'name': 'CopilotChat', 'type': 'command', 'opts': {'nargs': '1'}}, + \ {'sync': v:false, 'name': 'CopilotChatReset', 'type': 'command', 'opts': {}}, \ {'sync': v:false, 'name': 'CopilotChatVisual', 'type': 'command', 'opts': {'nargs': '1', 'range': ''}}, + \ {'sync': v:false, 'name': 'CopilotChatVsplitToggle', 'type': 'command', 'opts': {}}, \ {'sync': v:false, 'name': 'CopilotChatInPlace', 'type': 'command', 'opts': {'nargs': '*', 'range': ''}}, \ {'sync': v:false, 'name': 'CopilotChatAutocmd', 'type': 'command', 'opts': {'nargs': '*'}}, \ {'sync': v:false, 'name': 'CopilotChatMapping', 'type': 'command', 'opts': {'nargs': '*'}}, @@ -190,6 +208,14 @@ GENERATE TESTS ~ +TROUBLESHOOT AND FIX DIAGNOSTIC ~ + +1. Place your cursor on the line with the diagnostic message. +2. Run the command `:CopilotChatFixDiagnostic`. + + + + TOKEN COUNT & FOLD WITH VISUAL MODE ~ 1. Select some code using visual mode. @@ -208,9 +234,41 @@ IN-PLACE CHAT POPUP ~ +TOGGLE VERTICAL SPLIT WITH :COPILOTCHATVSPLITTOGGLE ~ + + + + TIPS *CopilotChat-copilot-chat-for-neovim-tips* +INTEGRATION WITH EDGY.NVIM ~ + +Consider integrating this plugin with `edgy.nvim` +. This will allow you to create a chat +window on the right side of your screen, occupying 40% of the width, as +illustrated below. + +>lua + { + "folke/edgy.nvim", + event = "VeryLazy", + opts = { + -- Refer to my configuration here https://github.com/jellydn/lazy-nvim-ide/blob/main/lua/plugins/extras/edgy.lua + right = { + { + title = "CopilotChat.nvim", -- Title of the window + ft = "copilot-chat", -- This is custom file type from CopilotChat.nvim + size = { width = 0.4 }, -- Width of the window + }, + }, + }, + } +< + + + + DEBUGGING WITH :MESSAGES AND :COPILOTCHATDEBUGINFO ~ If you encounter any issues, you can run the command `:messages` to inspect the @@ -304,11 +362,11 @@ ADD SAME KEYBINDS IN BOTH VISUAL AND NORMAL MODE ~ local my_prompts = { {prompt = "In Neovim.",desc = "Neovim",key = "n"}, {prompt = "Help with this",desc = "Help",key = "h"}, - {prompt = "Simplify and imporve readablilty",desc = "Simplify",key = "s"}, - {prompt = "Optimize the code to improve perfomance and readablilty.",desc = "Optimize",key = "o"}, + {prompt = "Simplify and improve readablilty",desc = "Simplify",key = "s"}, + {prompt = "Optimize the code to improve performance and readablilty.",desc = "Optimize",key = "o"}, {prompt = "Find possible errors and fix them for me",desc = "Fix",key = "f"}, {prompt = "Explain in detail",desc = "Explain",key = "e"}, - {prompt = "Write a shell scirpt",desc = "Shell",key = "S"}, + {prompt = "Write a shell script",desc = "Shell",key = "S"}, } -- you can change cc to your desired keybind prefix for _,v in pairs(my_prompts) do @@ -365,11 +423,14 @@ STARGAZERS OVER TIME ~ 3. *Chat Demo*: https://i.gyazo.com/10fbd1543380d15551791c1a6dcbcd46.gif 4. *Explain Code Demo*: https://i.gyazo.com/e5031f402536a1a9d6c82b2c38d469e3.gif 5. *Generate tests*: https://i.gyazo.com/f285467d4b8d8f8fd36aa777305312ae.gif -6. *Fold Demo*: https://i.gyazo.com/766fb3b6ffeb697e650fc839882822a8.gif -7. *In-place Demo*: https://i.gyazo.com/4a5badaa109cd483c1fc23d296325cb0.gif -8. *Debug Info*: https://i.gyazo.com/bf00e700bcee1b77bcbf7b516b552521.gif -9. *@ecosse3*: -10. *Stargazers over time*: https://starchart.cc/CopilotC-Nvim/CopilotChat.nvim.svg +6. *Fix diagnostic*: https://i.gyazo.com/4aff3fdbc5c3eee59cb68939546fa2be.gif +7. *Fold Demo*: https://i.gyazo.com/766fb3b6ffeb697e650fc839882822a8.gif +8. *In-place Demo*: https://i.gyazo.com/4a5badaa109cd483c1fc23d296325cb0.gif +9. *Toggle*: https://i.gyazo.com/db5af9e5d88cd2fd09f58968914fa521.gif +10. *Layout*: https://i.gyazo.com/550daf6cbb729027ca9bd703c21af53e.png +11. *Debug Info*: https://i.gyazo.com/bf00e700bcee1b77bcbf7b516b552521.gif +12. *@ecosse3*: +13. *Stargazers over time*: https://starchart.cc/CopilotC-Nvim/CopilotChat.nvim.svg Generated by panvimdoc diff --git a/lua/CopilotChat/init.lua b/lua/CopilotChat/init.lua index 1542e0f9..693769a4 100644 --- a/lua/CopilotChat/init.lua +++ b/lua/CopilotChat/init.lua @@ -33,6 +33,23 @@ M.setup = function(options) end, { nargs = '*', range = true }) end + -- Troubleshoot and fix the diagnostic issue at the current cursor position. + utils.create_cmd('CopilotChatFixDiagnostic', function() + local diagnostic = utils.get_diagnostics() + local file_name = vim.fn.expand('%:t') + local line_number = vim.fn.line('.') + -- Copy all the lines from current buffer to unnamed register + vim.cmd('normal! ggVG"*y') + vim.cmd( + 'CopilotChat Please assist with the following diagnostic issue in file: "' + .. file_name + .. ':' + .. line_number + .. '". ' + .. diagnostic + ) + end, { nargs = '*', range = true }) + -- Show debug info utils.create_cmd('CopilotChatDebugInfo', function() -- Get the log file path diff --git a/lua/CopilotChat/utils.lua b/lua/CopilotChat/utils.lua index 3d83bdc3..98589e52 100644 --- a/lua/CopilotChat/utils.lua +++ b/lua/CopilotChat/utils.lua @@ -52,4 +52,26 @@ M.log_error = function(...) log.error(...) end +--- Get diagnostics for the current line +--- It uses the built-in LSP client in Neovim to get the diagnostics. +--- @return string +M.get_diagnostics = function() + local buffer_number = vim.api.nvim_get_current_buf() + local cursor = vim.api.nvim_win_get_cursor(0) + local line_diagnostics = vim.lsp.diagnostic.get_line_diagnostics(buffer_number, cursor[1] - 1) + + if #line_diagnostics == 0 then + return 'No diagnostics available' + end + + local diagnostics = {} + for _, diagnostic in ipairs(line_diagnostics) do + table.insert(diagnostics, diagnostic.message) + end + + local result = table.concat(diagnostics, '. ') + result = result:gsub('^%s*(.-)%s*$', '%1'):gsub('\n', ' ') + return result +end + return M diff --git a/rplugin/python3/CopilotChat/copilot_plugin.py b/rplugin/python3/CopilotChat/copilot_plugin.py index 5e2708fc..c3b48cce 100644 --- a/rplugin/python3/CopilotChat/copilot_plugin.py +++ b/rplugin/python3/CopilotChat/copilot_plugin.py @@ -18,6 +18,12 @@ def init_vsplit_chat_handler(self): if self.vsplit_chat_handler is None: self.vsplit_chat_handler = VSplitChatHandler(self.nvim) + @pynvim.command("CopilotChatVsplitToggle") + def copilot_chat_toggle_cmd(self): + self.init_vsplit_chat_handler() + if self.vsplit_chat_handler: + self.vsplit_chat_handler.toggle_vsplit() + @pynvim.command("CopilotChat", nargs="1") def copilot_agent_cmd(self, args: list[str]): self.init_vsplit_chat_handler() diff --git a/rplugin/python3/CopilotChat/handlers/vsplit_chat_handler.py b/rplugin/python3/CopilotChat/handlers/vsplit_chat_handler.py index 9cd76a82..70284b61 100644 --- a/rplugin/python3/CopilotChat/handlers/vsplit_chat_handler.py +++ b/rplugin/python3/CopilotChat/handlers/vsplit_chat_handler.py @@ -11,11 +11,12 @@ def __init__(self, nvim: MyNvim): self.buffer: MyBuffer = MyBuffer.new( self.nvim, { - "filetype": "markdown", + "filetype": "copilot-chat", }, ) def vsplit(self): + self.buffer.option("filetype", "copilot-chat") var_key = "copilot_chat" for window in self.nvim.windows: try: @@ -35,7 +36,21 @@ def vsplit(self): ) self.nvim.current.window.vars[var_key] = True + def toggle_vsplit(self): + """Toggle vsplit chat window.""" + var_key = "copilot_chat" + for window in self.nvim.windows: + try: + if window.vars[var_key]: + self.nvim.command("close") + return + except Exception: + pass + + self.vsplit() + def chat(self, prompt: str, filetype: str, code: str = ""): + self.buffer.option("filetype", "markdown") super().chat(prompt, filetype, code, self.nvim.current.window.handle) def reset_buffer(self): diff --git a/version.txt b/version.txt index f0bb29e7..88c5fb89 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -1.3.0 +1.4.0