libvtermは端末状態を提供しemacs-libvtermがそれをEmacsへ接続する

「vterm」という呼び名は、端末エンジンのlibvtermとEmacsパッケージのemacs-libvtermを混同しやすい。libvtermはVT220、xterm、ECMA-48互換の端末エミュレーションを実装したC99ライブラリであり、単独ではウィンドウもEmacsバッファも表示しない。入力された制御シーケンスから端末状態を更新し、描画が必要になると埋め込み側が用意したコールバックを呼ぶ。

emacs-libvtermは、libvtermをEmacsの動的モジュールとして読み込む接続層である。PTYから受け取った出力をlibvtermへ渡し、libvtermが保持する文字、幅、前景色、背景色、属性から変更された行を組み立て、文字のプロパティを付けてEmacsバッファへ反映する。スクロールバックと端末サイズも動的モジュール側で端末状態に対応づける。Emacs Lisp側のvterm-modeは、プロセス管理、キーマップ、コピー用モード、TRAMPとの統合などを受け持つ。

flowchart LR
  APP[シェルやTUI] -->|PTYのバイト列| LIB[libvtermの端末状態]
  LIB -->|画面セルと変更通知| MOD[emacs-libvtermの動的モジュール]
  MOD --> BUF[Emacsバッファ]
  BUF -->|キー入力| APP

libvtermは描画先から独立しているため、同じ端末エンジンを別のアプリへ埋め込める。emacs-libvterm固有の操作性や制約をlibvtermの性質とみなすことはできない。たとえば、コピー用モード、シェル側の設定によるディレクトリ追跡、Emacs Lisp関数の呼び出しはemacs-libvtermが加える統合であり、libvtermそのものの機能ではない。

この分離はcomintとの違いも明確にする。comintはプロンプトと追記される入出力を管理するのに対し、libvtermはカーソル位置や画面セルを持つ端末状態を管理する。emacs-libvtermは後者をEmacsバッファへ投影するため、全画面TUIを扱える代わりに、通常時のキー入力はEmacsの編集ではなく端末アプリへ送られる。

agent-shell、Ghostel、vtermの比較では、emacs-libvtermはGhostelと同じ端末プロトコル層に位置する。違いは端末エンジンとEmacsへの接続方法にあり、emacs-libvtermはlibvtermをCの動的モジュールで接続し、Ghostelはlibghostty-vtをZigの動的モジュールで接続する。どちらもエージェント固有のツール呼び出しや権限要求を意味のあるデータとして受け取るわけではない。

https://www.leonerd.org.uk/code/libvterm/

https://github.com/akermu/emacs-libvterm

https://github.com/akermu/emacs-libvterm/blob/master/vterm-module.c

https://github.com/dakra/ghostel

#emacs #terminal #libvterm #vterm