Nvim ChatGPT Using AI inside of Vim

A guide and tutorial on how to start using ChatGPT from directly inside of nvim

February 9, 2023 | 4 minute read

Introduction

This post will guide you through setting up and getting started with jackMort/ChatGPT.nvim, a plugin for working with OpenAI’s GPT model from directly inside of NeoVim. In addition to GitHub Copilot and Warp, this is one of the best ways I’ve found to leverage OpenAI when coding.

Setup

To get started, you need to install and setup the GPT plugin. I use Packer and keep all my plugins listed inside of a file called plugins.lua. Here’s the snippet for installing the GPT plugin and it’s dependencies:

use {
   'jackMort/ChatGPT.nvim',
   requires = {
   'MunifTanjim/nui.nvim',
   'nvim-lua/plenary.nvim',
   'nvim-telescope/telescope.nvim',
   },
}

Configuration

Once we have the plugin installed, we need to configure it. I’m still learning and playing around with this plugin, so I’ve kept most of the defaults:

-- https://github.com/jackMort/ChatGPT.nvim#configuration
local chatgpt = require('chatgpt')

chatgpt.setup({
  welcome_message = 'Welcome to ChatGPT.nvim',
  max_line_length = 500,
})

I have a separate file for each plugin I want to configure. This is my plugin/chatgpt.lua file. I also like to put in a link to the configuration documentation at the top of each of these files.

In this file, I’ve imported the chatgpt plugin and called the .setup() function. The only two defaults that I’m changing here are the welcome_message and the max_line_length. The plugin comes with a really large welcome message with an ASCII robot. I find this annoying, so I’ve replaced it with a simple line of text. The default prompt length is also really short and I’ve had better success with longer prompt messages, so I set the default to be a bit higher (500, in this case).

Usage

This plugin exposes three commands:

  1. ChatGPT
  2. ChatGPTActAs
  3. ChatGPTEditWithInstructions

I’ve mapped these to the following custom keymaps:

-- A keymap to open the basic chat window
vim.keymap.set('n', '<Leader>ee', ':ChatGPT<CR>', { noremap = true, desc = 'ChatGPT' })
-- A keymap to open the Act As chat window
vim.keymap.set('n', '<Leader>ea', ':ChatGPTActAs<CR>', { noremap = true, desc = 'ChatGPTActAs' })
-- A keymap to open the instruction-based chat window
vim.keymap.set('n', '<Leader>ep', ':ChatGPTEditWithInstructions<CR>',
  { noremap = true, desc = 'ChatGPTEditWithInstructions' })

I want to use <Leader>e as the base command for all of these. There used to be a great Mac app called Command-E that gave you direct access to every file across all your file sources (the file system, Google Drive, Notion, etc), so that command feels really natural. I have <Leader>ee set for the general ChatGPT command, <Leader>ea for the ActAs command, and <Leader>ep for the EditWithInstructions command.

Guide

I’ve been using the plugin for a week now in my normal coding practice. I’ve used it for writing, editing, and documenting code. I’ve also used it in my Slipbox practice of taking notes and writing articles like this. In that time, I’ve found the ChatGPTEditWithInstructions command to be the most helpful. I’ve also discovered some good tricks for how to use it.

I’ve primarily used the plugin alongside GitHub Copilot, which I have set up in NeoVim. This ChatGPT plugin is very complementary. Copilot works great for line-by-line coding. This plugin works well for making larger changes to a section of code, be that refactoring or documenting.

For example: if I’m writing a smart contract, I might use Copilot to get the main idea for a particular method out onto the screen and for writing tests. If I need to go back through and refactor a section of the code by changing the name of a variable, I can use the ChatGPTEditWithInstructions command I have mapped to <Leader>ep.

The ChatGPTEditWithInstructions command opens the code in a window where you can interact with ChatGPT, using a snippet or the whole file as context. So, if I want to document a function, I can select it in Visual mode and open it in the EditWithInstructions screen and give ChatGPT a prompt like: "Add inline comments". It will take a second to run and if I like the results, I can hit <C-i> to accept them as context for the next prompt or <C-y> to write back to the original file.

The plugin can be used for generating a rough sketch of code, but it generally only works for generating short pieces of code and if you give it really specific instructions. I’ve found the most it can do is a single function at a time, which then will require some editing.

Conclusion

The plugin is still underactive development and is still a little rough around the edges. Some things I would love to see added are:

  • A way to pass a range in Visual mode into ChatGPTEditWithInstructions
  • A way to modify the model settings from a ChatGPT window
  • Better display of the pricing of a session (how much a prompt will cost to run and how much you’ve racked up in a session so far)
  • An easier way of passing in longer prompts (which tend to yield better results).
  • An easy way to save custom prompts to the ChatGPTActAs list
  • A way to map ActAs or other custom prompts directly to a key mapping (i.e. create a custom keymap to document selected code in Visual mode)

At the moment, this is the best plugin I’ve seen for working with GPT directly inside of NeoVim. I hope more developers start building these kinds of plugins and that we see more experimentation around the form factor of these integrations.