AIエディタのVimモード比較 Cursor・Zed・VSCode・Neovim
AIエージェントの出来でエディタを選ぼうとすると、Vimを使ってきた人は最後に必ず同じところで引っかかります。「Vimキーバインドに対応」と書いてあるのに、いざ移ってみると手が止まる操作がある、という現象です。原因ははっきりしていて、この「対応」は実装の仕組みが3種類あり、動く範囲がそれぞれ違うからです。しかも高いほうが、あるいはAIが賢いほうが再現度も高いという関係にはなっていません。ここを分類してから選ばないと、契約してから気づくことになります。
検証環境:Vim 9.1とNeovim 0.12.4はmacOS上で実際に動かして確認しました。VSCodeVimは1.32.4のソース(src/vimscript/exCommandParser.ts)、vscode-neovimは1.19.0のREADME、Zedは公式ドキュメントのdocs/src/vim.mdを2026-08-17時点で読んで判断しています。CursorとZedのアプリ本体は手元に入れていないので、この2つは一次情報の記述までを根拠とし、実機で叩いた話としては書きません。
目次(7項目)
「Vimキーバインド対応」は3種類に分かれる
まず全体の地図から出します。世の中のエディタが言う「Vimキーバインド」は、内部の作りで次の3つに分かれます。
| 方式 | 代表 | 中身 |
|---|---|---|
| 再実装 | VS Code / Cursor | VSCodeVim拡張がVimの挙動をTypeScriptで書き直している |
| 独自実装 | Zed | Zed本体に組み込み。Vimに似せるより自分の仕組みに寄せる方針 |
| 本物を積む | vscode-neovim / Neovim | Neovimのプロセスをそのまま動かし、キー入力を渡す |
再実装と独自実装は、よく使う操作から順に作られています。だから hjkl や dw、テキストオブジェクトあたりは普通に動きます。困るのはその外側で、自分がどれだけ外側を使っているかによって体感が変わります。移行してすぐ「問題なく動く」と言う人と「使い物にならない」と言う人が同時に出るのはこのためです。
本物を積む方式は挙動そのものはVimなので、代わりに統合の継ぎ目が問題になります。どこがVimでどこがエディタ側なのか、境界を知っておく必要があります。順に見ていきます。
再実装で最初に足りなくなるのは:g
VSCodeVimがどこまで実装しているかは、ソースを読むのがいちばん早いです。1.32.4のsrc/vimscript/exCommandParser.tsにコマンド名の一覧表があり、引数パーサが用意されていないものは次のように扱われます。
argParser ??= all.result(new UnimplementedCommand(...));
このUnimplementedCommandは実行するとステータスバーに「Command :global is not yet implemented (PRs are welcome!)」と出すだけのクラスです。つまり一覧表を見れば、実装されているものと名前だけ受け付けるものが機械的に分かります。読んだ結果が次です。
| コマンド | VSCodeVim 1.32.4 |
|---|---|
:s | あり |
:sort | あり |
:normal | あり |
:marks / :reg | あり |
:g / :v | 名前だけ。未実装のメッセージが出る |
:argdo / :bufdo / :windo | 同上 |
:source / :mksession | 同上 |
:gが無いのは、慣れている人ほど効きます。「特定の文字列を含む行だけまとめて処理する」という発想そのものが使えなくなるからです。手元のVim 9.1で、デバッグ用のログを消す典型的な例を実際に流すとこうなります。
# 元のファイル
const a = 1;
console.log(a);
const b = 2;
console.log(b);
return a + b;
# :g/console\.log/d を実行した後
const a = 1;
const b = 2;
return a + b;
同じことをVSCodeVimでやろうとすると、検索して1つずつ消すか、エディタ側の一括置換に持ち込むことになります。どちらも手数が増えるだけで済む話ではあります。ただ、:globalは:normalと組み合わせて任意の編集を配れるのが本領なので、そこを日常的に使っているなら移行のコストを一段高く見積もったほうが安全です。
いっぽうマクロはsrc/actions/commands/macro.tsがあり、qと@は実装されています。ドットコマンドも動きます。マクロで繰り返しを片づけるやり方が主戦力の人であれば、こちらは残ります。
Zedは「Vimに似せない」と決めている
Zedのvimモードは本体に組み込みで、拡張を入れる必要がありません。ただし方針が独特で、公式ドキュメントに「vim mode replicates the behavior of motions and commands where it makes sense and uses Zed-specific functionality where Zed's approach is better」と書かれています。Vimに寄せるのは意味があるところまで、という宣言です。
この方針が効いてくる場所が3つあります。まずマクロで、Zedはvimの記録ではなくZed自身の記録システムを使います。ドキュメントには「you can capture and replay more complex actions, like autocompletion」とあり、補完のような本来のVimには無い操作まで記録に乗ります。強力ですが、記録される単位がVimと同じとは限らないという意味でもあります。
2つ目が正規表現です。Zedは検索機能をそのまま使うので、書き方が変わります。
| 用途 | Vim | Zed |
|---|---|---|
| グループ化 | \(...\) | (...) |
| 後方参照 | \1 | $1 |
| 行内の全置換 | gフラグが要る | 検索は既定で全体が対象 |
指が覚えている:%s/\(foo\)_\(bar\)/\2_\1/gのような式が、そのままでは通りません。:substituteの書き方を体に入れているほど書き直しが必要になるので、ここは移行前に一度試したほうがいいところです。
3つ目がExコマンドの範囲で、ドキュメントに「We don't emulate the full power of Vim's command line yet. In particular, commands currently do not support arguments」と明記されています。編集系として表に載っているのは:join、:delete、:sort、:yankと置換の:sだけです。:sortも対象は選択範囲で、Vimのように行範囲を前置する形とは考え方が違います。ここもやはり:gはありません。
逆に、Zedが素で持っているものもあります。gccとgcでのコメント切り替えが標準で入っていて、これはNeovim 0.10以降の既定と同じ形です。両方を行き来する人にとっては、数少ない「そのまま通じる」キーになります。実際の動きはVim道場のコメント切り替えの回で手を動かして確かめられます。
Cursorは自前のVimモードを持っていない
意外と知られていませんが、CursorにVimモードという独自機能はありません。セットアップでVimキーバインドを有効にすると、VSCodeVim拡張が入る作りになっています。CursorはVS Codeのフォークなので、設定ファイルの書式も拡張の資産もそのまま共有されます。
これは選ぶ側にとっては単純化になります。CursorのVim再現度を調べたいときは、CursorではなくVSCodeVimを調べればよいということだからです。前の節に書いた:gの話は、そのままCursorの話でもあります。
Cursor固有の問題として残るのは、AI側の機能に割り当てられたキーとの衝突です。Cmd-kがVS Codeでは各種ショートカットの入り口だったのに対し、Cursorでは編集用のプロンプトを開くキーになっています。補完の受け取りにTabが使われる点も、挿入モードでの入力と競合しやすい場所です。このあたりは実機で触っていないので断定は避けますが、キーの取り合いが起きること自体は各所で報告されています。移行するなら、キーバインドの設定を最初に見る前提でいたほうが無難です。
本物のNeovimが動くのはこの2つ
再現度を最優先するなら選択肢は2つに絞られます。1つがvscode-neovimで、READMEに「This extension uses a fully embedded Neovim instance, no more half-complete Vim emulation!」とあるとおり、Neovimのプロセスを実際に起動してキー入力を渡します。だから:gも:argdoも普通に通ります。自分のinit.luaもそのまま読ませられます。
ただし全部がNeovimなわけではなく、境界がはっきり決められています。挿入モードはVS Code側が担当し、スクロールもVS Code側です。READMEにも<C-d>や<C-u>の挙動が少し違うこと、ドットリピートが特定の状況で標準のNeovimと異なることが書かれています。補完やLSPをNeovim側のプラグインでやろうとすると衝突するので、その手のプラグインは入れないよう明記されています。要するに、編集の頭脳はNeovim、画面と補完はVS Codeという分担です。
もう1つが、Neovim本体でAIエージェントを動かす形です。再現度は当然100%で、考えることは「エージェントをどう置くか」だけになります。sidekick.nvimで常駐させる方法と、プラグイン無しで:terminalに置く方法があり、後者はVim 9でも同じ手が使えます。
どれを選ぶか
ここまでを判断の順に並べ直すとこうなります。
| 優先するもの | 選択肢 | 諦めるもの |
|---|---|---|
| Vimの再現度 | Neovim + AIプラグイン | GUIの手厚さ、設定の手間 |
| 再現度とGUIの両立 | VS Code + vscode-neovim | 挿入モードとスクロールはVS Code側 |
| AIの体験 | Cursor | :g系のExコマンド、キーの衝突 |
| 動作の軽さ | Zed | 正規表現の書き方、Exコマンドの範囲 |
判断の分かれ目を1つだけ挙げるなら、:gと:argdoを日常的に使っているかどうかです。使っているなら再実装型は候補から外れます。使っていないなら、再実装型でも困る場面はそれほど出てきません。自分がどちら側かは、直近1週間で打ったExコマンドを思い出せば判定できます。
最初にVS Codeへ移ろうとしたとき、拡張を入れて30分ほどは順調でした。詰まったのはログ行の掃除をしようとして:g/console\.log/dを打った瞬間で、ステータスバーに未実装のメッセージが出たときは正直まだ信じていませんでした。自分がこのコマンドを1日に何回も打っていたことに、使えなくなって初めて気づいた形です。逆にマクロは動いたので、そこで「全部だめ」ではなく「どこが欠けるか」を先に調べるべきだったと反省しました。今回ソースを読んだのはその反省からで、看板の「Vim対応」を信じずコマンドの一覧表を見に行くのがいちばん早い、というのが結論です。Zedの正規表現の違いも、知らずに置換して意図しない結果を作る前に気づけてよかった部類でした。
まとめ
AIエディタの「Vimキーバインド対応」は、再実装(VS Code / Cursor)、独自実装(Zed)、本物のNeovimを積む(vscode-neovim / Neovim本体)の3種類に分かれます。再実装型で最初に欠けるのは:gと:argdo系で、VSCodeVim 1.32.4では名前だけ受け付けて未実装のメッセージを返します。Zedはマクロと正規表現の仕組みが別物で、編集系のExコマンドも:join、:delete、:sort、:yank、:sに限られます。CursorのVimモードは実体がVSCodeVimなので、再現度の話は同じです。挙動をそのまま持ち込みたいならvscode-neovimかNeovim本体になりますが、前者は挿入モードとスクロールがVS Code側という境界を理解しておく必要があります。選ぶ前に、自分が普段どこまでのVimを使っているかを棚卸しするのが結局いちばん早い判断材料になります。