tmux でペイン自動分割→全ペインまとめてディレクトリ移動→ウインドウ名リネームをできるようにしてみた

## はじめに

以前の記事で、tmux で最低限のペイン分割を試しました。

[tmux 起動時のペイン分割を設定ファイルを使って楽にする - Qiita](https://qiita.com/gotchane/items/77dc650084d0d4efa5be)

今回は、分割したペインに対し、コマンドを実行する例を例をいくつか試してみました。

## やりたかったこと

* 下記を tmux 新規セッション作成時・新規ウインドウ作成時に行いたい
  * ペインを自動で3分割
  * 分割したペイン全てのディレクトリを、peco 経由で ghq 管理している GitHub リポジトリのディレクトリに移動
  * ウインドウ名をカレントディレクトリ名に変更

## tl;dr

### 動作イメージ

こんな感じになりました。
※最後に、`C-b + a` コマンドで、全ペインキー送信を無効にしています。

![Apr-27-2019 09-23-58.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222030/71130177-5662-5edb-64d7-2eadaf9a6d3b.gif)


### 設定内容

最終的に以下のような設定を準備しました。いずれもカレントディレクトリに配置してます。

#### .zshrc：tmux 初期起動用

`.zshrc` にエイリアスを設定しています。

```zsh:.zshrc
alias tmuxg='tmux new-session \; source-file ~/.tmux.session.conf'
```

#### .tmux.conf：tmux 初期設定

```bash:.tmux.conf
# 新ウインドウを設定ファイルを読み込ませて起動
bind g new-window \; source-file ~/.tmux.session.conf

# 全ペインキー入力送信切り替え
bind a setw synchronize-panes \; display "synchronize-panes #{?pane_synchronized,on,off}"

# カレントディレクトリにウインドウ名を修正
set-option -g automatic-rename on
set-option -g automatic-rename-format '#{b:pane_current_path}'
```

#### .tmux.session.conf：ペイン分割・コマンド実行用 tmux ファイル

`tmuxg` 実行、 `bind g` 実行時に読み込ませているファイルは以下の通りです。

```bash:.tmux.session.conf
# ペイン1を上下に分割
splitw -d -t 1
# ペイン1（上ペイン）の縦幅をリサイズ
resize-pane -t 1 -D 10
# ペイン1 でコマンド実行
send-keys -t 1 nvim C-m
# ペイン2（下ペイン） を左右に分割
splitw -h -d -t 2
# 全ペインへのコマンド送信有効化
setw synchronize-panes on
send-keys -t 1 'cd $(ghq root)/$(ghq list | peco)' C-m
```

## 解説

以下、実行していることをかいつまんで解説します。

### 1. tmux 設定ファイルを読み込ませる

`source-file` コマンドをセッション作成やウインドウ作成後につけることで、tmux のセッション作成時に後から実行したい設定を追加する事ができます。

#### セッション作成後

zsh のエイリアスを作り、新規セッション作成時に読み込ませる形にしています。

```zsh:.zshrc
alias tmuxg='tmux new-session \; source-file ~/.tmux.session.conf'
```

#### ウインドウ作成後 

tmux の `C-b + g` キーに、新規ウインドウ作成時に読み込ませて起動する処理をバインドしています。

```bash:.tmux.conf
bind g new-window \; source-file ~/.tmux.session.conf
```

### 2. ペインを自動で分割する

こちらは以前の記事の内容と同様ですので、省略します。

[tmux 起動時のペイン分割を設定ファイルを使って楽にする - Qiita](https://qiita.com/gotchane/items/77dc650084d0d4efa5be)


### 3. コマンドを tmux ペインに送信する

以下は、1枚目のペインに、ghq/peco を利用したローカルリポジトリへのディレクトリに移動するコマンドを送信する設定です。

```bash:.tmux.conf
send-keys -t 1 'cd $(ghq root)/$(ghq list | peco)' C-m
```

`send-keys` で、ペインにコマンドを送信することが出来ます。`-t` オプションでどのペインに送信するかを指定し、シングルコーテーションで囲まれた文字列が送信したいコマンドに該当します。

`C-m` は bash や zsh のショートカットキーバインドで、`accept-line` という改行を表す readline の関数を実行します。

以下、bash、zsh どちらも `accept-line` が `C-m` にバインドされていることがわかります。

#### bash

```bash
$ bind -p | grep accept-line
"\C-j": accept-line
"\C-m": accept-line
```

#### zsh

```zsh
$ bindkey | grep accept-line
"^J" accept-line
"^M" accept-line
```

`cd $(ghq root)/$(ghq list | peco)` コマンドの解説は、以下記事が詳しいです。

[ghq, peco, hubで快適Gitライフを手に入れよう！ - Qiita](https://qiita.com/itkrt2y/items/0671d1f48e66f21241e2#%E3%83%AD%E3%83%BC%E3%82%AB%E3%83%AB%E3%83%AA%E3%83%9D%E3%82%B8%E3%83%88%E3%83%AA%E3%81%B8%E3%81%AE%E7%A7%BB%E5%8B%95--cd-ghq-rootghq-list--peco)

### 4. 分割したペイン全てに同じコマンドを実行する

`send-keys` のコマンドをすべてのペインに送信するために、キー入力を全てのペインに送信するためのオプションである、`synchronize-panes` オプションを on にする必要があります。

```bash
# 有効化
setw synchronize-panes on

# 無効化
setw synchronize-panes off
```

しかしすべてのペインへのキー送信がずっと有効にしていると面倒なこともあるので、以下設定で、`C-b + a` キーで、全てのペインへのキー送信設定のオンオフを切り替えられるようにしています。

```bash:.tmux.conf
# 全ペインキー入力送信切り替え
bind a setw synchronize-panes \; display "synchronize-panes #{?pane_synchronized,on,off}"
```

### 5. ウインドウ名をカレントディレクトリに変更

ウインドウを何枚か開くと、どのウインドウで何のリポジトリを開いているかわからなくなるときがあるので、自動でカレントディレクトリをウインドウ名にする設定を入れています。

`automatic-rename` オプションで自動リネームを有効にし、`automatic-rename-format` オプションで、現在開いているディレクトリをウインドウ名に設定しています。

```bash:.tmux.conf
# カレントディレクトリにウインドウ名を修正
set-option -g automatic-rename on
set-option -g automatic-rename-format '#{b:pane_current_path}'
```

## 終わりに

tmux 奥が深いです。マニュアルもっと読みこもうと思います。


## 参考

* [How to send a command to all panes in tmux? - Stack Overflow](https://stackoverflow.com/questions/16325449/how-to-send-a-command-to-all-panes-in-tmux)
* [How to automatically rename tmux windows to the current directory - Stack Overflow](https://stackoverflow.com/questions/28376611/how-to-automatically-rename-tmux-windows-to-the-current-directory)
* [tmuxのsynchronize-panesをtoggle化する方法 - Qiita](https://qiita.com/waieneiaw/items/22ed18809739c9a69f25)
* [bashのキーバインド(キーボードショートカット) まとめ - readlineとbind、ついでにstty編](https://hogem.hatenablog.com/entry/20090411/1239451878)