Quill
OpenCode prompt autocomplete: local n-gram word and next-word prediction shown as inline ghost text in the TUI composer, accepted with Tab.
1
1,212
近 7 天 161
41.4
生态多维模型
13 小时前
2026-10-20
快速安装与配置
opencode.json写入当前项目的 opencode.json,只对这个仓库生效。
opencode.json
{
"$schema": "https://opencode.ai/config.json",
"plugin": ["opencode-quill@0.3.1"]
}写入 ~/.config/opencode/opencode.json,对所有项目生效。
~/.config/opencode/opencode.json
{
"$schema": "https://opencode.ai/config.json",
"plugin": ["opencode-quill@0.3.1"]
}若你要在本地改造这个插件,先装到项目里再从本地路径引用。
shell
pnpm add -D opencode-quillOpenCode 启动时会通过内嵌运行时自动加载 npm 依赖并缓存至本地目录,无需手动在全局环境执行安装。
Local word autocomplete and next-word prediction for the OpenCode V2 prompt composer — inspired by oh-my-pi (OMP)'s n-gram text prediction engine.
As you type, Quill predicts the remainder of your current prose word or the next word in sequence, shown as dimmed inline ghost text directly at your cursor. Press Tab or → to accept it, or Esc to dismiss.
What it does
- Zero AI, completely local: Runs entirely on-device without sending prompt text to any model, API, or external service.
- Context-aware ranking: Blends a common-English vocabulary prior with an online n-gram model (bigrams and trigrams) learned from your prompt history.
- Completes words, fixes typos, and predicts next words: Completes the active prose prefix, offers single-edit corrections, and predicts following words when learned evidence supports the sequence.
- Ghost-text styling: Matches opencode-ghost's dimmed appearance (the theme's muted text color), rendered in the OpenTUI buffer without displacing the cursor.
- Safe acceptance: Inserts or corrects the active word in the draft without submitting. Supports native undo (Ctrl+- or Cmd+Z). Never overwrites unrelated draft text and never touches the system clipboard.
- Coexists with Ghost: Ghost suggests entire next prompts in an empty composer using a model; Quill predicts words in an active draft locally. When both are installed, each activates only in its respective domain without key conflicts.
- Prose-aware gating: Automatically suppresses suggestions in code blocks, backticks, file paths, URLs, slash commands, shell executions, active selections, composers holding attachments or pasted-text chips, and modal dialogs.
- End-of-draft only: Suggestions appear when the cursor is at the end of the draft, either on a partial word or after a space.
What suggestions look like
The suggestion appears dimmed at the end of the draft. It is not part of the editable text until you press Tab or →.
| Kind | Your draft | Dimmed suggestion | Draft after acceptance |
|---|---|---|---|
| Word completion | please comp |
lete |
please complete |
| Typo correction | please cmplete |
→ complete |
please complete |
| Next word | please run |
tests |
please run tests |
A correction looks like this, with only → complete dimmed:
> please cmplete → complete
- Completions append the missing letters or next word.
- Corrections replace only the active word, preserving its initial-capital
or all-uppercase casing (
Cmplete→Complete,CMPLETE→COMPLETE). First-person contractions use a capitalIin corrections and next-word suggestions (I'm,I'll,I've,I'd). Lowercase contraction prefixes are replaced on acceptance too (i'v→I've). - Learned casing is kept. A word you usually capitalize mid-sentence is
suggested that way:
ozshows→ Ozanand replaces the word, whileOzcompletes withan. - Normal completions take precedence. For example,
whatecompletes towhateverrather than being corrected towhat. Typo correction is a fallback when no confident prefix completion is available; recognized words are not corrected. - Earlier words are never rewritten. With learned evidence for
please run tests, typingplease rnucan suggesttests. Accepting it producesplease rnu tests, leavingrnuunchanged.
Requirements
- OpenCode with the V2 TUI plugin runtime (the supported
range is
engines.opencodeinpackage.json). - Node.js (for the installer script).
Install
From npm (recommended)
Add the package to plugins in ~/.config/opencode/cli.json:
{
"$schema": "https://opencode.ai/v2/cli.json",
"plugins": [
"opencode-quill"
]
}
OpenCode installs the package and its dependencies on the next start.
From this repository
git clone https://github.com/ozandogrultan/opencode-quill.git
cd opencode-quill
bun install
./install.sh
Restart OpenCode to load it. install.sh copies the plugin and its local
vocabulary into <config>/plugins/opencode-quill/ and registers that directory
in <config>/cli.json. Unrelated plugins and configuration are preserved.
To target a specific configuration directory:
./install.sh /path/to/config/opencode
Manually
Add the plugin directory to plugins in ~/.config/opencode/cli.json:
{
"$schema": "https://opencode.ai/v2/cli.json",
"plugins": [
"/absolute/path/to/opencode-quill/src"
]
}
To pass custom options:
{
"$schema": "https://opencode.ai/v2/cli.json",
"plugins": [
{
"package": "/absolute/path/to/opencode-quill/src",
"options": {
"enabled": true,
"acceptKeys": ["tab", "right"],
"dismissKeys": ["escape"]
}
}
]
}
Restart OpenCode after editing cli.json.
Options
| Option | Type | Default | Description |
|---|---|---|---|
enabled |
boolean |
true |
Enables or disables suggestions; can also be toggled with /quill. |
acceptKeys |
string[] |
["tab", "right"] |
Keys that accept and insert the active word suggestion. |
dismissKeys |
string[] |
["escape"] |
Keys that dismiss the visible suggestion without inserting. |
Custom keybindings can also be overridden using OpenCode's standard
keybinds map in cli.json:
{
"keybinds": {
"quill.accept": "ctrl+y",
"quill.dismiss": "ctrl+g"
}
}
Commands
/quill— Toggle word autocomplete on or off (persisted across sessions)./quill on//quill off— Set autocomplete explicitly./quill clear(alias/quill reset) — Erase everything Quill has learned from your prompts.- Command Palette (
Ctrl+P) — Includes Word autocomplete: on/off and Clear word autocomplete history.
How it works
Learning
Quill learns from your own submitted prompts, never from assistant output:
- It listens to session events (
session.execution.started,session.execution.succeeded,session.inbox.delivered). - On startup and when you open a session, it also backfills from the user messages of the current and most recently updated sessions.
- Each message is ingested once, tracked by
<sessionID>:<messageID>. - Only prose is learned. Code blocks, inline code, URLs, file paths, identifiers, slash commands, shell lines, indented blocks and very large pastes are ignored.
- Punctuation, line breaks and code reset the context, so words separated by syntax are never learned as adjacent.
- A word missing from the base vocabulary becomes suggestible only after it
has been seen more than once, and not while it is a prefix of a learned word
you use at least as often (
addryields toaddressed). - Casing is learned from words written mid-sentence; sentence-initial capitals are ignored.
Prediction
- Baseline prior: a bundled English word-frequency table (SUBTLEX) gives useful completions from the first keystroke.
- Personal model: unigram, bigram and trigram counts from your prompts. Context evidence falls back from trigram to bigram to unigram as it thins out.
- Current draft: words already in the draft get a small boost.
- Confidence gating: a suggestion is shown only when it clears a confidence threshold, which is stricter for next-word predictions than for prefix completions. If the typed prefix is already the most likely word, nothing is shown.
- Typo fallback: when prefix completion is not confident enough, nearby
words are ranked with an edit penalty and a stricter confidence threshold.
Correction confidence is the edit-penalized model score. Suggestions must
clear an absolute evidence floor and a separate candidate-dominance check.
Corrections require at least three typed letters. Short words are eligible
only for whole-word letter swaps that preserve the first letter; other edits
and mistyped longer prefixes require at least five letters, except for
apostrophe contractions, including missing apostrophes. Deletions repair only
doubled letters, not arbitrary extra characters or word endings.
Unknown tokens such as
json,yaml,bool,opts, andenumare left unchanged, and uncertain typos such asfucncan produce no suggestion. Context repair uses the same edit guards and confidence checks and requires repeated learned continuation evidence; not every typo produces a suggestion. - Bounded size: the personal model is pruned to its most frequent entries when saved. Once it holds about 100,000 learned words, every count is halved and single-use entries are dropped, so recent habits outweigh old ones.
Storage
Quill uses OpenCode's durable plugin storage, which writes JSON under the XDG
state directory ($XDG_STATE_HOME when set, otherwise ~/.local/state):
| Data | File |
|---|---|
| Learned model | opencode/<channel>/tui/plugin.quill.learning.json |
| Settings | opencode/<channel>/tui/plugin.quill.settings.json |
The learned model holds only word, bigram, trigram and word-casing counts plus processed message IDs. Raw prompt text is never written to disk. These files stay on your machine and are never tracked in Git or published to npm.
Development
bun install
bun run test # Unit tests and changelog checks
bun run typecheck # Type verification (tsc --noEmit)
bun run lint:sh # Syntax verification on shell scripts
Contributing
Contributions are welcome. Please read CONTRIBUTING.md and AGENTS.md before submitting a pull request.
License
MIT © Ozan Dogrultan
同类生态推荐
Ghost
opencode-ghost
OpenCode ghost text autosuggest: suggests your next message as dimmed inline ghost text in the empty TUI composer, accepted with Tab or Right arrow.
Shortcuts
opencode-shortcuts
A keyboard shortcut cheatsheet and rebinder for the OpenCode v1 and v2 TUI
Aside
opencode-aside
Claude Code's /btw side chat for opencode - ask a one-shot question in an overlay, with no tools and nothing added to the transcript