tmuxマルチセッション運用——AI時代を1キーバインドで乗り切る

AIエージェント時代が始まってから「Git worktree便利だよ」とあちこちで言われるようになりました。
ワークツリーは使うと便利なんですが、問題になるのが tmuxのウィンドウ数の多さ です。

ウィンドウが多いと ステータスバーがごちゃごちゃして見づらい ですし、別のウィンドウに移動したいときに 認知負荷が高い です。

そんなわけで tmuxのマルチセッション運用 に手を出してみたらめっちゃスッキリしたので、解説します。

筆者のマルチセッション管理画面

どんなふうにセッションを分けるの?

そもそもtmuxのセッション・ウィンドウ・ペインの違いを知らない方は別の記事【tmux入門】基本的な使い方を先にご覧ください。

セッションの分け方はぶっちゃけ人それぞれだと思いますが、筆者の例を書いておきます。

  • dotfiles + ブログ のセッション
    • dotfiles、ブログで2ウィンドウくらい
  • 仕事のメインセッション
    • 今自分が開発している機能関係 のウィンドウたち
    • API、ダッシュボード、アプリみたいな感じで3以上はある
  • 仕事のサブセッション
    • PRレビュー、不具合調査など 一時的なやつら
    • メインセッションでウィンドウが増えすぎたときだけ作る
  • 開発中の自作ツール のセッション
    • 仕事中はあまり開かないので別セッションに分けるとスッキリする

筆者が勘違いしていたこと

筆者は以前勘違いしていたのですが、 セッションを切り替えても既存のセッションは生きています 。ウィンドウを行き来するのと同じようにすぐ切り替えできます。

また、プラグインtmux-resurrectは複数のセッションがあっても問題なく動きます。

基本的な使い方まとめ

後で紹介するキーバインドがあるので 覚える必要は無い ですが、デフォルトで用意されているコマンド・キーバインドも書いておきます。

詳細なオプションまで知りたい人はman 1 tmuxを実行し^\s*コマンド名で検索してみてください。

セッションの一覧

Terminal window
tmux list-sessions

実行するとセッションの情報が表示されます。今アタッチしているやつは(attached)が付きます。

foo: 2 windows (created Wed Nov 12 09:34:17 2025)
default: 2 windows (created Wed Nov 12 09:34:15 2025) (attached)
bar: 7 windows (created Wed Nov 12 09:34:16 2025)

セッションの作成

セッションを新しく作るなら次のコマンドを実行します。

Terminal window
tmux new-session -d -s "セッション名"

-dを付けないとtmux内では実行できないようです。また、tmux外から実行したときに-dを外すとすぐアタッチされます。

セッションの切り替え

これだけコマンド名にsessionが無いので注意です。

Terminal window
tmux switch-client -t "セッション名"
# または
tmux choose-tree

choose-treeはキーバインドprefix+s(セッションのみ)やprefix+w(ウィンドウ込み)で実行できます。

choose-treeの例

ウィンドウの描画が十分に大きければ、画像のように 開いているウィンドウがプレビュー されます。

セッションの削除

セッションの削除は次のコマンドです。

Terminal window
tmux kill-session -t "セッション名"

セッション名変更

名前を変えるならrename-sessionです。

Terminal window
tmux rename-session -t "変更前" "変更後"

セッション管理を1キーバインドに集約する

もしかしたらすでにお腹いっぱいかもしれませんがここからが本番です。

筆者はコマンドを覚えるのも打つのも面倒であるため、セッション管理を1つのキーバインドに集約しています。

セッション管理キーバインドはこんな感じ

設定したキーバインドを押すとセッション一覧が表示されます。

筆者のマルチセッション管理画面

この画面の操作方法も表示しているので、 覚えるのはこのスクリプト起動のキーバインド1つだけ です。

切り替えはfzf

文字入力で絞り込んだりCtrl+pnで上下してEnterを押したら切り替わります。

追加・リネームもできる

Ctrl+tを入力後、セッション名を入力してセッションを作成できます。

筆者はステータスバーのわかりやすさのためにNerd Fontsのアイコンも表示するのでアイコン選択UIも出してます。

同様にCtrl+rでリネームもできます。

削除もできる

Ctrl+qで削除できます。いきなり消すのは怖いので最後にyを押さないと消しません。

