以下のブログで紹介されている、tmuxのお勧め設定の中の「Alt+矢印でpane移動して、端まで行ったら隣のwindowへ飛ぶ」がとても良いと思ったのですが、自分の環境(Ubuntu Linux 24.04)では動かなかったので別の方法で実現しています。このブログに「みなさんもぜひ自分のおすすめ設定を教えてください。」とあるので、私の方法を書きます。


以下エントリに書いたように、最近GreenCloudという格安VPSを借りたことをきっかけにLinux上に開発環境を整備しなおしているのですが、そのなかでtmuxの設定も上記アイデアをもとに少し更新しました。

私が実現したかったのは以下の動作です。

  • ALT – 左右矢印キーでPaneを移動する
  • Paneの左端までいった時、右端までいった時には次のWindowに移動する(ループする)

OpenCodeに以下のようなスクリプトを書いてもらって、 ~/.conf/tmux/smart_pane_move.shとして保存し、chmod +xで実行権限をつけます。

#!/bin/bash
# smart_pane_move.sh
# Alt+arrow key navigation across panes and windows with circular wrapping
DIRECTION=$1
SESSION=$(tmux display-message -p '#S')
CURRENT_WINDOW=$(tmux display-message -p '#I')
MIN_WINDOW=$(tmux list-windows -t "$SESSION" -F '#I' | sort -n | head -1)
MAX_WINDOW=$(tmux list-windows -t "$SESSION" -F '#I' | sort -n | tail -1)
if [ "$DIRECTION" = "left" ]; then
# Check if at the leftmost pane
if [ "$(tmux display-message -p '#{pane_at_left}')" = "1" ]; then
if [ "$CURRENT_WINDOW" = "$MIN_WINDOW" ]; then
# At minimum window, wrap to maximum window's rightmost pane
tmux select-window -t "$SESSION:$MAX_WINDOW"
while [ "$(tmux display-message -p '#{pane_at_right}')" != "1" ]; do
tmux select-pane -R
done
else
# Move to previous window's rightmost pane
tmux select-window -t "$SESSION:$((CURRENT_WINDOW – 1))"
while [ "$(tmux display-message -p '#{pane_at_right}')" != "1" ]; do
tmux select-pane -R
done
fi
else
tmux select-pane -L
fi
elif [ "$DIRECTION" = "right" ]; then
# Check if at the rightmost pane
if [ "$(tmux display-message -p '#{pane_at_right}')" = "1" ]; then
if [ "$CURRENT_WINDOW" = "$MAX_WINDOW" ]; then
# At maximum window, wrap to minimum window's leftmost pane
tmux select-window -t "$SESSION:$MIN_WINDOW"
while [ "$(tmux display-message -p '#{pane_at_left}')" != "1" ]; do
tmux select-pane -L
done
else
# Move to next window's leftmost pane
tmux select-window -t "$SESSION:$((CURRENT_WINDOW + 1))"
while [ "$(tmux display-message -p '#{pane_at_left}')" != "1" ]; do
tmux select-pane -L
done
fi
else
tmux select-pane -R
fi
fi

あとは、これを.tmux.conf等の設定ファイルでキーバインドするだけです。

# Alt+左右矢印でpane移動(端まで行ったら隣のwindowへ循環)
bind -n M-Left run-shell "~/.config/tmux/smart_pane_move.sh left"
bind -n M-Right run-shell "~/.config/tmux/smart_pane_move.sh right"

この他には、あまり凝ったtmuxの設定はしていません。あえて言うならGit管理のTUIであるLazyGitをいつでも呼び出せるようにpopup設定している部分でしょうか。

## prefix - C-g でpopupでlazygitがオープン
bind C-g popup -E -d "#{pane_current_path}" -w 90% -h 90% "lazygit"
bind C-s popup -E -w 90% -h 90% "nvim ~/scratchpad.txt"

上記のように書いておくことで、Prefix (私の場合はCtrl-z) -> C-g と押すことで、Window内部にLazyGitがポップアップで現れ、操作を終えたらすぐ元のWindowに戻れますので、お勧めです。

参考までに、以下に.tmux.conf全体を記載します。多くの部分は https://github.com/hendrikmi/dotfiles/blob/main/tmux/tmux.conf で公開されているものを参考にしています。

