Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/CopilotC-Nvim/CopilotChat.nvim
Chat with GitHub Copilot in Neovim
https://github.com/CopilotC-Nvim/CopilotChat.nvim
copilot copilot-chat github github-copilot neovim-plugin
Last synced: about 2 months ago
JSON representation
Chat with GitHub Copilot in Neovim
- Host: GitHub
- URL: https://github.com/CopilotC-Nvim/CopilotChat.nvim
- Owner: CopilotC-Nvim
- License: gpl-3.0
- Created: 2023-12-12T00:59:30.000Z (9 months ago)
- Default Branch: canary
- Last Pushed: 2024-07-31T12:48:19.000Z (about 2 months ago)
- Last Synced: 2024-07-31T16:03:29.019Z (about 2 months ago)
- Topics: copilot, copilot-chat, github, github-copilot, neovim-plugin
- Language: Lua
- Homepage: https://copilotc-nvim.github.io/CopilotChat.nvim/
- Size: 688 KB
- Stars: 1,336
- Watchers: 14
- Forks: 65
- Open Issues: 13
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- Funding: .github/FUNDING.yml
- License: LICENSE
Awesome Lists containing this project
- awesome-neovim - CopilotC-Nvim/CopilotChat.nvim - A chat interface for GitHub Copilot that allows you to directly ask and receive answers to coding-related questions. (AI / (requires Neovim 0.5))
- my-awesome-starred - CopilotC-Nvim/CopilotChat.nvim - Chat with GitHub Copilot in Neovim (Lua)
README
# Copilot Chat for Neovim
[![Documentation](https://img.shields.io/badge/documentation-yes-brightgreen.svg)](https://copilotc-nvim.github.io/CopilotChat.nvim/)
[![pre-commit.ci](https://results.pre-commit.ci/badge/github/CopilotC-Nvim/CopilotChat.nvim/main.svg)](https://results.pre-commit.ci/latest/github/CopilotC-Nvim/CopilotChat.nvim/main)
[![Discord](https://img.shields.io/discord/1200633211236122665.svg)](https://discord.gg/vy6hJsTWaZ)[![All Contributors](https://img.shields.io/badge/all_contributors-30-orange.svg?style=flat-square)](#contributors-)
> [!NOTE]
> Plugin was rewritten to Lua from Python. Please check the [migration guide from version 1 to version 2](/MIGRATION.md) for more information.## Prerequisites
Ensure you have the following installed:
- **Neovim stable (0.9.5) or nightly**.
Optional:
- tiktoken_core: `sudo luarocks install --lua-version 5.1 tiktoken_core`. Alternatively, download a pre-built binary from [lua-tiktoken releases](https://github.com/gptlang/lua-tiktoken/releases)
- You can check your Lua PATH in Neovim by doing `:lua print(package.cpath)`. Save the binary as `tiktoken_core.so` in any of the given paths.> For Arch Linux user, you can install [`luajit-tiktoken-bin`](https://aur.archlinux.org/packages/luajit-tiktoken-bin) or [`lua51-tiktoken-bin`](https://aur.archlinux.org/packages/lua51-tiktoken-bin) from aur!
## Installation
### Lazy.nvim
```lua
return {
{
"CopilotC-Nvim/CopilotChat.nvim",
branch = "canary",
dependencies = {
{ "zbirenbaum/copilot.lua" }, -- or github/copilot.vim
{ "nvim-lua/plenary.nvim" }, -- for curl, log wrapper
},
opts = {
debug = true, -- Enable debugging
-- See Configuration section for rest
},
-- See Commands section for default commands if you want to lazy load on them
},
}
```See @jellydn for [configuration](https://github.com/jellydn/lazy-nvim-ide/blob/main/lua/plugins/extras/copilot-chat-v2.lua)
### Vim-Plug
Similar to the lazy setup, you can use the following configuration:
```vim
call plug#begin()
Plug 'zbirenbaum/copilot.lua'
Plug 'nvim-lua/plenary.nvim'
Plug 'CopilotC-Nvim/CopilotChat.nvim', { 'branch': 'canary' }
call plug#end()lua << EOF
require("CopilotChat").setup {
debug = true, -- Enable debugging
-- See Configuration section for rest
}
EOF
```### Manual
1. Put the files in the right place
```
mkdir -p ~/.config/nvim/pack/copilotchat/start
cd ~/.config/nvim/pack/copilotchat/startgit clone https://github.com/zbirenbaum/copilot.lua
git clone https://github.com/nvim-lua/plenary.nvimgit clone -b canary https://github.com/CopilotC-Nvim/CopilotChat.nvim
```2. Add to your configuration (e.g. `~/.config/nvim/init.lua`)
```lua
require("CopilotChat").setup {
debug = true, -- Enable debugging
-- See Configuration section for rest
}
```See @deathbeam for [configuration](https://github.com/deathbeam/dotfiles/blob/master/nvim/.config/nvim/lua/config/copilot.lua#L14)
## Usage
### Commands
- `:CopilotChat ?` - Open chat window with optional input
- `:CopilotChatOpen` - Open chat window
- `:CopilotChatClose` - Close chat window
- `:CopilotChatToggle` - Toggle chat window
- `:CopilotChatStop` - Stop current copilot output
- `:CopilotChatReset` - Reset chat window
- `:CopilotChatSave ?` - Save chat history to file
- `:CopilotChatLoad ?` - Load chat history from file
- `:CopilotChatDebugInfo` - Show debug information
- `:CopilotChatModels` - View and select available models. This is reset when a new instance is made. Please set your model in `init.lua` for persistence.#### Commands coming from default prompts
- `:CopilotChatExplain` - Write an explanation for the active selection as paragraphs of text
- `:CopilotChatReview` - Review the selected code
- `:CopilotChatFix` - There is a problem in this code. Rewrite the code to show it with the bug fixed
- `:CopilotChatOptimize` - Optimize the selected code to improve performance and readablilty
- `:CopilotChatDocs` - Please add documentation comment for the selection
- `:CopilotChatTests` - Please generate tests for my code
- `:CopilotChatFixDiagnostic` - Please assist with the following diagnostic issue in file
- `:CopilotChatCommit` - Write commit message for the change with commitizen convention
- `:CopilotChatCommitStaged` - Write commit message for the change with commitizen convention### API
```lua
local chat = require("CopilotChat")-- Open chat window
chat.open()-- Open chat window with custom options
chat.open({
window = {
layout = 'float',
title = 'My Title',
},
})-- Close chat window
chat.close()-- Toggle chat window
chat.toggle()-- Toggle chat window with custom options
chat.toggle({
window = {
layout = 'float',
title = 'My Title',
},
})-- Reset chat window
chat.reset()-- Ask a question
chat.ask("Explain how it works.")-- Ask a question with custom options
chat.ask("Explain how it works.", {
selection = require("CopilotChat.select").buffer,
})-- Ask a question and do something with the response
chat.ask("Show me something interesting", {
callback = function(response)
print("Response:", response)
end,
})-- Get all available prompts (can be used for integrations like fzf/telescope)
local prompts = chat.prompts()-- Get last copilot response (also can be used for integrations and custom keymaps)
local response = chat.response()-- Pick a prompt using vim.ui.select
local actions = require("CopilotChat.actions")-- Pick help actions
actions.pick(actions.help_actions())-- Pick prompt actions
actions.pick(actions.prompt_actions({
selection = require("CopilotChat.select").visual,
}))
```## Configuration
### Default configuration
Also see [here](/lua/CopilotChat/config.lua):
```lua
{
debug = false, -- Enable debug logging
proxy = nil, -- [protocol://]host[:port] Use this proxy
allow_insecure = false, -- Allow insecure server connectionssystem_prompt = prompts.COPILOT_INSTRUCTIONS, -- System prompt to use
model = 'gpt-4o', -- GPT model to use, 'gpt-3.5-turbo', 'gpt-4', or 'gpt-4o'
temperature = 0.1, -- GPT temperaturequestion_header = '## User ', -- Header to use for user questions
answer_header = '## Copilot ', -- Header to use for AI answers
error_header = '## Error ', -- Header to use for errors
separator = 'βββ', -- Separator to use in chatshow_folds = true, -- Shows folds for sections in chat
show_help = true, -- Shows help message as virtual lines when waiting for user input
auto_follow_cursor = true, -- Auto-follow cursor in chat
auto_insert_mode = false, -- Automatically enter insert mode when opening window and if auto follow cursor is enabled on new prompt
clear_chat_on_new_prompt = false, -- Clears chat on every new prompt
highlight_selection = true, -- Highlight selection in the source buffer when in the chat windowcontext = nil, -- Default context to use, 'buffers', 'buffer' or none (can be specified manually in prompt via @).
history_path = vim.fn.stdpath('data') .. '/copilotchat_history', -- Default path to stored history
callback = nil, -- Callback to use when ask response is received-- default selection (visual or line)
selection = function(source)
return select.visual(source) or select.line(source)
end,-- default prompts
prompts = {
Explain = {
prompt = '/COPILOT_EXPLAIN Write an explanation for the active selection as paragraphs of text.',
},
Review = {
prompt = '/COPILOT_REVIEW Review the selected code.',
callback = function(response, source)
-- see config.lua for implementation
end,
},
Fix = {
prompt = '/COPILOT_GENERATE There is a problem in this code. Rewrite the code to show it with the bug fixed.',
},
Optimize = {
prompt = '/COPILOT_GENERATE Optimize the selected code to improve performance and readablilty.',
},
Docs = {
prompt = '/COPILOT_GENERATE Please add documentation comment for the selection.',
},
Tests = {
prompt = '/COPILOT_GENERATE Please generate tests for my code.',
},
FixDiagnostic = {
prompt = 'Please assist with the following diagnostic issue in file:',
selection = select.diagnostics,
},
Commit = {
prompt = 'Write commit message for the change with commitizen convention. Make sure the title has maximum 50 characters and message is wrapped at 72 characters. Wrap the whole message in code block with language gitcommit.',
selection = select.gitdiff,
},
CommitStaged = {
prompt = 'Write commit message for the change with commitizen convention. Make sure the title has maximum 50 characters and message is wrapped at 72 characters. Wrap the whole message in code block with language gitcommit.',
selection = function(source)
return select.gitdiff(source, true)
end,
},
},-- default window options
window = {
layout = 'vertical', -- 'vertical', 'horizontal', 'float', 'replace'
width = 0.5, -- fractional width of parent, or absolute width in columns when > 1
height = 0.5, -- fractional height of parent, or absolute height in rows when > 1
-- Options below only apply to floating windows
relative = 'editor', -- 'editor', 'win', 'cursor', 'mouse'
border = 'single', -- 'none', single', 'double', 'rounded', 'solid', 'shadow'
row = nil, -- row position of the window, default is centered
col = nil, -- column position of the window, default is centered
title = 'Copilot Chat', -- title of chat window
footer = nil, -- footer of chat window
zindex = 1, -- determines if window is on top or below other floating windows
},-- default mappings
mappings = {
complete = {
detail = 'Use @ or / for options.',
insert ='',
},
close = {
normal = 'q',
insert = ''
},
reset = {
normal ='',
insert = ''
},
submit_prompt = {
normal = '',
insert = ''
},
accept_diff = {
normal = '',
insert = ''
},
yank_diff = {
normal = 'gy',
},
show_diff = {
normal = 'gd'
},
show_system_prompt = {
normal = 'gp'
},
show_user_selection = {
normal = 'gs'
},
},
}
```For further reference, you can view @jellydn's [configuration](https://github.com/jellydn/lazy-nvim-ide/blob/main/lua/plugins/extras/copilot-chat-v2.lua).
### Defining a prompt with command and keymap
This will define prompt that you can reference with `/MyCustomPrompt` in chat, call with `:CopilotChatMyCustomPrompt` or use the keymap `ccmc`.
It will use visual selection as default selection. If you are using `lazy.nvim` and are already lazy loading based on `Commands` make sure to include the prompt
commands and keymaps in `cmd` and `keys` respectively.```lua
{
prompts = {
MyCustomPrompt = {
prompt = 'Explain how it works.',
mapping = 'ccmc',
description = 'My custom prompt description',
selection = require('CopilotChat.select').visual,
},
},
}
```### Referencing system or user prompts
You can reference system or user prompts in your configuration or in chat with `/PROMPT_NAME` slash notation.
For collection of default `COPILOT_` (system) and `USER_` (user) prompts, see [here](/lua/CopilotChat/prompts.lua).```lua
{
prompts = {
MyCustomPrompt = {
prompt = '/COPILOT_EXPLAIN Explain how it works.',
},
MyCustomPrompt2 = {
prompt = '/MyCustomPrompt Include some additional context.',
},
},
}
```### Custom system prompts
You can define custom system prompts by using `system_prompt` property when passing config around.
```lua
{
system_prompt = 'Your name is Github Copilot and you are a AI assistant for developers.',
prompts = {
MyCustomPromptWithCustomSystemPrompt = {
system_prompt = 'Your name is Johny Microsoft and you are not an AI assistant for developers.',
prompt = 'Explain how it works.',
},
},
}
```### Customizing buffers
You can set local options for the buffers that are created by this plugin: `copilot-diff`, `copilot-system-prompt`, `copilot-user-selection`, `copilot-chat`.
```lua
vim.api.nvim_create_autocmd('BufEnter', {
pattern = 'copilot-*',
callback = function()
vim.opt_local.relativenumber = true-- C-p to print last response
vim.keymap.set('n', '', function()
print(require("CopilotChat").response())
end, { buffer = true, remap = true })
end
})
```## Tips
Quick chat with your buffer
To chat with Copilot using the entire content of the buffer, you can add the following configuration to your keymap:
```lua
-- lazy.nvim keys-- Quick chat with Copilot
{
"ccq",
function()
local input = vim.fn.input("Quick Chat: ")
if input ~= "" then
require("CopilotChat").ask(input, { selection = require("CopilotChat.select").buffer })
end
end,
desc = "CopilotChat - Quick chat",
}
```[![Chat with buffer](https://i.gyazo.com/9b8cbf1d78a19f326282a6520bc9aab0.gif)](https://gyazo.com/9b8cbf1d78a19f326282a6520bc9aab0)
Inline chat
Change the window layout to `float` and position relative to cursor to make the window look like inline chat.
This will allow you to chat with Copilot without opening a new window.```lua
-- lazy.nvim opts{
window = {
layout = 'float',
relative = 'cursor',
width = 1,
height = 0.4,
row = 1
}
}
```![inline-chat](https://github.com/CopilotC-Nvim/CopilotChat.nvim/assets/5115805/608e3c9b-8569-408d-a5d1-2213325fc93c)
Telescope integration
Requires [telescope.nvim](https://github.com/nvim-telescope/telescope.nvim) plugin to be installed.
```lua
-- lazy.nvim keys-- Show help actions with telescope
{
"cch",
function()
local actions = require("CopilotChat.actions")
require("CopilotChat.integrations.telescope").pick(actions.help_actions())
end,
desc = "CopilotChat - Help actions",
},
-- Show prompts actions with telescope
{
"ccp",
function()
local actions = require("CopilotChat.actions")
require("CopilotChat.integrations.telescope").pick(actions.prompt_actions())
end,
desc = "CopilotChat - Prompt actions",
},
```![image](https://github.com/CopilotC-Nvim/CopilotChat.nvim/assets/5115805/14360883-7535-4ee3-aca1-79f6c39f626b)
fzf-lua integration
Requires [fzf-lua](https://github.com/ibhagwan/fzf-lua) plugin to be installed.
```lua
-- lazy.nvim keys-- Show help actions with fzf-lua
{
"cch",
function()
local actions = require("CopilotChat.actions")
require("CopilotChat.integrations.fzflua").pick(actions.help_actions())
end,
desc = "CopilotChat - Help actions",
},
-- Show prompts actions with fzf-lua
{
"ccp",
function()
local actions = require("CopilotChat.actions")
require("CopilotChat.integrations.fzflua").pick(actions.prompt_actions())
end,
desc = "CopilotChat - Prompt actions",
},
```![image](https://github.com/CopilotC-Nvim/CopilotChat.nvim/assets/5115805/743455bb-9517-48a8-a7a1-81215dc3b747)
nvim-cmp integration
Requires [nvim-cmp](https://github.com/hrsh7th/nvim-cmp) plugin to be installed (and properly configured).
```lua
-- Registers copilot-chat source and enables it for copilot-chat filetype (so copilot chat window)
require("CopilotChat.integrations.cmp").setup()-- You might also want to disable default complete mapping for copilot chat when doing this
require('CopilotChat').setup({
mappings = {
complete = {
insert = '',
},
},
-- rest of your config
})
```![image](https://github.com/CopilotC-Nvim/CopilotChat.nvim/assets/5115805/063fc99f-a4b2-4187-a065-0fdd287ebee2)
## Roadmap (Wishlist)
- Use indexed vector database with current workspace for better context selection
- General QOL improvements## Development
### Installing Pre-commit Tool
For development, you can use the provided Makefile command to install the pre-commit tool:
```bash
make install-pre-commit
```This will install the pre-commit tool and the pre-commit hooks.
## Contributors β¨
If you want to contribute to this project, please read the [CONTRIBUTING.md](/CONTRIBUTING.md) file.
Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
gptlang
π» π
Dung Duc Huynh (Kaka)
π» π
Ahmed Haracic
π»
TrΓ Thiα»n Nguyα» n
π»
He Zhizhou
π»
Guruprakash Rajakkannu
π»
kristofka
π»
PostCyberPunk
π
Katsuhiko Nishimra
π»
Erno Hopearuoho
π»
Shaun Garwood
π»
neutrinoA4
π» π
Jack Muratore
π»
Adriel Velazquez
π» π
Tomas Slusny
π» π
Nisal
π
Tobias GΓ₯rdhus
π
Petr DlouhΓ½
π
Dylan Madisetti
π»
Aaron Weisberg
π» π
Jose Tlacuilo
π» π
Kevin Traver
π» π
dTry
π»
Arata Furukawa
π»
Ling
π»
Ivan Frolov
π»
Folke Lemaitre
π» π
GitMurf
π»
Dmitrii Lipin
π»
jinzhongjia
π
This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind are welcome!
### Stargazers over time
[![Stargazers over time](https://starchart.cc/CopilotC-Nvim/CopilotChat.nvim.svg)](https://starchart.cc/CopilotC-Nvim/CopilotChat.nvim)