スクリプトtmux-session-manager

長いので折りたたみの中に書きます。

クリックで開閉
tmux-session-manager
#!/bin/bash
# アイコン選択関数
select_icon() {
selected=$(cat <<'EOF' | fzf --prompt="Icon: " --preview-window=hidden
: default
󱄅 : nix
: paw
: key
: fan
: cut
: setting
: bug
: db
: tag
: sun
: pin
: script
󰐟 : poll
󰇥 : duck
󱗆 : bird
: wind
: tree
: tint
: tool
: suse
: save
: plug
: mask
: leaf
: home
: gift
: frog
: fish
: bone
: neovim
󰢱 : lua
: cpp
: typescript
: pen
EOF
)
if [ -n "$selected" ]; then
echo "$selected" | awk '{print $1}'
else
# キャンセルされた場合はデフォルト
echo ""
fi
}
# セッション一覧を整形してソート
sessions=$(tmux list-sessions -F '#{session_name}' 2>/dev/null | while read -r s; do
if [ "$(echo "$s" | cut -c2)" = " " ]; then
echo "$(echo "$s" | cut -c3-)|$s"
else
echo "$s|$s"
fi
done | sort | cut -d'|' -f2)
# tmuxセッション一覧をfzfで表示し、アクションを実行
result=$(echo "$sessions" | \
fzf --prompt="Session: " \
--preview='tmux list-windows -t {} -F "#{window_index}: #{window_name}"' \
--preview-window=right:20% \
--expect=ctrl-q,ctrl-t,ctrl-r \
--no-select-1 \
--header='Enter: switch | ^Q: kill | ^T: new | ^R: rename')
# fzfがキャンセルされた場合は終了
if [ -z "$result" ]; then
exit 0
fi
# 結果を解析(1行目がキー、2行目が選択されたセッション名)
key=$(echo "$result" | sed -n '1p')
session=$(echo "$result" | sed -n '2p')
# アクションに応じて処理
case "$key" in
ctrl-q)
# kill: セッション削除
if [ -n "$session" ]; then
echo -n "Kill session '$session'? (y/N): "
read -r answer
if [ "$answer" = "y" ] || [ "$answer" = "Y" ]; then
# カレントセッションかチェック
current_session=$(tmux display-message -p '#S')
if [ "$session" = "$current_session" ]; then
# カレントセッションの場合は次のセッションに移動してから削除
tmux switch-client -n
fi
tmux kill-session -t "$session"
echo "Session '$session' killed."
else
echo "Cancelled."
fi
fi
;;
ctrl-t)
# new: 新規セッション作成
echo -n "New session name: "
read -r new_session
if [ -n "$new_session" ]; then
# アイコン選択
icon=$(select_icon)
full_session_name="$icon $new_session"
tmux new-session -d -s "$full_session_name"
tmux switch-client -t "$full_session_name"
echo "Session '$full_session_name' created."
else
echo "Cancelled."
fi
;;
ctrl-r)
# rename: セッション名変更
if [ -n "$session" ]; then
echo -n "New name for '$session': "
read -r new_name
if [ -n "$new_name" ]; then
# アイコン選択
icon=$(select_icon)
full_session_name="$icon $new_name"
tmux rename-session -t "$session" "$full_session_name"
echo "Session renamed to '$full_session_name'."
else
echo "Cancelled."
fi
fi
;;
*)
# switch: セッション切り替え(Enterの場合)
if [ -n "$session" ]; then
tmux switch-client -t "$session"
fi
;;
esac

fzfインストール済みが前提です。
使う時はパスを通した所に配置して実行権限を付けます。

Terminal window
chmod +x tmux-session-manager

次のようにキーバインドに登録し、設定をリロードします。

.tmux.conf
bind-key m display-popup -E -w 80% -h 80% "tmux-session-manager"

うまく実行できない場合

もしパスを通したのに実行できない場合、tmuxがまだパスを認識できてない可能性があります。

-Eを外して実行したときにno such file or directoryのような表示であればパスが認識されていません。次のコマンドで 一度tmuxサーバーを終了してから 再度tmuxを立ち上げましょう。

Terminal window
tmux kill-server

とはいえ普通のキーバインドも便利

セッション切り替えはキーバインド設定してます。

