š¤SimpleGPT is a Vim plugin designed to provide a simple (high transparency based on Jinja) yet flexible way (context-aware based on buffer, visual selection, LSP info, terminal etc.) to customize your LLM/ChatGPT prompts for your tasks (finishing tasks by replacing them with diff comparison, appending, SEARCH/REPLACE etc.) on nearly all kinds of LLM APIs.
- Why š¤SimpleGPT: You need customized LLM/ChatGPT prompts for your tasks.
- AI Coding Plugins didn't provide support for every scenario.
- General tasks beyond coding:
- Article writing.
- Reading, notetaking, summarizing.
- Translating.
- General tasks beyond coding:
- Even for specific tasks that AI Coding supports, using a customized prompt and workflow is often more effective and smooth.
- AI Coding Plugins didn't provide support for every scenario.
š¤SimpleGPT's efforts can be categorized into the following parts:
- Prompt Templates: Create your own prompt templates using a Jinja template engine. Details
- Context-aware Question Building: Construct questions based on the template and the current context, followed by multi-round chat instruction.
- Flexible Response Presenting: Present the response in the most convenient way (we provide options like diff, popup, replace, append).
This allows you to easily build a LLM-based toolbox with š¤SimpleGPT.
We provide a tools gallery for basic usage, which also serves as examples for further customization.
Tool | Config | Demo |
---|---|---|
Grammar fixing | conf.lua | |
Text Rewriting | conf.lua | |
Code completing | conf.lua | Demo |
Code Explanation | conf.lua | |
Bug Fixing | conf.lua | |
Translation with great formatting | conf.lua | Demo |
Dictionary with customized explanation | conf.lua | Demo |
Reading | My Config | |
Terminal with LLM supported | Config | Demo |
Code editing with LSP information | Config | Demo |
Code editing with terminal context | Config | Demo |
More tools are coming soon.
Our project aims to make customizing your LLM/ChatGPT prompts straightforward by using the yetone/avante.nvim as the backend API, ensuring we don't reinvent the wheel while supporting diverse models.
You can use :AvanteAsk
to start a chat and verify if it is working.
-- Lazy.nvim
{
"you-n-g/simplegpt.nvim",
dependencies = {
{
"yetone/avante.nvim", -- You should configure your avante.nvim make sure it works.
event = "VeryLazy",
opts = {<your config>},
dependencies = {
"MunifTanjim/nui.nvim",
"nvim-lua/plenary.nvim",
},
},
"you-n-g/jinja-engine.nvim",
"ibhagwan/fzf-lua",
},
config = true,
},
-- or packer.nvim
use({
"you-n-g/simplegpt.nvim",
config = function()
require("simplegpt").setup()
end,
requires = {
{
"yetone/avante.nvim", -- You should configure your avante.nvim make sure it works.
event = "VimEnter",
config = function()
require("avante").setup({<your config>})
end,
requires = {
"MunifTanjim/nui.nvim",
"nvim-lua/plenary.nvim",
},
},
"you-n-g/jinja-engine.nvim",
"ibhagwan/fzf-lua",
},
})
If you want to customize you <LocalLeader>
, please use following code:
vim.g.maplocalleader = "\\" -- change the localleader key to \
More detailed configuration are listed here. You can find my latest and preferred configuration here as an example.
- Press
<localleader>st
in a terminal buffer to open the LLM dialog. - Enter your request or command.
- Edit the suggestion to keep only what you want.
- Press
<c-a>
to add the chosen command to the terminal.
- Select the code you want to fix.
- Press
<localleader>sl
to use the code editing feature and address LSP warnings or errors. - Press
<c-r>
to replace the selected text with the suggested fix.
- Run
ls
andpython <your script>
to gather live feedback from the terminal. - Press
<localleader>sF
to use the code editing feature and fix errors detected in the terminal output. - Press
<m-r>
to apply search and replace actions to quickly update your code based on the suggestions.
I have attempted to summarize the key concepts and manual in one image.
The question is constructed by rendering a template. The 't' register serves as the template, encompassing:
- Special variables such as
{{content}}
,{{filetype}}
, and{{visual}}
. - Standard registers like
{{a}}
,{{b}}
, and{{c}}
.
Here is a gif demo that quickly showcases the customization process.
You can specify a custom template path for loading and dumping files by setting the custom_template_path
option in your configuration. If the specified path does not exist, it will be created automatically.
Example configuration:
require("simplegpt").setup({
custom_template_path = "~/my_custom_templates/"
})
When you set a custom_template_path:
- If a template is specified and it exists in the custom path, it will be loaded from and saved to that path.
- If the template file doesn't exist in the custom path, a new file will be created there when you save the registers.
-
Create a Template File: Navigate to your custom template path and create a
.json
file. -
Define Template Structure: Add your template with placeholders:
{ "t": "I am working on a {{filetype}} file. The content is: {{content}}. Selected lines: {{visual}}. Question: {{q}}." }
-
Save: Save the file in
custom_template_path
.
-
Set the 't' Register: In Vim, set the 't' register:
" setting it with command :let @t = "I am working on a {{filetype}} file. The content is: {{content}}. Selected lines: {{visual}}. Question: {{q}}." " or use `"ty` to copy the content to the 't' register
-
Dump the Register: Use the shortcut to dump the 't' register:
:<LocalLeader>gD
You can register custom shortcuts to use templates from the custom template path. Here is an example of how to configure custom shortcuts:
require("simplegpt").setup({
custom_template_path = "~/my_custom_templates/",
keymaps = {
custom_shortcuts = {
["<LocalLeader>sQ"] = {
mode = { "n", "v" },
tpl = "my_custom_template.json",
target = "popup",
opts = { noremap = true, silent = true, desc = "Use custom template" },
},
},
},
})
In this example, pressing <LocalLeader>sQ
in normal or visual mode will load the my_custom_template.json
from the custom template path and send it to the popup target.
The primary concepts that govern the functionality of this plugin are:
-
Register-based, template-driven question construction: This approach allows for the dynamic creation of questions by leveraging the power of Vim registers. The registers serve as placeholders within the template, which are then replaced with the appropriate content during the question construction process.
-
Dumping and loading of registers: This feature enables the preservation of register content across different sessions. It's important to note that temporary registers, denoted by
{{p-}}
, are exempt from this process and their content is not saved to disk. -
Response display targets: This refers to the destination where the response from ChatGPT is displayed. The plugin offers flexibility in choosing the target, allowing for a more tailored user experience.
To illustrate the core template rendering mechanism of SimpleGPT, consider the following example. We have a template in the 't' register:
"I am currently working on a {{filetype}} file. The content of the file is: {{content}}. I have selected the following lines: {{visual}}. My question is: {{q}}."
The register values are:
{{filetype}}
is 'markdown'{{content}}
is 'This is a sample markdown file.'{{visual}}
is 'This is a selected.'{{q}}
is 'How can I improve this line?'
The constructed question becomes:
"I am currently working on a markdown file. The content of the file is: This is a sample markdown file. I have selected the following lines: This is a selected line. My question is: How can I improve this line?"
Registers are of two types:
- Native vim registers: Standard Vim registers like 't', 'a', 'b', 'c', etc. used for storing and retrieving text.
- Special registers: Specific to SimpleGPT, including
{{content}}
,{{filetype}}
,{{visual}}
, and{{q}}
. They store special values used in the template process. The{{q}}
register allows for an editable question when rendering the whole content.
Register | meaning |
---|---|
t | The register for the template. |
others | the variables to render the template |
You can use these variables in your jinja template.
key | meaning |
---|---|
content | Content around the cursor, limited by a configurable length |
full_content | Entire content of the current file |
filetype | Filetype of the current buffer |
visual | Lines selected in visual mode |
context | Context around the cursor, configurable lines up/down |
all_buf | Content from all loaded buffers with files on disk |
lsp_diag | LSP diagnostics information for the selected lines |
md_context | Directly loading the content in .sgpt.md as the register value. |
filename | The name of the current file |
terminal | The content from the active (visiable) terminal buffer, capturing recent terminal output (if available) |
p | If register p contains a list of file paths (one per line), its value becomes the concatenation of the content from each of those files. Files that do not exist will be skipped. |
SimpleGPT uses a Jinja-like template engine (jinja-engine.nvim) to power its template system:
-
Variable Interpolation: Access registers using
{{register_name}}
syntax{ "t": "I am working on a {{filetype}} file. The content is: {{content}}. Selected lines: {{visual}}. Question: {{q}}." }
-
Control Structures: Use Jinja-style control flow
{% if visual %}Selected: {{visual}}{% else %}No selection{% endif %}
The template engine provides familiar Jinja-style syntax while being fully integrated with Neovim.
After receiving a response from ChatGPT, you can perform several actions to integrate the output into your workflow:
- Append: Use the Append action (e.g.,
<C-a>
key) to add the response to your original buffer. - Replace: Use the Replace action (e.g.,
<C-r>
key) to substitute the selected text, current line, or entire file with the response. - Yank: Use the Yank action (e.g.,
<C-y>
key) to copy the response to the clipboard. - Search and Replace: Use the Search and Replace action (e.g.,
<m-r>
key) to apply automated modifications via SEARCH/REPLACE blocks. - Chat/Continue: Use the Chat action (e.g.,
<m-c>
key) to continue the conversation or refine the response.
- Dialog shortcuts:
- For all dialogs
{"q", "<C-c>", "<esc>"}
: Exit the dialog{"<C-k>"}
: Extract code block closest to cursor{"<C-j>"}
: Cycle to next window{"<C-h>"}
: Cycle to previous window{"<C-s>"}
: Save registers (for template editing only)K
: Show special value for placeholder under cursor (for template editing only)
- For
ChatDialog
(The dialog that can get responses){"<C-a>"}
: Append response to original buffer after selection/current line{"<C-y>"}
: Copy full response to clipboard{"<C-r>"}
: Replace selected text/current line with response{"<m-c>"}
: Instruction Editing:- Continue conversation with current context
- Opens input prompt for follow-up questions
- New response replaces current response
{"<m-r>"}
: Apply search and replace blocks to modify code based on the response
- For all dialogs
- Normal shortcuts start with
<LocalLeader>g
(You can change it by settingkeymaps.prefix
when you setup the plugin)- Register operations:
<LocalLeader>gl
: load registers<LocalLeader>gD
: dump registers<LocalLeader>ge
: edit registers
- Send to target:
<LocalLeader>gs
: send question to clipboard<LocalLeader>gc
: send question to ChatGPT<LocalLeader>gr
: send to get direct response<LocalLeader>gd
: send to get response with diff
- Other operations:
<LocalLeader>gR
: toggle the dialog.<LocalLeader>gp
: load current file to reg<LocalLeader>gP
: append current file to reg
- Register operations:
- Shortcuts for combined actions: Loading template + send to target
- By default, they start with
<LocalLeader>s
(You can change it by settingkeymaps.shortcuts.prefix
when you setup the plugin) - Full list of shortcuts
<LocalLeader>sr
: (R)ewrite Text in Diff Mode.<LocalLeader>sC
: (C)omplete Code in Popup (with explanations).<LocalLeader>sc
: (C)omplete Code in Diff Mode (no explanation).<LocalLeader>sl
: Fix code using LSP diagnostics.<LocalLeader>sg
: (G)rammar Fix.<LocalLeader>sd
: (D)ense for condensing text.<LocalLeader>st
: (T)hread or Continue conversation.<LocalLeader>se
: (E)xplain Code or Text.<LocalLeader>sF
: (F)ix code with error messages.<LocalLeader>sE
: (E)xplain Text with Translation.<LocalLeader>sT
: (T)ranslate text.<LocalLeader>sq
: (Q)uestion with content.<LocalLeader>sf
: Edit Entire (F)ile in Diff Mode.<LocalLeader>s<m-f>
: Send current file for file edit via search/replace blocks.<LocalLeader>sD
: (D)ictionary lookup.
- By default, they start with
An example to change the shortcuts prefix in lazy.nvim:
{
"you-n-g/simplegpt.nvim",
--- ... other configurations
opts = {
keymaps = {
shortcuts = {
prefix = "<m-g>",
},
prefix = "<m-g><m-g>",
},
},
--- ... other configurations
}
Welcome to contribute to this project.
You can test the plugin with minimal config with
vim -u tests/init_configs/lazy.lua -U NONE -N -i NONE
for lazy.nvim- For packer.nvim
- Please install packer.nvim first.
- Run
vim -u tests/init_configs/packer.lua -U NONE -N -i NONE
- It only leverage the
ChatCompletion
API (which is the most powerful and frequently used in the future trend). - It is based on Vim registers, which may conflict with users' usage of them.