An open API service indexing awesome lists of open source software.

https://github.com/nathom/delphi.nvim

A simple LLM plugin for Neovim
https://github.com/nathom/delphi.nvim

llms neovim

Last synced: 8 months ago
JSON representation

A simple LLM plugin for Neovim

Awesome Lists containing this project

README

          

delphi.nvim


Pythia

Priestess of Delphi, 1891
John Collier

## Features

- Clean and snappy Vim buffer based chat interface
- Local storage for chat history, with optional [Telescope](https://github.com/nvim-telescope/telescope.nvim) integration
- Code rewrite and insert-at-cursor with live diff preview
- Zero startup time cost (with lazy.nvim)
- Pure Lua OpenAI client and diff algorithm

## Setup

You'll need a plugin manager (such as [lazy](https://github.com/folke/lazy.nvim)), and an OpenAI compatible
LLM API (such as [OpenRouter](https://openrouter.ai)). If you want the chat history picker, install Telescope and load the extension.

Example configuration with lazy.nvim:

```lua
{
"nathom/delphi.nvim",
keys = {
{ "", "(DelphiChatSend)", desc = "Delphi: send chat" },
{ "", "(DelphiRewriteSelection)", mode = { "x", "s" }, desc = "Delphi: rewrite selection" },
{ "", "(DelphiInsertAtCursor)", mode = { "n", "i" }, desc = "Delphi: insert at cursor" },
{ "a", "(DelphiRewriteAccept)", desc = "Delphi: accept rewrite" },
{ "R", "(DelphiRewriteReject)", desc = "Delphi: reject rewrite" },
},
cmd = { "Chat", "Rewrite" },
opts = {
chat = { default_model = "gemini_flash", scroll_on_send = true },
rewrite = { default_model = "gemini_flash" },
models = {
gemini_flash = {
base_url = "https://openrouter.ai/api/v1",
api_key_env_var = "OPENROUTER_API_KEY",
model_name = "google/gemini-2.5-flash",
},
},
},
dependencies = { "nvim-lua/plenary.nvim", "nvim-telescope/telescope.nvim" },
}
```

In this case, delphi will expect your OpenRouter API keys under the environment variable `OPENROUTER_API_KEY`.

## Usage

### Chat

Type `:Chat` to open up a chat buffer. If one is already open
in your Neovim instance, it will switch to that buffer. If you want to create a new chat regardless, use `:Chat new`.

Example blank chat buffer:

```md
---
model: kimi_k2
temperature: 0.7
---

System:

User:

```

To send a message to the model, type text below `User:`, switch to normal mode, and trigger `(DelphiChatSend)`.

```md
---
model: kimi_k2
temperature: 0.7
---

System:

User:
Is it worth switching to Neovim?
```

You should see the model's response being streamed in live.

```md
---
model: kimi_k2
temperature: 0.7
---

System:

User:
Is it worth switching to Neovim?

Assistant:
Short answer
If you already know Vim and are happy with it, you probably don’t *need* to switch—but if you enjoy experimenting,
want modern features without waiting for Bram to merge them, or are starting from scratch, Neovim is almost always the better choice today.

Below is a practical “decision matrix” so you can decide whether the switch is worth the one-time migration cost for *you*.
...
```

The system prompt can usually be left empty, as the provider will set a reasonable one for you.

#### Chat history

You have two options:

- Use `:Telescope delphi chats` (after loading the extension)
- Run `:Chat list` to view the ids and titles of chats, and `:Chat go ` to open them

### Rewrite

This command allows the LLM to rewrite a selected block of code or insert at the cursor.
It displays a live diff preview as tokens stream in.

To use it

- open a buffer with some text
- highlight a few lines in Visual Lines mode (shift-V)
- press `` (or use `(DelphiRewriteSelection)`) to open the prompt
- instruct the model, hit `ENTER`
- accept or reject the changes via `(DelphiRewriteAccept)` or `(DelphiRewriteReject)`

Insert at cursor

- from Normal or Insert mode, press `` (or use `(DelphiInsertAtCursor)`) to insert at the current line
- the diff preview shows only additions; accepting applies the generated lines at the cursor line
- press `` inside the prompt popup to cancel (mapping is local to the popup only)

### Configuration

Configuration schema:

```lua
---@class Model
---@field base_url string
---@field api_key_env_var string
---@field model_name string
---@field temperature number

---@class Config
---@field models table
---@field allow_env_var_config boolean
---@field chat { system_prompt: string, default_model: string?, headers: { system: string, user: string, assistant: string }, scroll_on_send: boolean }
---@field rewrite { default_model: string? }
```

Default options:

```lua
opts = {
models = {},
allow_env_var_config = false,
chat = {
system_prompt = "",
default_model = nil,
headers = {
system = "System:",
user = "User:",
assistant = "Assistant:",
},
scroll_on_send = true,
},
rewrite = {
default_model = nil,
},
}
```