.tmux.conf
bind-key -n M-k { switch-client -p; refresh-client -S }
bind-key -n M-j { switch-client -n; refresh-client -S }

refresh-client -Sを指定すれば切り替え後にすぐステータスバーが更新されます。

ステータスバーをアイコンでスッキリ表示

ここからはステータスバーの設定です。前述のとおり筆者はNerd Fontsのアイコンを付けています。
ステータスバーに全セッション名を表示するのは長くて見づらいからです。

画像の水色の部分がセッション情報です。

ステータスバーにもセッション情報を表示

カレントセッションは「アイコン+名前」、それ以外はアイコンだけにしています。

スクリプトtmux-status-sessions

クリックで開閉

#{@c-base-100}などの変数は別途設定した色の値です。別の記事tmuxのステータスライン設定方法!〜カスタマイズしやすいテンプレ付き〜で解説しています。

tmux-status-sessions
#!/bin/bash
current_session=$(tmux display-message -p '#{session_name}')
bg="#{@c-base-100}"
color="#{@c-info}"
text_fg="#{@c-info-content}"
output="#[bg=$bg,fg=$color]"
# セッション一覧を整形してソート
sessions=$(tmux list-sessions -F '#{session_name}' 2>/dev/null | while read -r s; do
if [ "$(echo "$s" | cut -c2)" = " " ]; then
echo "$(echo "$s" | cut -c3-)|$s"
else
echo "$s|$s"
fi
done | sort | cut -d'|' -f2)
# セッション一覧を取得してループ
while IFS= read -r session; do
# 2文字目が空白かチェック
second_char=$(echo "$session" | cut -c2)
if [ "$second_char" = " " ]; then
# "<アイコン> <名前>" 形式
icon=$(echo "$session" | cut -c1)
session_name=$(echo "$session" | cut -c3-)
else
# 通常のセッション名
icon=""
session_name="$session"
fi
if [ "$session" = "$current_session" ]; then
# カレントセッション:アイコン+名前+区切り
output+="#[bg=$color,fg=$text_fg]$icon $session_name#[bg=$bg,fg=$color] "
else
# その他:アイコンのみ
output+="$icon "
fi
done <<< "$sessions"
echo -n " $output "
Terminal window
chmod +x tmux-status-sessions
.tmux.conf
set-option -g status-left '#(tmux-status-sessions)'
set-option -g status-left-length 30

status-left-lengthを設定しないとデフォルトが10文字ですぐはみ出るので注意しましょう。

ウィンドウを別セッションに移動

あると便利なのが ウィンドウを別のセッションに移動する キーバインドです。これもfzfを使います。

クリックで開閉
tmux-move-window
#!/bin/bash
if [ -z "$TMUX" ]; then
echo "Error: This command must be run inside tmux."
exit 1
fi
# 現在のセッション名とウィンドウ情報を取得
current_session=$(tmux display-message -p '#S')
current_window=$(tmux display-message -p '#I')
window_name=$(tmux display-message -p '#W')
window_id=$(tmux display-message -p '#{window_id}')
# 現在のセッション以外のセッション一覧を取得してfzfで選択
target_session=$(tmux list-sessions -F '#{session_name}' 2>/dev/null | \
grep -v "^${current_session}$" | \
fzf --prompt="Move window '${window_name}' to: " \
--preview='tmux list-windows -t {} -F "#{window_index}: #{window_name}"' \
--preview-window=right:50% \
--header="Moving window ${current_window}: ${window_name}")
# fzfがキャンセルされた場合は終了
if [ -z "$target_session" ]; then
exit 0
fi
# ウィンドウを移動先セッションに移動
tmux move-window -t "${target_session}:"
# 移動したウィンドウにフォーカス
tmux switch-client -t "${window_id}"
Terminal window
chmod +x tmux-move-window
.tmux.conf
bind-key M display-popup -E -w 80% -h 80% "tmux-move-window"

以上、tmuxのマルチセッション運用の解説でした。自作キーバインドのおかげで覚えるコマンドが減って快適です。
最初は「セッション名にアイコン付けると問題あるかなぁ〜」とちょっと心配でしたが、今のところ問題なく動いてます。

今回のスクリプトで初めてfzfのexpectオプションを知りましたがこれもめっちゃ便利です。