Inline Completions
User Flow
- User is editing code in Neovim
- User presses their configured keybind (e.g.,
<C-Space>) - Ghost text appears inline at cursor, streaming token-by-token
- User accepts (inserts text), accepts line (inserts first line only), or dismisses
Plugin Interface
lua
-- All keybinds are user-configured. No defaults.
-- Example setup:
require('bonk').setup({
server = {
-- path to server directory (auto-detected from plugin install path)
path = nil,
},
completion = {
model = 'claude-opus-4-6',
context_budget = 32768,
max_tokens = 512, -- max completion length
},
})
-- Functions exposed for keybinding:
require('bonk').complete() -- trigger completion
require('bonk').accept() -- accept full ghost text
require('bonk').accept_line() -- accept first line only
require('bonk').dismiss() -- clear ghost text
require('bonk').cancel() -- cancel in-flight requestAPI: POST /complete
Request
json
{
"token": "auth-uuid",
"client_id": "nvim-12345",
"file_path": "/absolute/path/to/file.ts",
"filetype": "typescript",
"buffer_content": "function fibonacci(n: number): number {\n if (n <= 1) return n;\n \n}",
"cursor": {
"line": 2,
"col": 2
},
"context": {
"open_buffers": [
{ "path": "/absolute/path/to/utils.ts", "content": "..." }
],
"recent_edits": [
{ "path": "/absolute/path/to/file.ts", "diff": "@@ -1,3 +1,4 @@..." }
]
},
"options": {
"model": "claude-opus-4-6",
"max_tokens": 512,
"context_budget": 32768
}
}Response (SSE Stream)
event: token
data: {"text": "return"}
event: token
data: {"text": " fibonacci(n - 1)"}
event: token
data: {"text": " + fibonacci(n - 2);"}
event: done
data: {"full_text": "return fibonacci(n - 1) + fibonacci(n - 2);", "model": "claude-opus-4-6", "usage": {"input_tokens": 1234, "output_tokens": 25}}
event: error
data: {"message": "Agent SDK error: ...", "code": "SDK_ERROR"}Ghost Text Rendering
Ghost text is rendered using Neovim extmarks (nvim_buf_set_extmark) within a dedicated namespace.
First line of completion:
virt_text_pos = 'inline'virt_text =
Subsequent lines:
virt_lines = { }
Highlight: BonkGhost is linked to Comment by default. Users can override it in their colorscheme.
Behavior:
- Only one active completion at a time
- New trigger cancels any in-flight request and clears existing ghost text
- Ghost text is cleared on any buffer change (
InsertLeave,TextChangedI,CursorMovedI) - Accept inserts the text and clears the extmark
Completion Agent
typescript
const completionAgent = {
model: 'claude-opus-4-6',
instructions: `You are a code completion engine. Given a file with a cursor position marked by <|CURSOR|>, output ONLY the code that should be inserted at that position.
Rules:
- Output raw code only. No markdown fences. No explanations.
- Match the surrounding style, indentation, and conventions.
- Complete the logical unit: finish the statement, block, or function.
- If the cursor is mid-line, complete the rest of the line and any following lines that logically belong.
- Stop when the completion is naturally complete. Do not over-generate.
- Use context from other files and recent edits to inform your completion.`,
// No tools -- pure completion, minimal overhead
}