vde-layoutの使い方――tmuxのレイアウトをコマンド一発で再現
筆者のtmuxのレイアウトは、どのウィンドウでもほぼ似たような感じです。
左上にエディタ、左下に開発サーバー、右上にClaude Code、右下にeditprompt。

分割・サイズ調整・コマンド実行を 1日に数回繰り返すのが面倒 でした。また、 対角ペインへの移動は別ペイン経由が必須 なのも面倒でした。
「この面倒を解消してくれるツールvde-layoutがあったな」とvim-jpのSlackで思い出しました。使ってみたら良かったので解説します。
## vde-layoutとは
vde-layoutはターミナルのレイアウトをYAMLファイルで宣言的に定義して、コマンドを叩くだけで サクッとレイアウトを適用 できるツールです。
tmuxのほか、weztermにも対応しているようです。
単に画面を分割したりサイズを調整するだけでなく、 ペインを開きつつ指定したコマンドを実行できます 。
## 導入方法
導入方法を載せておきますが、最新の手順はリポジトリのREADMEをご覧ください。
### 前提
- Node.js:22以上
- tmuxのレイアウトの場合: tmux2.0以上
- weztermのレイアウトの場合:weztermのnightlyビルド
※この記事はvde-layout v1.1.1で確認して書きました。
### インストール
npmでパッケージとして公開されているので、npmでインストールします。
npm install -g vde-layout筆者はbunを使ってインストールしました。
bun add -g vde-layout## 設定ファイルの配置
全体の設定は~/.config/vde/layout/config.ymlに書きます。拡張子はymlじゃないと認識されません。
※プロジェクト毎の設定は ./.vde/layout/config.yml に置きます。
## レイアウトの書き方
レイアウトの一覧はpresetsに書き、レイアウト自体はlayoutに書きます。
presets: test: # vde-layout test のように引数で指定する時のプリセット名 name: test # tmuxやweztermでの表示名 description: Editor/Server | Claude # 人間用の説明 layout: # ...### 先に分割無しの書き方
ペイン毎の設定を説明するために、「分割無しのレイアウト」を先に解説します。
「新しいウィンドウでログを開く」というレイアウトです。
presets: logs: name: logs command: tail -f /var/log/system.log windowMode: new-window # new-window | current-window次のコマンドを実行するとレイアウトが作成されます。
vde-layout logslayoutを指定せずcommandを書くと分割無しになります。
windowModeは次の2つを指定できます。
new-window:新しいウィンドウで開くcurrent-window:他のペインを閉じてから今のウィンドウで開く
設定ファイルには書かずに引数で--current-windowなどの指定もできます。
### 分割レイアウト
分割する場合はtype・ratio・panesを指定します。
layout: type: vertical ratio: [7, 3] panes: # 上 - name: editor command: nvim focus: true # 起動後にこのペインへフォーカス # 下 - name: terminalnameはペインの名前、commandはコマンドです。
commandは未指定でも大丈夫です(単にペインを開くだけ)。
#### type
- horizontal(左右に分割)
- vertical(上下に分割)
#### ratio
サイズを書きます。数字なら割合、"12c"のように書いたらセルの数で幅や高さを指定できます。
### 分割をネストしたレイアウト
続いて、分割のネストしたレイアウトです。
panesをネストして書きます。
layout: type: horizontal ratio: [1, 1] panes: # 左側 - type: vertical ratio: [1, "7c"] panes: # 左上 - name: "other" # 左下 - name: "server" # 右側 - type: vertical ratio: [1, "7c"] panes: # 右上 - name: "claude" command: claude # 右下 - name: "editprompt" command: >- editprompt open --editor nvim --target-pane {{pane_id:claude}} --always-copy ephemeral: true # 実行後にペインを閉じる focus: true{{pane_id:claude}}のように書くと、指定したペインのIDを埋め込めます。
その他にもenvで環境変数、cwdでディレクトリ指定などができます。詳しくはREADMEを見てください。
## 筆者の設定
ここからは筆者が実際に使っている設定の紹介です。
### 特定の種類のキーバインドにジャンプ
記事冒頭に書いたように、筆者はたまに 対角のペインに移動したくなります。
これを次のように設定することで1キーバインドだけで移動できるようにしました。
- vde-layout起動時にtmuxのペイン変数
@roleにペインの種類を書いておく(claude、serverなど) - 「ペイン変数
@roleが指定した種類のペインに移動」というキーバインドを設定
#### レイアウト設定
commandで;を使い、複数コマンド実行してます。
presets: dev: name: dev description: Editor/Server | AI/editprompt layout: type: horizontal ratio: [1, 1] panes: - type: vertical ratio: [1, "12c"] panes: - name: "other" command: >- tmux set-option -p -t {{this_pane}} @role other; git status -s | grep . || echo '変更なし' - name: "server" command: "tmux set-option -p -t {{this_pane}} @role server" - type: vertical ratio: [1, "10c"] panes: - name: "claude" command: >- tmux set-option -p -t {{this_pane}} @role claude; claude - name: "editprompt" command: >- tmux set-option -p -t {{this_pane}} @role editprompt; node ~/ghq/github.com/eetann/editprompt/dist/index.js open --editor nvim --target-pane {{pane_id:claude}} --always-copy ephemeral: true focus: true#### フォーカス用のスクリプト
続いて、キーバインドで実行する処理です。今のウィンドウのペインを取ってきて、@roleが指定したペインの種類ならフォーカスします。
#!/bin/bash
if [ -z "$TMUX" ]; then echo "Error: This command must be run inside tmux." exit 1fi
if [ -z "$1" ]; then echo "Usage: tmux-focus-pane role" exit 1fi
pane_id=$(tmux list-panes -F "#{pane_id} #{@role}" | awk -v t="$1" '$2 == t {print $1}')
if [ -n "$pane_id" ]; then tmux select-pane -t "$pane_id"else # フォーカスできなかったことを伝えるため exit 1fiこれをtmux-focus-paneとして呼び出せるようにします。
#### キーバインドを設定
-nを付けることで、tmuxのprefix無しでさきほど書いたスクリプトtmux-focus-paneを実行します。
bind-key -N "otherペインにフォーカス" -n M-e run-shell "tmux-focus-pane other"bind-key -N "serverペインにフォーカス" -n M-s run-shell "tmux-focus-pane server"bind-key -N "claudeペインにフォーカス" -n M-c run-shell "tmux-focus-pane claude"bind-key -N "editpromptペインにフォーカス" -n M-q run-shell '\ #{@editprompt-cmd} resume --target-pane #{pane_id} || \ tmux-focus-pane editprompt || \ tmux split-window -v -l 10 -c "#{pane_current_path}" \ "tmux set-option -p -t \$TMUX_PANE @role editprompt \ && #{@editprompt-cmd} open --editor nvim --target-pane #{pane_id} --always-copy" \'editpromptのペインは、一度閉じたときにもまた@roleを付与しつつペインが開けるようにしました。
これで、どのペインにいても一発で移動できます。割り当てるキーは、Alt+1とか番号でもいいかなと考え中です。
### ペインをリセット
ペインを1つだけにしたいときに使うレイアウトです。
プロセスもまとめて終了してくれるようなので重宝してます。
presets: empty: name: empty description: プロセス終了用の単一ペイン command: "" windowMode: current-windowvde-layout emptyコマンドは入力が面倒なのでvemptyでzeno.zshに登録してます。
以上、vde-layoutの使い方の解説でした。何度も同じ操作をしてたのが1キーバインドにまとまってスッキリしました。