# 参考 https://github.com/hendrikmi/dotfiles/blob/main/tmux/tmux.conf
# Enable 256-color and true-color (24-bit) support in tmux
set -g default-terminal "screen-256color" # Set terminal type for 256-color support
set -ga terminal-overrides ",*256col*:Tc" # Override to enable true-color for compatible terminals
# xterm keysを有効化
set-window-option -g xterm-keys on
# 基本設定
set -g set-clipboard on # システムクリップボードを使用する
set -g status-interval 3 # ステータスバーを3秒ごとに更新する(デフォルト: 15秒)
set -g escape-time 0 # ESCを押した際の遅延をゼロにする
set -g history-limit 1000000 # 履歴サイズを増やす(デフォルト: 2,000)
set -g mouse on # マウスサポートを有効にする、通常の選択はSHIFTを押しながら
set -g allow-passthrough on # ペイン内のプログラムがtmuxをバイパスできるようにする(例: 画像プレビュー)
set -g status-position bottom
set -g focus-events on # tmuxに端末のアクティブ/非アクティブ状態を通知
# 基本キーバインド
set -g prefix C-z # prefixキーをC-zに変更する
unbind C-b # デフォルトのprefixキーC-bを解除する
bind C-z send-prefix # Ctrl+z -> Ctrl+zで本来のCtrl+zを送信
# prefix無しのAlt (M-)にバインディング:IMEの状況に関係なく実行できるショートカット
# ただしAltは利用しているターミナルエミュレーターや、ターミナル内で実行しているソフトウェアでの設定とバッティングしないように注意が必要
# 他の方法としては、M-Cと書くと Alt-Shift-c なのでバッティングする場合、こちらにする事も検討
bind -n M-c new-window -c "#{pane_current_path}" # Alt+C: デフォルトでbashを起動(現在のディレクトリで)
# Alt+左右矢印でpane移動(端まで行ったら隣のwindowへ循環)
bind -n M-Left run-shell "~/.config/tmux/smart_pane_move.sh left"
bind -n M-Right run-shell "~/.config/tmux/smart_pane_move.sh right"
bind -n M-C command-prompt -p "Command:" "new-window -c '#{pane_current_path}' '%%'" # Alt+Shift+C: コマンドを指定して起動
bind -n M-n next-window # Alt+n で次のウィンドウ
#bind Space next-window # Prefix + スペースで次のウィンドウ
# prefix + "\" (円マーク) で左右分割
unbind %
bind \\ split-window -h -c "#{pane_current_path}"
# prefix + -で上下分割
unbind \"
bind – split-window -v -c "#{pane_current_path}"
# ペイン/ウィンドウ関連
bind w choose-tree -Zw # ウィンドウの一覧を表示
set -g base-index 1 # ウィンドウのインデックスを1から始める
set -g renumber-windows on # ウィンドウを閉じた時に番号を詰める
set -g pane-base-index 1 # ペインのインデックスを1から始める
# TPM https://github.com/tmux-plugins/tpm
# TPM プラグイン
set -g @plugin 'tmux-plugins/tpm'
set -g @plugin 'tmux-plugins/tmux-sensible'
set -g @plugin 'tmux-plugins/tmux-cpu'
# カラー設定
gray_light="#D8DEE9"
gray_medium="#ABB2BF"
gray_dark="#3B4252"
green_soft="#A3BE8C"
blue_muted="#81A1C1"
cyan_soft="#88C0D0"
# ステータスバー
set -g status-position top
set -g status-left-length 100
set -g status-style "fg=${gray_light},bg=default"
set -g status-left "#[fg=${green_soft},bold] #S #[fg=${gray_light},nobold] | "
set -g status-right " #{cpu_percentage}  #{ram_percentage} %m/%d %H:%M"
#set -g status-right "#[fg=cyan]#{?AWS_PROFILE,[#{AWS_PROFILE}],} #[default] #{cpu_percentage}  #{ram_percentage} %m/%d %H:%M"
#set -g status-right-length 40
set -g window-status-current-format "#[fg=${cyan_soft},bold]  #[underscore]#I:#W"
set -g window-status-format " #I:#W"
set -g message-style "fg=${gray_light},bg=default"
set -g mode-style "fg=${gray_dark},bg=${blue_muted}"
set -g pane-border-style "fg=${gray_dark}"
set -g pane-active-border-style "fg=${green_soft}"
# popup
## prefix – C-g でpopupでlazygitがオープン
bind C-g popup -E -d "#{pane_current_path}" -w 90% -h 90% "lazygit"
bind C-s popup -E -w 90% -h 90% "nvim ~/scratchpad.txt"
# bell
set -g bell-action any
set -g visual-bell off
# Initialize TMUX plugin manager (keep this line at the very bottom of tmux.conf)
run '~/.tmux/plugins/tpm/tpm'
view raw .tmux.conf hosted with ❤ by GitHub

コメントを残す