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 はこんな画面です。
- 左が自分のバッファ、右がゴール。赤い行がまだ違うところ
- 模範解答より少ないキー数で解けば ★★★
- 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 ではこれが不安定です。
使ってみる
インストール・設定なしでブラウザですぐ遊べます。英語・韓国語に対応しています。
👉 https://s3onghyun.github.io/nvim-edu/
- 物理キーボードが必要です(タッチ操作は未対応)
- 進捗はブラウザの localStorage にだけ保存されます
- オープンソース(MIT):https://github.com/s3onghyun/nvim-edu
レベルは src/levels.js にオブジェクトを 1 つ足すだけで、npm test が模範解答で本当にクリアできるかをエミュレーターと本物の Vim の両方で確認します。「こんな場面のレベルがほしい」があれば Issue・PR 歓迎です。
この記事は Zenn にも投稿しています: https://zenn.dev/s3onghyun/articles/fb0f2c16d35e24
すでに Vim を使いこなしている方も多いと思いますが、私のように :wq で止まっている方の役に立てばうれしいです。🙂
