Panda Noir

JavaScript の限界を究めるブログでした。最近はいろんな分野を幅広めに書いてます。

tmuxのすべてのpaneでzshrcの再読み込みをする

卒論が全然終わらないしストレスがすごいです…はぁ…

とりあえず息抜きにこないだ作ったtmuxの設定を上げておきます。

モチベーション

zshrcを書き直したあとに、一括ですべてのpaneに変更を適用したいからです。いちいち全てのpaneに移動してsource ~/.config/zsh/.zshrcして回るのは怠いですよね?かといって# tmux kill-serverでいちいちtmuxを落とすのもスタイリッシュではありません*1

というわけで作ったのが下の設定です。

コード

適当なファイル名をつけて、次のファイルを保存してください(僕は~/.config/tmux/respawnに保存しています)

#!/bin/bash
# カレントディレクトリが変わらないようにしつつ、すべてのpaneに対してrespawn-paneする
tmux list-panes -as -F '#{pane_id} : #{pane_current_path}' | sed -e 's/ : /\n/' | xargs -n 2 bash -c 'tmux respawn-pane -c $1 -t $0 -k $SHELL'

そして、tmux.confに以下を追記してください。

bind-key R run-shell 'bash $XDG_CONFIG_HOME/tmux/respawn' # すべてのpaneをrespawnする

Prefix - Rを入力すると、すべてのpaneのシェルが再起動します。

注意点

respawn-paneは起動しているシェルをkillします。そのため、何かしら走らせた状態ではゼッタイに実行しないでください。僕は一切の責任を取りません。

動作原理

まず概要を話すと、

  1. 全てのpaneの、idとカレントディレクトリを列挙
  2. 取得したidとカレントディレクトリを使ってrespawn-paneをする

これだけです。

1. 全paneのidとカレントディレクトリを列挙

tmux list-panes -as -F '#{pane_id} : #{pane_current_path}'の部分です。これを実行すると、たとえば次のような感じになります。

%0 : /home/pandanoir/hoge
%1 : /home/pandanoir/Documents/sotsuron-tsurai

さらに、xargsに渡して良しなにやるために、idとディレクトリパスのあいだで改行します(| sed -e 's/ : /\n/'の部分です)。tmux単体ではidとcurrent pathのあいだに改行ができなかったので仕方なくsedを使っています…

%0
/home/pandanoir/hoge
%1
/home/pandanoir/Documents/soturon-turai

2. すべてのpaneに対してrespawn-paneする

これを| xargs -n 2 bash -c "SCRIPT"につなげてやると、SCRIPTが $0に#{pane_id}、$1に#{pane_current_path}が格納された状態で実行されます。つまり、tmux respawn-pane -c #{pane_current_path} -t #{pane_id} -k $SHELLとなります*2

終わりに

要は、カレントディレクトリが変わらないようにしつつ、respawn-paneをすべてのpaneに対して実行しているだけです。bash scriptだから可読性が著しく悪いだけで、文章にすると明瞭ですね。

作ってて思いましたが、需要ありそうだし普通にpluginとして公開しようかな…卒論が終わったら

*1:僕はかれこれ3年くらい思考停止でkill-serverしてました

*2:-tはどのpaneをrespawnするか指定するオプション、-cオプションはカレントディレクトリを指定するオプションです