Learn the next Vim command from your own editing habits — not a cheat sheet.
tobira watches how you actually edit, and when it spots a pattern you could do better, it quietly shows you the one command that would have helped. No quizzes. No interruptions.
Features • Installation • Usage • Configuration • vs hardtime.nvim
vim.on_key(); no config required, zero impact on your existing mappingsf searches, dw→i instead of cw, retyping the same :s/// substitution instead of &/g&, and more (see examples below):g, :norm, :s, and friends are tracked from the command line itself, not just normal-mode keys, so :g / :norm can be suggested to users who have never tried them (tobira's own :Tobira* commands are excluded, so checking your stats never counts as usage)lazy.nvim
{
"kamegoro/tobira.nvim",
event = "VeryLazy",
opts = {},
}
packer.nvim
use {
"kamegoro/tobira.nvim",
config = function()
require("tobira").setup()
end,
}
| Command | Description |
|---|---|
:Tobira |
Show the next suggestion now (ignores cooldown). Press q / Esc to dismiss. |
:TobiraGuide |
Toggle the cheatsheet panel |
:TobiraProgress |
Show skill tree with mastery glyphs and a cursor-driven detail preview. x = suppress, p = pin, g/s = jump to guide/stats, q/Esc/<C-c> = close. |
:TobiraStats |
Show usage stats: command distribution (never/tried/familiar/mastered) and efficiency gap suggestions |
:TobiraReset |
Clear all usage data |
:checkhealth tobira |
Diagnose your install — Neovim version, data directory, usage.json validity, lang config |
Full documentation is available in Neovim via :help tobira.
:TobiraGuide opens a cheatsheet on the right side of the screen. Commands you've already mastered are automatically hidden, so only your next targets are shown — and if one of them fades from use after you'd gotten comfortable with it, it reappears with a ⟳ (forgotten) marker instead of staying hidden forever. Pinned commands always appear at the top, marked ●. Covers all 10 categories: motion, edit, search, window, fold, mark, macro, diff, ex, and terminal — each capped to 3 unmastered commands (preferring ones you've never tried) so the panel stays a compact reference to glance at while you keep coding, with a +N more line if a category has more to show. Opens automatically on first launch.
:TobiraStats leads with the one section that actually changes what you do next — Try these next, commands you're using heavily whose neighbors you've never tried — followed by a mastery bar and your top commands. Total keystrokes and how many commands you've discovered sit in a quiet line at the bottom: fun to see, but not the point. g / p jump straight to Guide / Progress.
:TobiraProgress shows your current level and the full command learning graph as a calm grid — mastery glyphs only, no clutter. Move the cursor onto any command and a preview strip below the grid fills in with its usage sparkline, count, status, and how far it is from the next star. The header shows your overall {n} / {total} mastered ratio, and each category shows its own {done} / {total}.
| Glyph | Meaning |
|---|---|
| (blank) | Not yet tried |
☆ |
Tried (1+ uses) |
★ |
Familiar (100+ uses) |
★★ |
Practiced (1000+ uses) |
★★★ |
Mastered (5000+ uses) |
⟳ |
Forgotten — recent use has fallen off well below its earlier pace |
✗ |
Suppressed — you don't want this suggested |
● |
Pinned — always shown, in both :TobiraGuide and :TobiraProgress |
Keys inside :TobiraProgress: x toggles suppress on the command under the cursor, p toggles pin, g / s jump to Guide / Stats, q / Esc / <C-c> closes.
All options are optional — the defaults work out of the box.
require("tobira").setup({
lang = 'en', -- 'en' | 'ja' | 'zh' | 'es' | 'fr' | 'de'
idle_delay = 1500, -- ms of inactivity before showing an ambient suggestion
idle_suggestions = true, -- enable ambient idle suggestions
suggestion_cooldown = 300, -- s between automatic suggestions (default: 5 min)
max_shown = 2, -- max times to suggest the same command per session
integrations = true, -- boost suggestions when a known helper plugin is installed
})
tobira always respects your own :nmap/:nnoremap overrides — it never suggests a
command you've remapped away, and integrations above only gates the optional
plugin-detection boost, not that baseline behavior (see :help tobira-integrations).
tobira also tells apart a genuine remap from Neovim's own factory-default mappings —
gx, &, ]q/[q/]l/[l, and (Neovim 0.10+) even Y = y$ ship as built-in
defaults out of the box, so none of them count as "remapped" on a stock install; they're
suggested completely normally.
Two narrow exceptions cover a mapping that genuinely was set by something but still
does what tobira teaches: if you personally add nnoremap Y y$ yourself (redundant with
the modern default above, but a real personal binding), it's recognized as equivalent,
so the reactive y$ → Y suggestion still fires instead of being suppressed outright —
a Y remapped to anything else still suppresses it. Likewise, Neovim auto-loads
matchit.vim by default, which remaps % to <Plug>(MatchitNormalForward) — a strict,
compatible superset of the built-in % tobira teaches, so :TobiraGuide's cheat sheet
still lists % (with a "mapped to ..." note) on a stock install instead of hiding it
outright; a % remapped to anything else still hides it like any other override. Both
exceptions are still excluded from the proactive idle/:Tobira picks and
:TobiraStats's "Try these next" list either way — see :help tobira-integrations for
why those two surfaces don't read this distinction.
| You do this | tobira suggests |
|---|---|
fa → fa on the same line |
; — repeat the last f/t |
dw → i |
cw — change word in one command |
diw → i |
ciw — change inner word in one command |
j × 5 in a row on a genuinely wrapped line (with 'wrap' set) |
gj — move by display line instead |
j × 10 in a row |
} — jump by paragraph |
j × 10 in a row while &diff is set |
]c — jump to the next diff hunk |
dd × 3 in a row |
{n}dd — delete N lines at once |
<C-w>q / <C-w>c × 2 in a row |
<C-w>o — close all other windows |
zo × 2 in a row (different folds) |
zR — open all folds at once |
zc × 2 in a row (different folds) |
zM — close all folds at once |
G then gg (or gg then G) |
'' — jump straight back to your previous position |
cwFooBar<Esc> repeated 3× (navigation allowed between) |
qq...q / @q — record and replay a macro |
Same :s/pat/repl/ retyped 3× across lines |
g& — repeat it across the whole file |
<Esc> × 2 in terminal mode, no effect |
<C-\><C-n> — exit terminal mode |
<C-w>+ / <C-w>- / <C-w>< / <C-w>> × 2 in a row |
<C-w>= — equalize all window sizes |
<C-e> / <C-y> × 5 in a row |
zz — center the cursor line on screen |
Same one-line edit (e.g. A;<Esc>) on 3 consecutive lines |
<C-v> — block-visual edit them all at once |
Insert-mode edit right after a ]c/[c diff-hunk jump |
do / dp — diff obtain/put the whole hunk |
| Cursor returns to the same line 3× with real edits in between | ma — set a named mark to jump back to |
~ × 6 (spans a word) / × 12 (spans a line) |
g~iw / g~$ — toggle case in one motion |
77 patterns total — see :help tobira-patterns for the full list.
| Plugin | What it does | vs tobira |
|---|---|---|
| hardtime.nvim | Blocks repeated keys, hints better motions | Punishes bad habits — tobira teaches without ever blocking input |
| precognition.nvim | Shows available motions as virtual text | Always-on overlay — tobira appears only when you would have benefited |
| spamguard.nvim | Detects key spamming | Spam detection only — tobira covers the full command graph and tracks mastery |
| pathfinder.vim | Suggests more efficient cursor movement | Cursor movement only — tobira covers motion, edit, and search |
| vim-be-good | Game-based practice | Generic drills — tobira personalizes to your actual usage |
tobira is the only plugin that learns from your actual usage and shows you the specific commands you are missing.
| Question | Answer |
|---|---|
| Will tobira slow down my Neovim? | No — vim.on_key() stays minimal, no I/O per keystroke; usage data flushes only on exit. |
| Does it send my keystrokes anywhere? | No. Everything stays local in tobira/usage.json. |
| Can I use it alongside hardtime.nvim? | Yes — hardtime blocks bad habits, tobira teaches better ones. They complement each other. |
| A suggestion keeps appearing for something I already know | Open :TobiraProgress, move to it, press x to suppress. |
| How do I reset my data? | Run :TobiraReset. |
See CONTRIBUTING.md. This project follows strict TDD — tests before implementation, always.
MIT