0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

EXWM + claude-code-ide.el で Emacs が固まる問題を ghostel バックエンドで回避する (+ 複数行プロンプト用 compose UI)

0
Posted at

TL;DR

  • claude-code-ide.elEXWM 上で使うと、Claude の Ink TUI 再描画中に Emacs が固まることがある。原因は eat バックエンドのターミナル処理が純 Elisp で main loop 上で走り、xelb の X イベント受信を飢餓状態にすること。
  • これを回避するために、ghostel (libghostty-vt のネイティブモジュール) を claude-code-ide の第3のバックエンドとして使えるようにする小さなアドオン claude-code-ide-ghostel を作った。
  • ついでに、ddskk / mozc など IM を活かして複数行プロンプトを編集できる child frame UI claude-code-ide-compose も同梱した。
  • 両方まとめて frenzieddoll/claude-code-ide-extras で公開している。

動機

問題1: EXWM + eat バックエンドで Emacs が固まる

私は普段 EXWM をウィンドウマネージャとして使っている。この状態で claude-code-ideeat バックエンド経由で Claude セッションを動かすと、Claude 側 (Ink TUI) の再描画が激しいタイミングで Emacs 全体が一時的に固まる現象に遭遇した。

メカニズムを追ってみると:

  • eat はターミナルエミュレーション一式を 純 Elisp で実装している。出力処理はすべて Emacs の main loop 上。
  • EXWM は X11 プロトコルを xelb (これも純 Elisp) で喋っている。X イベントの受信処理も main loop。
  • Claude CLI の Ink TUI は文字単位で頻繁に再描画してくる。
  • すると main loop が eat のパース処理で詰まり、xelb の X イベント受信が後回しになる。
  • 結果として、ウィンドウ操作が秒単位で固まる。

問題2: ターミナルバッファ上で日本語 IM (ddskk 等) を活かして複数行プロンプトを書きたい

Claude CLI のプロンプトは複数行入れたい場面が多い (コード片を貼る、説明を構造化する、など)。しかし:

  • claude-code-ide-send-promptミニバッファ入力RET で送信されてしまうので複数行プロンプトに不向き。
  • かといってターミナルバッファ (vterm/eat/ghostel) に直接打つと、ターミナルモードが多くのキーを横取りして ddskk などのキーバインドが壊れる

どちらも嫌なので、独立した text-mode のバッファでプロンプトを編集して、まとめて送る UI が欲しかった。

解決1: claude-code-ide-ghostel — ghostel バックエンド

ghostel は libghostty (Ghostty ターミナルエミュレータの C 実装) の VT パーサ部分を Emacs のネイティブモジュールとして使うパッケージ。ターミナル状態管理が C 側に降りているので、Emacs の main loop は数マイクロ秒で xelb に戻れる。

claude-code-ide は内部で claude-code-ide-terminal-backend ('vterm / 'eat) で分岐しているので、そこに 'ghostel を足す形で :around advice を当てている。

インストール

;; leaf.el を使う場合
(leaf claude-code-ide
  :when (executable-find "claude")
  :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)
  (setq claude-code-ide-cli-extra-flags "--remote-control"))

(leaf claude-code-ide-extras
  :vc (:url "https://github.com/frenzieddoll/claude-code-ide-extras.git" :rev :newest)
  :require t
  :bind ("C-c j" . claude-code-ide-compose)
  :custom (claude-code-ide-terminal-backend . 'ghostel)
  :config
  (claude-code-ide-ghostel-mode 1))

ghostel 本体は現時点で MELPA に無いので、一度だけ手で入れる:

M-x package-vc-install RET https://github.com/dakra/ghostel RET
M-x ghostel-download-module RET

ghostel-download-module がプラットフォーム向けの prebuilt なネイティブモジュールを取ってきてくれる。zig などのツールチェインは要らない。

効果

私の EXWM 環境では、eat バックエンド時に出ていた「Claude が高速に出力している間 WM 操作が固まる」状態が再現しなくなった。

(注: EXWM 上で eat がフリーズする問題は私の実体験ベースの話で、claude-code-ide.el のリポジトリに公式なバグ報告として上がっているわけではない。ただメカニズム的には xelb と eat がどちらも main loop を奪い合う以上、似た構成なら再現してもおかしくないと思う。)

解決2: claude-code-ide-compose — 複数行プロンプト用 child frame

text-mode の child frame を Claude バッファの下端に重ねて、複数行プロンプトを編集・送信するための UI。

キー 動作
M-x claude-code-ide-compose compose overlay を開く
C-c C-c 内容を Claude に送信して閉じる
C-c C-k 破棄 (overlay を閉じる。下書きは残る)
C-u M-x claude-code-ide-compose 下書きを消して開き直す

中身は text-mode バッファそのものなので:

  • ddskk / mozc など IM がそのまま動く
  • RET で送信されない (普通の改行になる)
  • 編集中は Emacs の編集機能 (移動・kill ring・undo …) が全部使える

送信時には、バッファ内の改行を \\ + RET (Claude の in-prompt newline 規約) に変換して送るので、Claude 側では「複数回の送信」ではなく「1回の複数行プロンプト」として届く。これは upstream の claude-code-ide-insert-newline の慣習に合わせている。

おまけ: C-g を Emacs 側に届ける

Claude CLI は標準で C-g を自分で消費する。なので、ターミナルバッファ上で C-g を押しても Emacs の keyboard-quit が走らない。Emacs ユーザーは C-g を連打する習慣があるので地味に困る (evil-mode ユーザーだと、思わぬ state 遷移を起こすこともある)。

~/.claude/settings.json で Chat コンテキストの ctrl+g を無効化すると、C-g がそのまま端末に流れ、Emacs の keyboard-quit まで届く:

{
  "binding": [
    {
      "context": "Chat",
      "bindings": {
        "ctrl+g": null
      }
    }
  ]
}

Claude 本体側の設定なので、バックエンド (ghostel / vterm / eat) は問わない。

まとめ

  • EXWM で claude-code-ide.el を使うなら ghostel バックエンドを試す価値がある
  • ターミナル上で日本語複数行プロンプトを書くなら child frame compose UI が便利
  • C-g 問題は ~/.claude/settings.json で解決

リポジトリは frenzieddoll/claude-code-ide-extras です。

動作確認環境

  • Emacs: 30.2
  • claude-code-ide.el: 09875f8
  • ghostel: 20260522.1543(elpa)
  • WM: EXWM
  • OS: Arch Linux
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?