5 分で読了 #tools

Zellij

tmuxの代わりに使っていますが、主な理由は設定が構造化されたKDL形式であること、プラグインがWASMで動作すること、レイアウトをファイルとして保存できることです。しかし、私にとってこれらが必須である唯一の理由は、Neovimとのシームレスなナビゲーションです。

nvim内でCtrl+h/j/k/lを押すとvimウィンドウが切り替わり、端まで移動するとさらに押すことでフォーカスが隣接するZellijパネルに直接移動します。逆も同様です。画面全体がグリッド状に分割され、「今、カーソルがvim内にあるのかzellij内にあるのか、どのキーバインディングを使うべきか」といったことを意識する必要がありません。Ctrl+hjklの1セットで全てを操作できます。これは、nvim側のsmart-splitsと、Zellij側のvim-zellij-navigatorプラグインが連携することで実現しています。

この仕組みを成立させるためには、Zellijがキーバインディングを奪わないことが前提です。デフォルトでは多くのショートカットキーが消費され、下部のプロセスと競合するため、lockedモードで常駐させています。これにより、基本的にはキーを一切奪わず、nvimやシェルに委ねます。Ctrl+gを押した時のみ独自のnormalモードに入り、パネル分割やタブ操作などのコマンドを実行します。

locked {
    bind "Ctrl g" { SwitchToMode "normal"; }
}
shared_except "tmux" {
    bind "Alt e" { EditScrollback; }   // スクロールバックバッファをnvimに渡して検索
    bind "Ctrl h" { MessagePlugin ".../vim-zellij-navigator.wasm" {
        name "move_focus_or_tab"; payload "left"; move_mod "ctrl"; }; }
    // j/k/l も同様
}

Alt eのコマンドは頻繁に使用しています。ログが流れてしまった際、ワンクリックでスクロールバック内容をnvimに渡して、検索やコピーがすぐにできます。

normalモード(Ctrl+g)に入ると、モード別の操作になります。Zellijの設計思想は「親メニュー+サブキー」です。pでpaneモード(さらに矢印キーでパネルを開いたり切り替えたり)、tでtabモード、rでresizeモード、sでscroll/searchモード、oでsessionモードに入ります。tmuxの「プレフィックスキー+覚えるべき多数の文字」と比較すると、各モードに入った際に下部バーに利用可能なキーが直接表示されるため、ほとんど暗記する必要がありません。よく使うのは、パネルを開く、タブを切り替える、wでパネルを浮き上がらせて一時的なウィンドウにする、fで全画面に集中する、などです。

マルチプレクサに真の価値があるのはセッションの永続化です。この点は特に触れておく価値があります:

  • detach / attach: zellij attachで前回のセッションに再接続します。SSHが切断されたり、うっかりターミナルを閉じたりしても、実行中のプロセスや全体のレイアウトはそのまま保持されます。これは「ターミナルは置き換え可能だが、セッションは失わない」という私の原則の具現化です。
  • レイアウトのファイル保存⁠: よく使うワークスペース(例:左側にコード、右下にログ、右上にREPL)を.kdl形式のレイアウトファイルとして保存しておき、zellij --layout devで一括展開できます。毎回手動で切り替える必要がありません。レイアウト内では、各パネルの初期コマンドや作業ディレクトリを事前に設定できます。
  • resurrection(蘇生): セッションが異常終了した場合、Zellijはレイアウトを記録しており、次回起動時に「蘇らせる」ことができます。パネル構造が復元され、実行済みのコマンドをワンクリックで再実行できます。

配色とステータスバーはmatugenに合わせています(MaterialYou.kdl)。デフォルトのバーではなく、zjstatusを使用して自作しています。モード、タブ、セッション名、時刻などを独自のフォーマットで配置し、情報密度を高めつつ、デスクトップ全体のカラーテーマと統一感を持たせています。