Claude CodeをEmacsに統合する使い方 — claude-code-ide.elの導入と設定
claude-code-ide.elはMCP経由でClaude Code CLIとEmacsを繋ぐパッケージです。導入手順、ediffでの差分確認、ターミナルバックエンドとレンダラー設定の優先順位、独自ツールの追加までを扱います。
claude-code-ide.elは、Model Context Protocol(MCP)を使ってEmacsとClaude Code CLIを繋ぐEmacsパッケージです。開いているファイルや選択範囲をClaudeに伝え、変更案をEmacsのediffで確認してから適用できます。
ターミナル表示だけのラッパーと違い、EmacsからClaudeへ状態が渡り、Claudeの変更案がEmacsへ戻る経路を持ちます。導入手順に続けて、ちらつきが出たときの設定の優先順位や、独自のElisp関数をClaudeのツールにする方法まで書きます。
claude-code-ide.elは何を橋渡しするのか
LSPやプロジェクト管理、独自のElisp関数といったEmacsの機能を、Claudeが使えるようにします。READMEの表現では、ClaudeとEmacsの間に双方向のブリッジを作るパッケージです。
MCPは、AIモデルが外部のツールやデータソースに接続するための標準プロトコルです。Claude Codeはこの仕組みでJira・GitHub・Sentryのような外部サービスと連携できます。claude-code-ide.elは同じ標準を使い、接続先を外部サービスではなくEmacs自身に置いた実装です。
橋渡しされるものは、大きく4つに分かれます。
Emacsとの間で行き来するもの
見ているものが伝わる
開いているファイルと選択範囲が、プロジェクトのすべてのインスタンスに伝わります。FlycheckとFlymakeの診断結果もClaudeが読めます。
変更案がediffで戻る
Claudeの提案はediffで開き、Buffer Bを直してから適用できます。tab-barの切り替えにも対応しています。
Emacsの機能がツールになる
xref・tree-sitter・imenu・project情報を、組み込みのMCPツールとして呼べます。任意のElisp関数も追加できます。
複数のセッションを管理できる
プロジェクトを自動検出し、同じプロジェクトで複数のインスタンスを動かせます。ターミナルは
vterm・eat・ghostelから選びます。
導入する
前提は3つです。Emacs 28.1以降、PATH上で動くClaude Code CLI、そしてvterm・eat・ghostelのいずれかです。Emacsから呼び出すだけなので、通常のターミナルでclaudeが動けば足ります。
claude --versionv2.1.287では2.1.287 (Claude Code)と表示されます。Emacs側からはM-x claude-code-ide-check-statusで、CLIが入っていて動く状態かを確かめられます。
emacs-version 30以降であれば、use-packageの:vcバインディングでGitHubから直接取得できます。
(use-package claude-code-ide
:vc (:url "https://github.com/manzaltu/claude-code-ide.el" :rev :newest)
:bind ("C-c C-'" . claude-code-ide-menu)
:config
(claude-code-ide-emacs-tools-setup))straight.elを使っている場合は次のように書きます。
(use-package claude-code-ide
:straight (:type git :host github :repo "manzaltu/claude-code-ide.el")
:bind ("C-c C-'" . claude-code-ide-menu)
:config
(claude-code-ide-emacs-tools-setup))Doom Emacsではpackages.elとconfig.elの2ファイルに分けて書きます。
(package! claude-code-ide
:recipe (:host github :repo "manzaltu/claude-code-ide.el"))(use-package! claude-code-ide
:bind ("C-c C-'" . claude-code-ide-menu)
:config
(claude-code-ide-emacs-tools-setup))config.elを保存したあと、ターミナルでdoom syncを実行してパッケージを反映します。
doom syncどの設定例でも(claude-code-ide-emacs-tools-setup)は「Optionally」とコメントされた任意の設定です。呼ぶとxrefやtree-sitterなどのMCPツールが有効になり、呼ばなければファイル操作やエディタ状態の共有といった基本機能だけが動きます。
transientメニューから使い始める
最も簡単な入口は、transientメニューです。M-x claude-code-ide-menu(上の設定例ではC-c C-')を実行すると、使えるコマンドが一覧表示されます。
| コマンド | 説明 |
|---|---|
claude-code-ide | 説明プロジェクト用の新しいClaude Codeインスタンスを起動 |
claude-code-ide-send-prompt | 説明ミニバッファからClaudeにプロンプトを送信 |
claude-code-ide-insert-at-mentioned | 説明選択したテキストをClaudeのプロンプトに送る |
claude-code-ide-continue | 説明直近の会話を新しいインスタンスで継続 |
claude-code-ide-resume | 説明過去の会話を新しいインスタンスで再開 |
claude-code-ide-stop / claude-code-ide-stop-all | 説明プロジェクトのインスタンスを停止 / プロジェクトの全インスタンスを停止(C-uで全プロジェクト) |
claude-code-ide-toggle | 説明プロジェクトのClaudeウィンドウを表示・非表示 |
claude-code-ide-toggle-recent | 説明全プロジェクトのClaudeウィンドウをまとめて表示・非表示 |
claude-code-ide-list-sessions | 説明全プロジェクトのインスタンス一覧から切り替え |
claude-code-ide-rename-session | 説明起動済みインスタンスの名前を変更 |
claude-code-ide-send-escape | 説明Claudeのターミナルにescapeキーを送る |
claude-code-ide-insert-newline | 説明プロンプトに改行を入れる(\とEnterを送る) |
claude-code-ide-show-debug | 説明WebSocketメッセージのデバッグバッファを表示 |
Claudeターミナルの中では、M-RETがclaude-code-ide-insert-newline、C-<escape>がclaude-code-ide-send-escapeに割り当てられます。この2つにC-c C-x(claude-code-ide-clear-selection)を加えた3つは、vterm・eat・ghostelのどれでも、Claudeのバッファの中だけで有効です。
claude-code-ide-stopやclaude-code-ide-send-promptのように1つのインスタンスを対象にするコマンドは、対象を順に絞り込みます。今いるClaudeターミナル、プロジェクト内の唯一のインスタンス、唯一の可視インスタンスの順です。
それでも決まらないとき、送信系は直近に使ったインスタンスを選び(選んだ先を表示)、claude-code-ide-stopは選択を尋ねます。前置引数(C-u)を付ければ、いつでも明示的に選べます。
複数のClaudeを同時に走らせる
claude-code-ide.elはEmacs標準のproject.elでプロジェクトを自動検出します。同じプロジェクトで複数のインスタンスを動かせるので、片方でリファクタリングを進め、もう片方に質問する使い方ができます。
最初のインスタンスのバッファ名は*claude-code[project-name]*です。再度M-x claude-code-ideを実行すると追加のインスタンスが起動し、名前を入力できます。refactorと入れれば*claude-code[project-name:refactor]*に、空入力なら番号が振られます(*claude-code[project-name:2]*など)。この番号は位置依存で、インスタンスが終了すると再利用されます。
各インスタンスは自分専用のMCPサーバーを動かします。ただし、カーソル位置や選択範囲のコンテキストは同じプロジェクトの全インスタンスで共有されます。プロンプト送信・at-mention・diffのような明示的な操作だけが、指定した1つに向かいます。
複数インスタンスを動かす方法は2つあり、作業ツリーを共有するかどうかで選びます。
同じ作業ツリーか、別のworktreeか
同じプロジェクトで複数インスタンス
M-x claude-code-ideをもう一度実行するだけです。全インスタンスが同じファイルを触るので、実装役・レビュー役・質問役のように分担する使い方に向きます。
git worktreeで分ける
競合する変更が入る別ブランチでの並行作業は、こちらです。project.elがworktreeを別プロジェクトとして扱うため、バッファもセッションも完全に独立します。
worktreeを使う場合は、先にブランチ用の作業ツリーを作ります。worktreeの扱い全般はworktreeの完全ガイドにあります。
git worktree add ../myproject-worktree feature-branch作成したmyproject-worktreeでM-x claude-code-ideを実行すると、*claude-code[myproject]*と*claude-code[myproject-worktree]*が別々のバッファとして並びます。
継続の挙動にも注意が要ります。claude-code-ide-continueで同じディレクトリに継続インスタンスを複数起動すると、どれも同じ「直近の」会話をフォークします。これはClaude Code CLI自体の挙動です。
Claudeに見せるファイルと選択範囲
プロジェクトの各インスタンスには、いま見ているファイルと選択中のテキストが常に伝わります。プロンプト欄に⧉ In file.elや⧉ 3 lines selectedというラベルが出て、次に送るプロンプトには「ユーザーがIDEで〜を開いた」という短い注記が付きます。ファイルの内容そのものは送られません。
見せたくないときの操作は2種類あります。
claude-code-ide-clear-selection(メニューのx、Claudeターミナル内ではC-c C-x)で、1つのインスタンスからコンテキストを外します。外したファイルは、その中を移動してもプロンプトに含まれません。範囲選択するか別のファイルを開くと、共有が再開しますclaude-code-ide-share-opened-fileをnilにすると(設定メニューのoでも切り替え可)、報告されるのは選択範囲だけになります。範囲選択がアクティブな間だけ共有され、解除すると止まります
VS Code拡張のファイル名の横にあるxと同じ発想の操作です。他のIDE統合との操作感の違いが気になる場合は、VS Code拡張の基本的な使い方と比べると分かりやすくなります。
ファイルの共有は、プロジェクトの内側が前提のようです。GitHubのissue #196には、フォルダがプロジェクトとみなされないと「Active File Awareness」が働かなかったという報告があります。プロジェクトの外にあるファイルで共有が効かないときは、まずここを疑えます。
ediffで変更案を直してから適用する
claude-code-ide-use-ide-diffが有効(既定値)だと、Claudeの変更案はEmacsのediffで開きます。左右または統合ビューで比べられ、Buffer B(Claudeの提案)を自分で直してから適用できます。
ediffでの確認から適用まで
- 1
ediffが自動で開く
Claudeが変更を提案すると、ediffが開き、小さなコントロールバッファがアクティブになります。
- 2
Buffer AとBを見比べる
Buffer Aに現在のコード、Buffer Bに提案内容が出ます。必要ならBuffer Bを直接編集して、提案を調整します。
- 3
コントロールバッファで q を押す
ediffを終了すると、変更を受け入れるかどうかを尋ねられます。
- 4
y か n を選ぶ
yを選ぶと、Buffer Bの内容が元のファイルに適用される形でClaudeに送り返されます。nは拒否です。
ターミナルの表示のまま確認したいときは、(setq claude-code-ide-use-ide-diff nil)でediffを無効にします。Claude Code自体のVS Code・JetBrains向け統合にも、差分をIDE内かターミナルかで切り替えるdiffTool設定があります。ただし、これはclaude-code-ide.elのuse-ide-diffとは別の設定です。
ediffの開き方と受け入れ後のバッファの状態については、利用者の報告が2件あります。
- issue #192: 別のタブで作業中でも、Claudeの変更のたびにediffのウィンドウがフォーカスを奪う。静かに開く方法はないか、という質問です
- issue #200: ediffで変更を受け入れてClaudeがディスクへ書き込んだあとも、対応するバッファが「modified」のまま表示される。編集しようとするたびに、ディスク上でファイルが変わっている旨の確認が出るという報告です
ediffまわりの設定変数には、claude-code-ide-focus-claude-after-ediff(ediffを開いた後にClaudeへフォーカスを移すか)、claude-code-ide-show-claude-window-in-ediff(ediff中にClaudeのウィンドウを出すか)、claude-code-ide-switch-tab-on-ediff(ediffを開くときにClaudeのタブへ移るか)があります。
ちらつきやスクロールの乱れが出るとき
claude-code-ide.elはターミナル表示にvterm・eat・ghostelを使えます。既定はvtermです。
| バックエンド | 特徴 | 向く場面 |
|---|---|---|
vterm | 特徴既定。コンパイルを伴う | 向く場面標準的な構成で使いたい場合 |
eat | 特徴Pure Elispのターミナルエミュレータ | 向く場面vtermのコンパイルがうまくいかない環境 |
ghostel | 特徴ghostel-execを提供するバージョンが必要 | 向く場面フリッカーやスクロールの乱れを避けたい場合(READMEが推奨) |
READMEは、使えるバックエンドの中でghostelが最も滑らかだとしています。vtermとeatにありがちなフリッカー・スクロールの乱れ・表示崩れがほとんど出ないため、使える環境ではこれを勧める、という書き方です。切り替えは1行で済みます。
(setq claude-code-ide-terminal-backend 'eat)レンダラー設定の優先順位
バックエンドとは別に、Claude Code側にも2種類のレンダラーがあります。通常の画面に出力を残すインライン表示と、vimやhtopのように代替スクリーンバッファを使うフルスクリーン表示です。インラインなら会話が普通のテキストとしてバッファに残るので、isearchで全体を検索できます。
インライン表示に固定するには、~/.claude/settings.jsonでtuiをdefaultにします。
{
"tui": "default"
}セッション中に/tui defaultを実行しても切り替えられ、同じ設定が保存されます。
厄介なのは、claude-code-ide-no-flickerとの組み合わせです。READMEによると、この変数をtにするとセッションにCLAUDE_CODE_NO_FLICKER=1が渡され、フルスクリーン表示が有効になります。環境変数のドキュメントでは、この変数がtuiの設定を上書きすると書かれています。
| 設定 | 効果 | 優先 |
|---|---|---|
CLAUDE_CODE_DISABLE_ALTERNATE_SCREEN=1 | 効果クラシックなインライン表示にする | 優先最優先(NO_FLICKERとtuiの両方に勝つ) |
CLAUDE_CODE_NO_FLICKER=1 | 効果フルスクリーン表示にする | 優先tuiの設定を上書き |
~/.claude/settings.jsonのtui | 効果defaultかfullscreenを選ぶ | 優先最も弱い |
つまり、tuiをdefaultにしてあってもclaude-code-ide-no-flickerをtにすると、フルスクリーンが勝ちます。CLAUDE_CODE_NO_FLICKER=0もフルスクリーンを切る設定で、DISABLE_ALTERNATE_SCREEN=1と両方が設定されたときもオフになります。ghostelではフリッカー自体が問題にならないので、claude-code-ide-no-flickerは既定のnilのままにします。
この設定が効かない場面も報告されています。issue #202は、vtermでフルスクリーン表示になるとスクロールバックが壊れ、"tui": "default"で直ったという報告です。
issue #226はghostelでの報告で、Claude Code 2.1.281のC-gによる外部エディタの待機中だけ、代替スクリーンに切り替わります。CLAUDE_CODE_DISABLE_ALTERNATE_SCREEN=1と"tui": "default"の両方を設定していても、この画面には効かないそうです。
eatのちらつきには、別の環境変数が用意されています。CLAUDE_CODE_FORCE_SYNC_OUTPUT=1は、同期出力に対応しているのに能力の問い合わせへ応答しないエミュレータ(Emacsのeatなど)向けです。使い方はEmacsのeatでClaude Codeを使うとちらつく問題を直す設定にあります。
ghostelでCtrl+Gを使う
ghostelバックエンドはC-gをそのままターミナルに転送します。そのため、Claude Code側がCtrl+Gに割り当てている「外部エディタでプロンプトを編集」が使えます。この操作の詳しい挙動はClaude CodeのCtrl+Gで外部エディタにプロンプトを開くにまとめています。
別のキーに移したいときは、~/.claude/keybindings.jsonでctrl+gを無効にし、chat:externalEditorを割り当て直します。READMEの例はalt+eです。chat:externalEditorのもう一つの既定キーCtrl+X Ctrl+Eは、C-xをEmacsが握るため端末に届きません。alt+eならghostelが転送します。
{
"$schema": "https://www.schemastore.org/claude-code-keybindings.json",
"bindings": [
{
"context": "Chat",
"bindings": {
"ctrl+g": null,
"alt+e": "chat:externalEditor"
}
}
]
}設定変数とCLIフラグの対応
設定変数は多数ありますが、最初に触ることが多いものは次のとおりです。
| 変数 | 内容 | 既定値 |
|---|---|---|
claude-code-ide-cli-path | 内容Claude Code CLIへのパス | 既定値"claude" |
claude-code-ide-cli-extra-flags | 内容CLIに渡す追加フラグ(--modelなど) | 既定値"" |
claude-code-ide-window-side | 内容Claudeウィンドウを出す側 | 既定値'right |
claude-code-ide-use-side-window | 内容サイドウィンドウを使うか | 既定値t |
claude-code-ide-diagnostics-backend | 内容診断バックエンド(auto/flycheck/flymake) | 既定値'auto |
claude-code-ide-enable-execute-code | 内容ElispをClaudeが評価できるようにするか | 既定値t |
claude-code-ide-system-prompt | 内容追加するカスタムシステムプロンプト | 既定値nil |
Emacs側の設定の一部は、Claude Codeのコマンドラインフラグに変換されます。READMEの説明と、v2.1.287のclaude --helpの出力を並べると、対応は次のとおりです。
claude --help | grep -E -- '^ +(-c,|-d,|-r,|--model <|--append-system-prompt <)' --append-system-prompt <prompt> Append a system prompt to the default
-c, --continue Continue the most recent conversation in
-d, --debug [filter] Enable debug mode with optional category
--model <model> Model for the current session. Provide
-r, --resume [value] Resume a conversation by session ID, or| Emacs側の設定 | 渡るフラグ |
|---|---|
claude-code-ide-system-prompt | 渡るフラグ--append-system-prompt |
claude-code-ide-cli-debugをt | 渡るフラグ-d |
claude-code-ide-resumeの実行 | 渡るフラグ-r(READMEは組み込みフラグの例に-dと-rを挙げる) |
claude-code-ide-cli-extra-flags | 渡るフラグ書いた文字列をそのまま追加 |
claude-code-ide-cli-extra-flagsの値は、-dや-rのような組み込みフラグの後ろに付きます。モデルを固定するなら--modelを渡します。
(setq claude-code-ide-cli-extra-flags "--model opus")READMEの「複数のフラグを渡す」例には"--model opus --no-cache"が載っています。v2.1.287のclaude --helpに--no-cacheというオプションは出ません。extra-flagsに入れる値は、自分の環境のclaude --helpに載っているものから選ぶと確実です。
プロジェクトごとに振る舞いを変えたいときは、claude-code-ide-system-promptを.dir-locals.elで上書きします。
((nil . ((claude-code-ide-system-prompt . "Focus on functional programming patterns and avoid mutations."))))不具合を疑うときは、claude-code-ide-cli-debug(CLIの-d)とclaude-code-ide-debug(WebSocket通信のEmacs側ログ)をtにします。M-x claude-code-ide-show-debugで、JSON-RPCのやり取りが見られます。
EmacsのコマンドをClaudeのツールにする
claude-code-ide-emacs-tools-setupを呼ぶと、Emacsのコマンドが追加のMCPツールとして公開されます。組み込みは5つです。
xref-find-references— プロジェクト全体でシンボルの参照箇所を探すxref-find-apropos— パターンに一致するシンボルをプロジェクト全体から探すtreesit-info— tree-sitterによる構文木の情報を取得するimenu-list-symbols— imenuでファイル内のシンボル(関数・クラス・変数)を列挙するproject-info— 現在のプロジェクトの情報(ディレクトリ、ファイルなど)を取得する
有効にすると、「foo関数の定義を見せて」「この変数が使われている箇所を全部見せて」「カーソル位置のASTノードの型は何?」といった依頼に、Claudeがこれらのツールで答えられるようになります。
独自の関数を足す
自分のElisp関数も、claude-code-ide-make-toolで登録できます。READMEが示す定義の形は次のとおりです。
(claude-code-ide-make-tool
:function #'function-name
:name "tool_name"
:description "..."
:args '((:name "param1"
:type string
:description "..."
:optional t))):nameはClaudeが呼ぶときの名前で、snake_caseが勧められています。引数の型に使えるのはstring・number・integer・boolean・array・object・nullです。
関数の中で、そのセッションのプロジェクトをdefault-directoryにしたいときは、claude-code-ide-mcp-server-with-session-contextマクロで本体を包みます。複数のプロジェクトで同時にClaudeを動かしていても、ツールが正しいプロジェクトで動きます。
READMEのmy-project-grepの例は、検索パターンをformatで組んだシェルコマンドの文字列にしてshell-command-to-stringに渡します。パターンを決めるのはClaudeなので、引用符を含む値が来る場合も想定して書く必要があります。
Elispの評価を許すかどうか
もう一つ、executeCodeというMCPツールがあります。Claudeが実行中のEmacsでElisp式を評価できるようにするもので、既定で有効です。使わないなら止められます。
(setq claude-code-ide-enable-execute-code nil)つまずきやすいポイント
- 複数インスタンスが並ばない: 各インスタンスは自分専用のサイドウィンドウスロットを持ちます。片側に何枚並ぶかはEmacs標準の
window-sides-slotsが決めるので、READMEの例のように(setq window-sides-slots '(nil nil 3 nil))で右側に3枚まで並べられます - tab-bar-modeの新しいタブにClaudeが出ない: 新規タブは複製元のレイアウトからClaudeウィンドウを継承しません。
claude-code-ide-show-allや表示切り替えコマンドで呼び出します - ウィンドウのリサイズでスクロールが乱れる: ターミナルの再描画で制御できないスクロールが起きる、Claude Code側の既知の不具合(#1422)の回避策として、
claude-code-ide-prevent-reflow-glitchが既定で有効です。upstreamの修正後に外される一時対応とされています
まとめ
判断の分かれ目は2つです。ちらつきを避けたいなら、バックエンドはghostelを第一候補に置き、tuiとclaude-code-ide-no-flickerが逆向きの設定にならないかを見ておきます。
executeCodeと独自ツールはClaudeにEmacsの実行権を渡す機能なので、使うものだけを有効にする構成もあります。