/nvim-gpt

Integrated ChatGPT + Bing AI in NeoVim just for neo-pioneers like you :)

Primary LanguagePythonMIT LicenseMIT

nvim-gpt

Integrated ChatGPT and Bing AI in NeoVim just for neo-pioneers like you 😇

🤩 Pro tips

You may use :GPTOpen to open the GPT window, as well as :GPTClose and :GPTToggle. In the GPT window press i to start input question, but there are more efficient ways to submit questions and code to GPT.

  1. In normal mode:
  • Press <CR> or :GPT <question> to enter GPT prompt, input your question, and you get the answer in the pop-up GPT window on the right, automatically started in insert mode.
  • Press g<CR> or :GPTWrite <question> to enter GPT prompt, input your requiement description for code (e.g. write a quick sort). The current filetype will be automatically appended for you (e.g. write a quick sort, in cpp), and you get the code in the pop-up GPT window. And after GPT completes their answer you may press 'a' to insert the code directly to where you pressed g<CR>.
  1. In visual mode:
  • Press <CR> or :GPTCode <question> to enter GPT prompt, input the question you want to ask or action you want to do on the code. The code will be appended to the question, and you will get the output code from GPT in the pop-up GPT window.
  1. Utilize the cool vim range expressions:
  • Try :%GPTCode for sending the whole file to GPT.
  • Try :.GPTCode for sending only the current line to GPT.
  • Try :1,.GPTCode for sending from first line to current line to GPT.
  • Try :.,$GPTCode for sending from current line to last line to GPT.
  • Try :-5,+4GPTCode for sending from the previous 5 lines and the next 4 lines to GPT.
  • Try :'<,'>GPTCode for sending the selected (visual mode) lines to GPT.
  1. In the GPT input prompt:
  • You may type 'How to fix this error?' to describe the problem for GPT, press <CR> to submit the question.
  • But we've already got some nice templates for you, you may type @<CR> in either insert mode or normal mode to start looking up templates (thanks to telescope.nvim). Now you may type fixerr, and find How to fix this error? in the HUD, press <CR> and it will be automatically inserted to your question buffer.
  • There is also a useful template Please wrap the final answer with triple quotes, which not only gives us a better syntax highlighting for code, but also make it easier to seperate the real answer from GPT's descriptive text like Sure or Here is the result:.
  • See keymaps.py for a complete list of all templates provided by default, you may override the templates in the setup option question_templates = ....
  • If you want to edit multi-line questions, simply press <Esc> then i to enter insert mode again. Now pressing <CR> in insert mode won't trigger submit anymore, and you may use <CR> or o in normal mode to compose multi-line questions. After finished editing the question, press <CR> in normal mode to submit. The question buffer is remained when you use r to regenerate answer from GPT.
  1. In the GPT window:
  • Suppose you just got the code generated by GPT in the GPT window, now press a to accept their change, and apply it to your previous visual selected code lines (simply replace it).
  • Pressing a will only paste the code into your file, excluding the descriptive texts, when a triple-quoted ``` code block is found.
  • If you dislike the current answer, you may press r to re-edit the question (if needed), then press <CR> again let GPT to regenerate a different solution.
  • Press d to delete all memory of this GPT session, i.e. reset.
  • Press s to stop GPT from generating the complete answer.
  • Press q or <Esc> to close the GPT window and back to where you're editing.
  • Press i to follow up with a new question (equivalent to :GPT).

🌈 Multi-backend support

You may use :GPTModel <model_name> to switch to another model, e.g. :GPTModel creative to switch to the Bing AI - 'creative'. The default model is gpt-3.5-turbo, which can be tweaked in setup options, see below.

If you have telescope.nvim, use :Telescope nvim-gpt gpt_model to show a list of all GPT models to select from.

Currently supported backends are: gpt-3.5-turbo, gpt-4, gpt-4-32k, creative, balanced, percise, google-search.

🤔 Install

It's suggested to use packer.nvim to manage NeoVim plugins, this plugin for example:

use({
    'archibate/nvim-gpt',
    -- optional for supporting ':Telescope nvim-gpt gpt_model/gpt_history/gpt_template' commands
    requires = { 'nvim-telescope/telescope.nvim' },
    config = function()
        require'nvim-gpt'.setup {
            model = 'gpt-3.5-turbo',
            window_width = 45,
            -- see more setup options in section 'Setup options' below
        }
    end,
})

After adding above code to init.lua, restart nvim and run :PackerInstall and :PackerCompile.

Then try run :GPTOpen command and if everything working fine the GPT window should shows up.

If not, try :UpdateRemotePlugins.

Make sure you have Python3 and ran python3 -m pip install neovim

🤖 For ChatGPT users

openai-python is required for using the ChatGPT backend.

pip install openai
  1. Obtain an API key from OpenAI: https://platform.openai.com/account/api-keys

  2. Add this to your ~/.bashrc:

export OPENAI_API_KEY=sk-**********  # replace this with your API key
  1. and then restart your shell, enter nvim and choose gpt-3.5-turbo or gpt-4 as model, which is default.

👻 For Bing AI users

EdgeGPT is required for using the Bing AI backend.

pip install EdgeGPT
  1. Obtain the cookies JSON via Cookie Editor plugin from the Bing site.

  2. Click the 'Export' button on the Cookie editor to dump all the cookies as JSON, then paste all these cookies into a file ~/.bing-cookies.json.

See https://github.com/acheong08/EdgeGPT#getting-authentication-required for more details.

  1. Enter nvim and :GPTModel balanced. For setting Bing AI as default, add model = 'balanced' to setup options. You may also use creative or percise instead.

🤡 For Google users

googlesearch-python is required for using the Google search backend.

pip install googlesearch-python

Then enter nvim and :GPTModel googlesearch-python. Now search current word with gy<CR>, current line with gs<CR>.

⌨️ Keymaps

There are keymaps applied by default when loading this plugin. See nvim-gpt.lua and keymaps.py:

nnoremap <silent> <CR> <Cmd>GPT<CR>
vnoremap <silent> <CR> <Cmd>GPTCode<CR>
nnoremap <silent> g<CR> <Cmd>GPTWrite<CR>
nnoremap <silent> @<CR> <Cmd>Telescope nvim-gpt gpt_template initial_mode=insert<CR>
nnoremap <silent> g@<CR> <Cmd>Telescope nvim-gpt gpt_history<CR>
vnoremap <silent> @<CR> <Cmd>GPTCode<CR><Cmd>Telescope nvim-gpt gpt_template initial_mode=insert<CR>
vnoremap <silent> g@<CR> <Cmd>GPTCode<CR><Cmd>Telescope nvim-gpt gpt_history<CR>
nnoremap <silent> gs<CR> <Cmd>exec ":GPT " . getline('.')<CR>
nnoremap <silent> gy<CR> <Cmd>exec ":GPT " . expand('<cword>')<CR>
nnoremap <silent> gu<CR> <Cmd>%GPTCode<CR>
nnoremap <silent> gsm<CR> <Cmd>Telescope nvim-gpt gpt_model<CR>

Can be disabled by no_default_keymaps = true option in setup.

😎 GPT window keymaps

Apart from universal keymaps above, inside the GPT window, which is not modifiable, also have their own keymaps:

" (i)nput (a)ccept (c)opy (r)egenerate (d)iscard e(x)ecute (s)top (q)uit
nnoremap <buffer><silent> i <Cmd>GPT<CR>
nnoremap <buffer><silent> a <Cmd>GPTAccept<CR>
nnoremap <buffer><silent> A <Cmd>GPTAccept!<CR>
nnoremap <buffer><silent> c <Cmd>GPTYank<CR>
nnoremap <buffer><nowait><silent> C <Cmd>GPTYank!<CR>
nnoremap <buffer><nowait><silent> r <Cmd>GPTRegenerate!<CR>
nnoremap <buffer><silent> dd <Cmd>GPTDiscard<CR>
nnoremap <buffer><silent> x <Cmd>GPTExecute<CR>
nnoremap <buffer><silent> s <Cmd>GPTStop<CR>
nnoremap <buffer><silent> q <Cmd>wincmd q<CR>
nnoremap <buffer><silent> <Esc> <Cmd>wincmd q<CR>

😍 Question editing buffer keymaps

nnoremap <buffer><silent> <CR> <Cmd>GPTQuestion<CR>
vnoremap <buffer><silent> <CR> <Cmd><C-u>GPTQuestion<CR>
inoremap <buffer><silent> @<CR> <Cmd>Telescope nvim-gpt gpt_template initial_mode=insert<CR>
inoremap <buffer><silent> g<CR> <Cmd>Telescope nvim-gpt gpt_history<CR>
snoremap <buffer><silent> @<CR> <Cmd>Telescope nvim-gpt gpt_template initial_mode=insert<CR>
snoremap <buffer><silent> g<CR> <Cmd>Telescope nvim-gpt gpt_history<CR>
inoremap <expr><buffer><silent> <CR> (!exists('b:_no_enter_submit') ? '<Esc><Cmd>GPTQuestion<CR>' : '<CR>')
snoremap <expr><buffer><silent> <CR> (!exists('b:_no_enter_submit') ? '<Esc><Cmd>GPTQuestion<CR>' : '<CR>')
inoremap <buffer><silent> <Esc> <Esc><Cmd>let b:_no_enter_submit = 1<CR>
snoremap <buffer><silent> <Esc> <Esc><Cmd>let b:_no_enter_submit = 1<CR>
nnoremap <buffer><silent> q <Cmd>wincmd q<CR>
nnoremap <buffer><silent> <Esc> <Cmd>wincmd q<CR>

🧐 All setup options

require'nvim-gpt'.setup {
    -- which backend to use: 'gpt-3.5-turbo', 'gpt-4', 'gpt-4-32k', 'creative', 'balanced', 'percise', 'google-search'
    model = 'gpt-3.5-turbo',
    -- may provide specific parameters like temperature depends on models
    params = {
        ['gpt-3.5-turbo'] = {
            -- see https://platform.openai.com/docs/api-reference/chat/create
            temperature = 0.85,
            top_p = 1,
            n = 1,
            presence_penalty = 0,
            frequency_penalty = 0,
        },
        ['gpt-4'] = {
            -- same as above
        },
        ['gpt-4-32k'] = {
            -- same as above
        },
        ['google-search'] = {
            -- see https://pypi.org/project/googlesearch-python
            num_results = 10,
            sleep_interval = 0,
            timeout = 5,
            lang = 'en',
            format = '# {title}\n{url}\n\n{desc}',
        },
    },
    -- '|/_\\' = rotating loading symbol, '_ ' = blinking on and off, '' = disable
    cursors = '|/_\\',
    -- this is how we quote code when :'<,'>GPTCode
    code_quote = '{question}\n```{filetype}\n{code}\n```',
    -- this is how we quote language type when :GPTWrite
    in_language = '{question}\n(in {filetype})',
    -- title indicating human question in GPT window
    question_title = '\n🙂:',
    -- title indicating bot answer in GPT window
    answer_title = '\n🤖:',
    -- marker use when human requests to regenerate
    regenerate_title = '🔄',
    -- whether to show bot's welcome messages on start up: 'fancy', '🤖 {}', 'none'
    welcome_messages = '🤖 {}',
    -- GPT window width
    window_width = 45,
    -- GPT window specific options
    window_options = {
        wrap = true,
        list = false,
        cursorline = true,
        number = false,
        relativenumber = false,
    },
    -- whether we lock to last line when answer: none, last-char, last-line, force
    lock_last_line = 'force',
    -- GPT window update interval (ms) when streaming the answer
    update_interval = 180,
    -- automatically add default keymaps (see 'Keymaps' section below)
    no_default_keymaps = false,
    -- preset templates, can be used like @p or @plain in :GPT or :GPTCode
    question_templates = [[
Note that you shall only output the plain answer, with no additional text like 'Sure' or 'Here is the result'.
Please wrap the final answer with triple quotes like ```answer```.
The answer is wrong, please try again.
Write a test for this code.
Write an documentation or API reference for this code.
Could you find any possible BUGs in this code?
Write a benchmark for this code. You may want to use the Google Benchmark as framework.
Rewrite to simplify this.
Edit the code to fix the problem.
How to fix this error?
Explain the purpose of this code, step by step.
Rename the variable and function names to make them more readable.
Rewrite to make this code more readable and maintainable.
This line is too long and complex. Could you split it for readability?
Please reduce duplication by following the Don't Repeat Yourself principle.
Complete the missing part of code with given context.
Implement the function based on its calling signature.
Here is a markdown file that have several links in the format [name](link), please fill the links according to given name. You may want to search the web if you are not sure about the link.
Make this expression longer and fullfilling.
Let's think step by step.
Could you verify this?
You may want to search the web.
Since the output length is limited. Please omit the unchanged part with ellipses. Only output the changed or newly-added part.
Please provide multiple different versions of answer for reference.
Fix possible grammar issues or typos in my writing.
Rewrite with better choices of words.
Translate from Chinese to English, or English to Chinese.
]],
}

Found bugs or any suggestions? Please let me know by opening a GitHub issue, I'm glad to help 😘