Skip to content

CopilotC-Nvim/CopilotChat.nvim

Folders and files

NameName
Last commit message
Last commit date

Latest commit

39647f5 · Mar 1, 2024
Feb 27, 2024
Feb 27, 2024
Mar 1, 2024
Feb 28, 2024
Dec 23, 2023
Feb 26, 2024
Feb 2, 2024
Dec 12, 2023
Feb 2, 2024
Feb 24, 2024
Feb 23, 2024
Dec 23, 2023
Feb 24, 2024
Dec 12, 2023
Mar 1, 2024
Feb 2, 2024
Mar 1, 2024
Feb 29, 2024
Feb 2, 2024
Feb 2, 2024
Feb 2, 2024
Feb 18, 2024
Feb 24, 2024

Repository files navigation

Copilot Chat for Neovim

Prerequisite Documentation pre-commit.ci status

All Contributors

Note

Plugin was rewritten to Lua from Python. Please check the migration guide for more information.

Prerequisites

Ensure you have the following installed:

  • Neovim stable (0.9.5) or nightly.

Installation

Lazy.nvim

return {
  {
    "CopilotC-Nvim/CopilotChat.nvim",
    branch = "canary",
    dependencies = {
      { "zbirenbaum/copilot.lua" }, -- or github/copilot.vim
      { "nvim-lua/plenary.nvim" }, -- for curl, log wrapper
      { "nvim-telescope/telescope.nvim" }, -- for telescope help actions (optional)
    },
    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

Vim-Plug

Similar to the lazy setup, you can use the following configuration:

call plug#begin()
Plug 'zbirenbaum/copilot.lua'
Plug 'nvim-lua/plenary.nvim'
Plug 'nvim-telescope/telescope.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/start

git clone https://github.com/zbirenbaum/copilot.lua
git clone https://github.com/nvim-lua/plenary.nvim
git clone https://github.com/nvim-telescope/telescope.nvim

git clone -b canary https://github.com/CopilotC-Nvim/CopilotChat.nvim
  1. Add to you configuration
require("CopilotChat").setup {
  debug = true, -- Enable debugging
  -- See Configuration section for rest
}

See @deathbeam for configuration

Usage

API

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()

-- 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,
})

Commands

  • :CopilotChat <input>? - Open chat window with optional input
  • :CopilotChatOpen - Open chat window
  • :CopilotChatClose - Close chat window
  • :CopilotChatToggle - Toggle chat window
  • :CopilotChatReset - Reset chat window
  • :CopilotChatDebugInfo - Show debug information

Commands coming from default prompts

  • :CopilotChatExplain - Explain how it works
  • :CopilotChatTests - Briefly explain how selected code works then generate unit tests
  • :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

Configuration

For further reference, you can view @jellydn's configuration.

Default configuration

Also see here:

{
  system_prompt = prompts.COPILOT_INSTRUCTIONS, -- System prompt to use
  model = 'gpt-4', -- GPT model to use
  temperature = 0.1, -- GPT temperature
  debug = false, -- Enable debug logging
  show_user_selection = true, -- Shows user selection in chat
  show_system_prompt = false, -- Shows system prompt in chat
  show_folds = true, -- Shows folds for sections in chat
  clear_chat_on_new_prompt = false, -- Clears chat on every new prompt
  auto_follow_cursor = true, -- Auto-follow cursor in chat
  name = 'CopilotChat', -- Name to use in chat
  separator = '---', -- Separator to use in chat
  -- default prompts
  prompts = {
    Explain = {
      prompt = 'Explain how it works.',
    },
    Tests = {
      prompt = 'Briefly explain how selected code works then generate unit tests.',
    },
    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()
        return select.gitdiff(true)
      end,
    },
  },
  -- default selection (visual or line)
  selection = function()
    return select.visual() or select.line()
  end,
  -- default window options
  window = {
    layout = 'vertical', -- 'vertical', 'horizontal', 'float'
    relative = 'editor', -- 'editor', 'win', 'cursor', 'mouse'
    border = 'single', -- 'none', single', 'double', 'rounded', 'solid', 'shadow'
    width = 0.8, -- fractional width of parent
    height = 0.6, -- fractional height of parent
    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
  },
  -- default mappings
  mappings = {
    close = 'q',
    reset = '<C-l>',
    complete_after_slash = '<Tab>',
    submit_prompt = '<CR>',
    accept_diff = '<C-y>',
    show_diff = '<C-d>',
  },
}

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 <leader>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.

{
  prompts = {
    MyCustomPrompt = {
      prompt = 'Explain how it works.',
      mapping = '<leader>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.

{
  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.

{
  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.',
    },
  },
}

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:

-- lazy.nvim keys

  -- Quick chat with Copilot
  {
    "<leader>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

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.

-- lazy.nvim opts

  {
    window = {
      layout = 'float',
      relative = 'cursor',
      width = 1,
      height = 0.4,
      row = 1
    }
  }

inline-chat

Roadmap (Wishlist)

  • Use vector encodings to automatically select code
  • Treesitter integration for function definitions
  • General QOL improvements

Development

Installing Pre-commit Tool

For development, you can use the provided Makefile command to install the pre-commit tool:

make install-pre-commit

This will install the pre-commit tool and the pre-commit hooks.

Contributors ✨

Thanks goes to these wonderful people (emoji key):

gptlang
gptlang

💻 📖
Dung Duc Huynh (Kaka)
Dung Duc Huynh (Kaka)

💻 📖
Ahmed Haracic
Ahmed Haracic

💻
Trí Thiện Nguyễn
Trí Thiện Nguyễn

💻
He Zhizhou
He Zhizhou

💻
Guruprakash Rajakkannu
Guruprakash Rajakkannu

💻
kristofka
kristofka

💻
PostCyberPunk
PostCyberPunk

📖
Katsuhiko Nishimra
Katsuhiko Nishimra

💻
Erno Hopearuoho
Erno Hopearuoho

💻
Shaun Garwood
Shaun Garwood

💻
neutrinoA4
neutrinoA4

💻 📖
Jack Muratore
Jack Muratore

💻
Adriel Velazquez
Adriel Velazquez

💻 📖
Tomas Slusny
Tomas Slusny

💻 📖
Nisal
Nisal

📖

This project follows the all-contributors specification. Contributions of any kind are welcome!

Stargazers over time

Stargazers over time