I can barely use Vim, so I built a Vim trainer with AI. Then I failed my own level.
> TL;DR: A DevOps engineer who can barely use Vim built a Vim/tmux trainer with Claude Code. Then he couldn't solve his own level. The builder learned Vim before the site launched.
Why: I open a terminal more than an IDE now
The way I work changed. Claude Code and Codex run in a terminal, a few tmux panes show the output, and I watch.
But there's still a moment where a human touches up what the agent wrote. That happens in Vim/Neovim inside the terminal. And I'm not good at Vim. I know :wq. That's roughly it.
Around then I heard DHH say he just builds whatever he needs. Fair enough: if there's no good place to practice, build one.
Goal: that LearnGitBranching feeling
If you've played LearnGitBranching, you know how addictive it is: you see the goal state and close the gap with your own hands.
So nvim-edu looks like this:
!Boss level: apply an AI code review
- Your buffer on the left, the goal on the right. Red lines still differ
- Beat the par keystroke count for ★★★
- 41 levels: motions → editing → text objects → visual & macros → real world: cleaning up AI code → tmux → guru combos
- Drills, a daily challenge (same tasks for everyone that day, with a 🔥 streak) and free practice
- Deliberately Neovim-looking: neo-tree sidebar, lualine, :colo tokyonight and friends
The real-world boss reads like this: "Review comments: ① remove the DEBUG prints ② rename tot → total." Exactly the moment where a human cleans up agent code.
The tmux chapter: only the keys humans still type
tmux has hundreds of bindings, but while an agent runs, a human presses only a handful:
- Create, attach, detach sessions (tmux new -s agent, C-b d, tmux a)
- Split, move, zoom panes (C-b %, C-b o, C-b z)
- Copy mode to scroll back and copy an error (the one I use most when agent logs get long)
That's the whole chapter. tmux can't run in a browser, so there's a small simulator with a session/window/pane tree.
Incident 1: the builder failed his own level
With the levels done, I was asked to try one by hand. The par solution on screen: 3lxfmx.
Me: "I don't get 3lxfmx."
I was pressing 3 over and over. 😇 Claude broke it down:
| Keys | Meaning | Result |
|---|---|---|
| 3l | move right 3 | cursor on the 4th character |
| x | delete under cursor | typo gone |
| fm | find the next m on this line | cursor on m |
| x | delete | done |
"Oh, it works."
Since then Claude has a standing rule for me: always explain keys as keys → meaning → result. The builder was the first user, and the first to fail.
Incident 2: typing jjl produced ㅓㅓㅣ
Every Korean (or Japanese, or Chinese) Vim user knows this one. Leave your input method on Korean, press jjl in NORMAL mode, and instead of moving down, down, right you get ㅓㅓㅣ on screen. That happened to me.
So in NORMAL mode, if a non-Latin IME is composing, nvim-edu blocks the text from entering the buffer and tells you to switch to English input. Early levels also block arrow keys and the mouse to build hjkl habits. (After I asked "wait, do arrow keys not work in real nvim?", arrows came back from chapter 2 on.)
Does it behave like real Neovim?
For speed, levels run on a browser Vim emulator (@replit/codemirror-vim). The worry: if the emulator is wrong, the site teaches wrong habits.
So real Neovim is the answer key:
- The same keys go into nvim --headless and into the site's editor; text, cursor and mode are compared
- It started at 130/169 matching: search always ignored case, dG left an empty line, Ctrl-a read 007 as octal…
- After fixing the emulator: 180/180. CI compares against Neovim 0.11.0 on every push
Still skeptical? There's a Real Vim mode (beta): actual Vim 8.2 running in the browser via vim.wasm, solving the same levels.
…except in Safari. 😅 GitHub Pages can't send the required isolation headers, so a service worker adds them, and Safari doesn't like that.
Try it
No install, no config. English and Korean.
👉 **s3onghyun.github.io
- Needs a physical keyboard (no touch yet)
- Progress lives only in your browser's localStorage
- MIT open source: s3onghyun/nvim-edu
A level is one object in src/levels.js, and npm test checks that the par solution really clears it, both in the emulator and in real Vim. Got a situation you wish were a level? Issues and PRs welcome.
Plenty of you already live in Vim. This is for anyone who, like me, is still stuck at :wq. 🙂
1 reaction
Mentions
Vim を使えない DevOps が AI と Vim 練習サイトを作ったら、自分のレベルを解けなかった話 :::note info Vim をろくに使えない DevOps エンジニアが、Claude Code と一緒に Vim・tmux の練習サイトを作りました。作った本人が自分のレベルを解けず、サイトより先に作者が Vim を覚えました。 ::: きっかけ:IDE よりターミナルを開く日が増えた 働き方が変わりました。Claude Code や Codex をターミナルで動かし、tmux のペインを何枚か並べて結果を眺める毎日です。 それでも、エージェントが書いたコードを最後に人が手直しする瞬間はあります。そこで手が伸びるのは結局ターミナルの中の Vim/Neovim。そして私は Vim が苦手です。:wq は知っています。ほぼそれだけです。 ちょうどその頃、Ruby on Rails の作者 DHH が「必要なものは自分で作ってしまう」と話していたと聞いて刺激を受けました。練習する場所がないなら、作ればいい。 目標:Git ブランチを練習したあの感覚で Learn Git Branching をやったことがある人なら分かると思います。ゴールの状態が見えていて、その差を自分の手で埋める形式は中毒性があります。 nvim-edu はこんな画面です。 !ボスレベル:AI のコードレビューを反映する - 左が自分のバッファ、右がゴール。赤い行がまだ違うところ - 模範解答より少ないキー数で解けば ★★★ - 41 レベル:移動 → 編集 → テキストオブジェクト → ビジュアル・マクロ → 実戦:AI が書いたコードの手直し → tmux → 達人コンボ - ドリル、デイリーチャレンジ(その日は全員同じ問題、🔥 連続記録あり)、自由練習 - 見た目はあえて Neovim 風:neo-tree のサイドバー、lualine、:colo tokyonight などのテーマ切り替え 実戦章のボスはこんな感じです。「レビューコメント:① DEBUG の print を削除 ② tot → total にリネーム」。まさにエージェントのコードを人が直す場面です。 tmux 章:人が実際に打つキーだけ tmux のキーバインドは何百もありますが、エージェントを動かしている間に人が実際に押すキーはほんの少しです。 - セッションの作成・アタッチ・デタッチ(tmux new -s agent、C-b d、tmux a) - ペインの分割・移動・ズーム(C-b %、C-b o、C-b z) - コピーモードでスクロールしてエラーをコピー(エージェントのログが長いとき一番使う) これだけを集めました。tmux はブラウザでは動かないので、セッション・ウィンドウ・ペインの木構造を持つ小さなシミュレーターを作りました。 やらかし 1:作者が自分のレベルを解けない レベルを作り終えて「実際に押してみてください」と確認を頼まれました。画面の模範解答は 3lxfmx。 私:「3lxfmx 分からない」 3 を何回も押していました。😇 Claude が手順表で分解してくれました。 | キー | 意味 | 結果 | |---|---|---| | 3l | 右へ 3 文字 | カーソルが 4 文字目へ | | x | カーソル位置の文字を削除 | 余分な文字が消える | | fm | この行で次の m を探す | カーソルが m へ | | x | 削除 | 完成 | 「おお、できた」 それ以来、Claude には「キーを教えるときは必ず キー → 意味 → 結果 の表で」というルールを入れてあります。作者が最初のユーザーで、最初の落第生でした。 やらかし 2:jjl と打ったらハングルが出た 日本語入力のまま NORMAL モードで dd を押して「っd」が出た経験、ありませんか。私の場合は韓国語入力のまま jjl を押して、カーソルが動く代わりに画面に ㅓㅓㅣ が並びました。 そこで NORMAL モードで日本語・韓国語・中国語の IME が変換中なら、文字をバッファに入れずに「英字入力に切り替えて」と警告を出すようにしました。最初の章では矢印キーとマウスも止めて hjkl の癖をつけます。(「本物の nvim って矢印キー効かないの?」と私が聞いたあとで、2 章以降は矢印キーを許可するよう直しました。) 本物の Neovim と同じ動きをするのか 反応速度のため、レベルはブラウザ用の Vim エミュレーター(@replit/codemirror-vim)の上で動いています。心配だったのは「エミュレーターが間違っていたら、間違った癖を教えてしまうのでは?」という点です。 そこで本物の Neovim を答案にしました。 - 同じキーを nvim --headless とサイトのエディターに入れて、テキスト・カーソル・モードを比較 - 最初は 130/169 一致。検索が常に大文字小文字を無視する、dG が空行を残す、Ctrl-a が 007 を 8 進数として扱う…などの差がありました - エミュレーターを直して今は 180/180 一致。CI が push のたびに Neovim 0.11.0 と比較します それでも疑う人のために 本物の Vim モード(beta) もあります。vim.wasm でブラウザの中に実際の Vim 8.2 を動かし、同じレベルを解けます。 …ただし Safari では動きません。😅 GitHub Pages では必要なヘッダーを付けられないので Service Worker で補っているのですが、Safari ではこれが不安定です。 使ってみる インストール・設定なしでブラウザですぐ遊べます。英語・韓国語に対応しています。 👉 **s3onghyun.github.io - 物理キーボードが必要です(タッチ操作は未対応) - 進捗はブラウザの localStorage にだけ保存されます - オープンソース(MIT):s3onghyun/nvim-edu レベルは src/levels.js にオブジェクトを 1 つ足すだけで、npm test が模範解答で本当にクリアできるかをエミュレーターと本物の Vim の両方で確認します。「こんな場面のレベルがほしい」があれば Issue・PR 歓迎です。 この記事は Zenn にも投稿しています: zenn.dev すでに Vim を使いこなしている方も多いと思いますが、私のように :wq で止まっている方の役に立てばうれしいです。🙂
I can barely use Vim, so I built a Vim trainer with AI. Then I failed my own level. > TL;DR: A DevOps engineer who can barely use Vim built a Vim/tmux trainer with Claude Code. Then he couldn't solve his own level. The builder learned Vim before the site launched. Why: I open a terminal more than an IDE now The way I work changed. Claude Code and Codex run in a terminal, a few tmux panes show the output, and I watch. But there's still a moment where a human touches up what the agent wrote. That happens in Vim/Neovim inside the terminal. And I'm not good at Vim. I know :wq. That's roughly it. Around then I heard DHH say he just builds whatever he needs. Fair enough: if there's no good place to practice, build one. Goal: that LearnGitBranching feeling If you've played LearnGitBranching, you know how addictive it is: you see the goal state and close the gap with your own hands. So nvim-edu looks like this: !Boss level: apply an AI code review - Your buffer on the left, the goal on the right. Red lines still differ - Beat the par keystroke count for ★★★ - 41 levels: motions → editing → text objects → visual & macros → real world: cleaning up AI code → tmux → guru combos - Drills, a daily challenge (same tasks for everyone that day, with a 🔥 streak) and free practice - Deliberately Neovim-looking: neo-tree sidebar, lualine, :colo tokyonight and friends The real-world boss reads like this: "Review comments: ① remove the DEBUG prints ② rename tot → total." Exactly the moment where a human cleans up agent code. The tmux chapter: only the keys humans still type tmux has hundreds of bindings, but while an agent runs, a human presses only a handful: - Create, attach, detach sessions (tmux new -s agent, C-b d, tmux a) - Split, move, zoom panes (C-b %, C-b o, C-b z) - Copy mode to scroll back and copy an error (the one I use most when agent logs get long) That's the whole chapter. tmux can't run in a browser, so there's a small simulator with a session/window/pane tree. Incident 1: the builder failed his own level With the levels done, I was asked to try one by hand. The par solution on screen: 3lxfmx. Me: "I don't get 3lxfmx." I was pressing 3 over and over. 😇 Claude broke it down: | Keys | Meaning | Result | |---|---|---| | 3l | move right 3 | cursor on the 4th character | | x | delete under cursor | typo gone | | fm | find the next m on this line | cursor on m | | x | delete | done | "Oh, it works." Since then Claude has a standing rule for me: always explain keys as keys → meaning → result. The builder was the first user, and the first to fail. Incident 2: typing jjl produced ㅓㅓㅣ Every Korean (or Japanese, or Chinese) Vim user knows this one. Leave your input method on Korean, press jjl in NORMAL mode, and instead of moving down, down, right you get ㅓㅓㅣ on screen. That happened to me. So in NORMAL mode, if a non-Latin IME is composing, nvim-edu blocks the text from entering the buffer and tells you to switch to English input. Early levels also block arrow keys and the mouse to build hjkl habits. (After I asked "wait, do arrow keys not work in real nvim?", arrows came back from chapter 2 on.) Does it behave like real Neovim? For speed, levels run on a browser Vim emulator (@replit/codemirror-vim). The worry: if the emulator is wrong, the site teaches wrong habits. So real Neovim is the answer key: - The same keys go into nvim --headless and into the site's editor; text, cursor and mode are compared - It started at 130/169 matching: search always ignored case, dG left an empty line, Ctrl-a read 007 as octal… - After fixing the emulator: 180/180. CI compares against Neovim 0.11.0 on every push Still skeptical? There's a Real Vim mode (beta): actual Vim 8.2 running in the browser via vim.wasm, solving the same levels. …except in Safari. 😅 GitHub Pages can't send the required isolation headers, so a service worker adds them, and Safari doesn't like that. Try it No install, no config. English and Korean. 👉 **s3onghyun.github.io - Needs a physical keyboard (no touch yet) - Progress lives only in your browser's localStorage - MIT open source: s3onghyun/nvim-edu A level is one object in src/levels.js, and npm test checks that the par solution really clears it, both in the emulator and in real Vim. Got a situation you wish were a level? Issues and PRs welcome. Plenty of you already live in Vim. This is for anyone who, like me, is still stuck at :wq. 🙂