NeoAI is a Neovim plugin that brings the power of OpenAI's GPT-4 directly to your editor. It helps you generate code, rewrite text, and even get suggestions in-context with your code. The plugin is built with a user-friendly interface, making it easy to interact with the AI and get the assistance you need.
Note: This plugin is in early it's early changes and is subject to change.
To install NeoAI, you can use your favorite plugin manager. For example,
with vim-plug, add the following line to your init.vim
or .vimrc
, note that
it also requires the nui dependency
and curl installed on the system:
Plug 'MunifTanjim/nui.nvim'
Plug 'Bryley/neoai.nvim'
Then run :PlugInstall
to install the plugins.
For lazy.nvim:
return {
"Bryley/neoai.nvim",
dependencies = {
"MunifTanjim/nui.nvim",
},
cmd = {
"NeoAI",
"NeoAIOpen",
"NeoAIClose",
"NeoAIToggle",
"NeoAIContext",
"NeoAIContextOpen",
"NeoAIContextClose",
"NeoAIInject",
"NeoAIInjectCode",
"NeoAIInjectContext",
"NeoAIInjectContextCode",
},
keys = {
{ "<leader>as", desc = "summarize text" },
{ "<leader>ag", desc = "generate git message" },
},
config = function()
require("neoai").setup({
-- Options go here
})
end,
}
To use this plugin make sure you have an OpenAI API key which can be created
here. Save this key in your
environment variables as OPENAI_API_KEY
.
IMPORTANT NOTE : This plugin is not responsible for unintentional purchases made to OpenAI. While using this plugin I would recommend you frequently check the usage of your account and setup limits, so you don't spend more that you can afford.
This plugin introduces 3 modes or ways to interact with the AI models.
In the default mode, a GUI opens up on the side using the :NeoAI
command,
allowing you to chat with the model. This operation is similar to what you
get when using it in a browser, but now it's made more convenient by the GUI
being inside your editor.
In the Prompt Buffer, you can send text by pressing Enter while in insert mode. Additionally, you can insert a newline by using Control Enter.
Also note that the plugin has a feature where the output from the model
automatically gets saved to the g
register and all code snippets get saved to
the c
register. These can be changed in the config.
The Context mode works similarly to the Normal mode. However, you have the
ability to provide additional information about what you want to change. For
instance, if you are reading someone else's code and need a description of what
it does, you can highlight the code in the buffer via the visual mode. Then,
you can run :NeoAIContext
and type something like "Please explain this code
for me" in the prompt buffer.
Additionally, you can highlight some text and request "Fix up the punctuation and grammar in this text" to obtain a better version of the text.
Note that if you run the command without any selection then the whole buffer is passed in.
The final mode is known as "inject mode" by using :NeoAIInject
. This mode
operates without the graphical user interface, allowing you to quickly send a
prompt to the model and have the resulting output automatically inserted below
your cursor. All of this can be done without opening the GUI. Additionally,
there is a sub-mode within Inject mode that can be executed with context.
One feature of this plugin is creating shortcuts, which are explained below.
The plugin includes two built-in shortcuts; the first one reformats selected
text to improve readability, with the default key bind being <leader>as
(A
for AI and S for summarize).
The other built-in shortcut is auto generating git commit messages for you:
Caution: Be aware that overusing this feature might lead to an accumulation of data sent to the model, which can result in high costs. To avoid this, it is recommended that smaller commits be made or the feature be used less frequently. It is imperative to keep track of your usage, which can be monitored through this link
To set up the plugin, add the following to your init.vim
or .vimrc
(or put
under the config
option if using lazy.nvim:
lua << EOF
require('neoai').setup{
-- Below are the default options, feel free to override what you would like changed
ui = {
output_popup_text = "NeoAI",
input_popup_text = "Prompt",
width = 30, -- As percentage eg. 30%
output_popup_height = 80, -- As percentage eg. 80%
},
models = {
{
name = "openai",
model = "gpt-3.5-turbo"
},
},
register_output = {
["g"] = function(output)
return output
end,
["c"] = require("neoai.utils").extract_code_snippets,
},
inject = {
cutoff_width = 75,
},
prompts = {
context_prompt = function(context)
return "Hey, I'd like to provide some context for future "
.. "messages. Here is the code/text that I want to refer "
.. "to in our upcoming conversations:\n\n"
.. context
end,
},
open_api_key_env = "OPENAI_API_KEY",
shortcuts = {
{
key = "<leader>as",
use_context = true,
prompt = [[
Please rewrite the text to make it more readable, clear,
concise, and fix any grammatical, punctuation, or spelling
errors
]],
modes = { "v" },
strip_function = nil,
},
{
key = "<leader>ag",
use_context = false,
prompt = function ()
return [[
Using the following git diff generate a consise and
clear git commit message, with a short title summary
that is 75 characters or less:
]] .. vim.fn.system("git diff --cached")
end,
modes = { "n" },
strip_function = nil,
},
},
}
EOF
The setup function accepts a table of options to configure the plugin. The available options are as follows:
output_popup_text
: Header text shown on the output popup window (default: "NeoAI").input_popup_text
: Header text shown on the input popup window (default: "Prompt").width
: Width of the window as a percentage (e.g., 30 = 30%, default: 30).output_popup_height
: Height of the output popup as a percentage (e.g., 80 = 80%, default: 80).
models
: A list of models to use:name
: The name of the model provider (eg. "openai")model
: Either a string of the model name to use or a list of model names
register_output
: A table with a register as the key and a function that takes the raw output from the AI and outputs what you want to save into that register. Example:
register_output = {
["g"] = function(output)
return output
end,
["c"] = require("neoai.utils").extract_code_snippets,
}
cutoff_width
: When injecting, if the text becomes longer than this value, it should go to a new line. If set to nil, the length is ignored (default: 75).
context_prompt
: A function that generates the prompt to be used when using Context modes. Example:
context_prompt = function(context)
return "Hi ChatGPT, I'd like to provide some context for future "
.. "messages. Here is the code/text that I want to refer "
.. "to in our upcoming conversations:\n\n"
.. context
end
open_api_key_env
: The environment variable that contains the OpenAI API key (default: "OPENAI_API_KEY").
shortcuts
: An array of shortcuts. Each shortcut is a table containing:key
: The keybind value to listen for.use_context
: If the context from the selection/buffer should be used.prompt
: The prompt to send or a function to generate the prompt to send.modes
: A list of modes to set the keybind up for "n" for normal, "v" for visual.strip_function
: The strip function to use (optional).
Smart toggles the NeoAI window. If the window is closed, it will open and send the optional [prompt]. If the window is open and focused, it will close, finally if the window is open but not focused, it will focus the window and send the optional [prompt].
Toggles the NeoAI window. If the window is closed, it will open and send the optional [prompt]. If the window is open, it will close.
Opens the NeoAI window and sends the optional [prompt].
Closes the NeoAI window.
Smart toggles the NeoAI window with context. If the window is closed, it will open and send the optional [prompt]. If the window is open and focused, it will close, finally if the window is open but not focused, it will focus the window and send the optional [prompt]. The context used for this command is the visually selected text or the entire buffer if no selection is made.
Opens the NeoAI window with context and sends the optional [prompt]. The context used for this command is the visually selected text or the entire buffer if no selection is made.
Closes the NeoAI window with context.
Sends the [prompt] to the AI and directly injects the AI response into the buffer without opening the NeoAI window.
Sends the [prompt] to the AI and directly injects the AI response into the buffer without opening the NeoAI window. The response will be stripped of everything except code snippets.
Sends the [prompt] to the AI with context and directly injects the AI response into the buffer without opening the NeoAI window. The context used for this command is the visually selected text or the entire buffer if no selection is made.
Sends the [prompt] to the AI with context and directly injects the AI response into the buffer without opening the NeoAI window. The response will be stripped of everything except code snippets. The context used for this command is the visually selected text or the entire buffer if no selection is made.
- Issue 1
- Add description option for shortcuts
- Have ability to have shortcuts be run via user command instead
- Tests
- Switching Models
- Better Colours (eg. highlighting user input)
- Highlight context when inside NeoAIContext buffer or make context clear
- Keymap for replacing context with newly generated code
- Better error detection
- Back and forth conversations
- Context using visual mode
- Fix when using :q on NeoAI GUI
- Config
- Add custom keybinds for context related issues
- Join undos of inject
- Inject fix mark sometimes not set inject mode.
- Inject strip output for code or other.
- Make sure to match end of file as well and use for inject mode
- Context using buffer
- Strip code from output and put in buffer
- Add setup config
- Better way to focus on GUI window
Licensed under the MIT License. Check the LICENSE file for details.