Tmux生活を送る

![Screenshot from 2020-08-30 19-50-18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415288/ca412834-ee68-5e81-ba7e-f40fcb4bfa5e.png)

いい感じのTmux環境を作成できたので、そのプロセスを共有する。
bashrc内で
tmux起動~tmuxのセッション内でコマンド実行
を行う方法はハマりがちなので共有する価値はあると思う。

## 環境
記事用にvirtualbox内で構築
OS:　Lubuntu-20.04.1-desktop-amd54
terminal: qterminal 0.14.1 (Lubuntuにデフォルトで入っているもの)
tmux: 3.0a

## tmuxをインストール

```terminal
sudo apt install tmux
```
## tmuxの設定

1.  ~/.tmux.confに設定を記述(ファイルがなければ作成)
- tmux source ~/.tmux.confで設定を読み込む
- tmuxのセッションに入って反映されているか確認  

#### 見た目調整の設定
prefixキー押下字のステータスバーの名前を反転させる設定は、どこを参照したか忘れてしまった
default-terminalとterminal-overridesの動作の詳細は未調査

```config
# ~/.tmux.conf

# appearance setting
set-option -g status-position top  #ステータスバーを下部から上部に変更
set-option -g status-style fg=red,bg=black  # タブの表示色を変更
# prefixキーを押したときにステータスバーのユーザ名の色を反転させる
set-option -g status-left '#[fg=cyan,bg=#303030]#{?client_prefix,#[reverse],} #H[#S] #[default]'
set-option -g default-terminal "xterm-256color"  #ターミナルに設定したカラースキームをtmuxでも使用する
set-option -ga terminal-overrides ',*256color:Tc'  # 同上 
```

#### 操作系の設定
デフォルトのprefixキーCtrl+b は微妙に押しづらいので、Ctrl+tに設定し直した
また、pane間の移動をvimのキーバインドに近いものにした

```config
# ~/.tmux.conf

# operation settings
set-option -g prefix C-t # Ctrl+tをprefixキーに変更
unbind C-b  # Ctrl+bをprefixから解除
## vim keybind
bind -r k select-pane -U 
bind -r j select-pane -D 
bind -r h select-pane -L 
bind -r l select-pane -R

## ペインをkillするとき、それが最後のペインでない限り確認なしにkillする
bind -r w if "tmux display -p \"#{session_windows}\" | grep ^1\$ && tmux display -p \"#{window_panes}\" | grep ^1\$" \
    "confirm-before -p \"Kill the only pane in the only window? It will kill this session too. (y/n)\" kill-pane" \
        "kill-pane"
```

##### 画面分割機能の設定
画面分割や新しいタブで新しいpaneを作った際に、その新しいシェルのカレントディレクトリは、命令を出したディレクトリではなくホームディレクトリになったしまう。
これは不便だ。
キーバインドを上書きして期待通りにする

```config
# ~/.tmux.comf
bind c new-window -c "#{pane_current_path}"
bind '"' split-window -c "#{pane_current_path}"
bind % split-window -h -c "#{pane_current_path}"
```

## terminal起動時に自動的にtmuxを起動する
tmux内でwindowやpaneを作ったときにもbashrcを読み込んでいるため、
普通に.bashrcにtmuxコマンドを記述すると、無限ループに陥る。
実際は無限ループは起こらないのだが、警告が表示されてダサい。
シェルレベルを判定し、シェルレベル１（terminal起動時）のみtmuxを実行するように記述する

```bash
# .bashrc
if [ $SHLVL = 1 ]; then
   tmux -2 
fi
```
#### Tips. terminal起動時のtmux自動実行の際、tmux内でコマンドを実行も自動化したい
htopコマンドやらscreenfetchコマンド、画面分割の命令等、tmux実行時にいつも行う作業は自動的に実行したい

しかしながら.bashrcのif内で

```bash
# .bashrc 失敗例
if [ $SHLVL = 1 ]; then
   tmux -2
   echo hello  # これはtmux内で実行されない
fi
```
としてもechoコマンドを実行する前にtmuxに入っているので、echoコマンドは実行されない
そこで、
1. tmuxのセッションをデタッチされた状態で作成
2. デタッチされたtmuxセッションに命令を送信
3. tmuxセッションにアタッチ
というプロセスを行えばよい

```bash
if [ $SHLVL = 1 ]; then
   tmux -2 new -d -s SES  # SESという名前のセッションをデタッチされた状態で作成
   tmux send-key -t SES.0 "echo hello" ENTER  # SESに命令を送信
   tmux a -t SES  # SESにアタッチ
fi
```
## 画面分割自動化コマンドの作成
いつも同じレイアウトの画面分割でコーディング作業をしているので、コマンド一発でそのレイアウトになるようにコマンドを作成する

**ホームディレクトリに、自作コマンド用のディレクトリを作成**

```bash
mkdir $HOME/bin
```
**環境変数にディレクトリを追加**
この作業は環境によっては不要
.bashrcに追記

```bash
# .bashrcに追記
PATH=$PATH:$HOME/bin
```
これで自作コマンド用のディレクトリを作成できた

**自作コマンド**
私が使っている画面分割コマンドを紹介
$HOME/bin/tmcというファイル名で保存している

```bash
#!/bin/bash
# filename: $HOME/bin/tmc
# exec Desktop
if [ "$1" = "desktop" ]; then
    tmux rename-window "Desktop"  # タブ名をDesktopに変更
    tmux split-window -v -p 67
    tmux select-pane -U
    tmux split-window -h -p 66
    tmux split-window -h -p 35
    tmux select-pane -D
    tmux split-window -h -p 66
    tmux select-pane -U

    tmux send-key -t 0 "htop" C-m  # pane番号0 でhtopコマンドを実行
    tmux send-key -t 1 "screenfetch_view" C-m  # screenfetch表示コマンド
    tmux send-key -t 2 "tty-clock -c -C 1" C-m  # 時計表示コマンド
    tmux send-key -t 3 "spt" C-m  # spotify-tuiを起動
    tmux send-key -t 4 "weather" C-m  # 天気予報コマンド
    exit
fi


# exec ide
if [ "$1" = "ide" ]; then
    tmux rename-window "IDE"

    tmux split-window -v -p 20
    tmux split-window -h -p 50
    tmux select-pane -U
    exit
fi

# kill other pane
if [ "$1" = "exit" ]; then
    tmux kill-pane -a
    exit
fi

# kill window
if [ "$1" = "exit!" ]; then
    tmux kill-pane -a
    tmux kill-window
    exit
fi            
```

``` bash
# Usage
tmc desktop  # トップに載せた画像のようなwindowを作成
tmc ide  # コーディング作業用windowを作成
tmc exit # 今居るpane以外のpaneをすべてkill
tmc exit! # windowをkill
```


## 参考
@ssh様『tmuxで最後のwindowの最後のpaneであるときだけ確認メッセージを出して、それ以外はそのままkillする』
https://qiita.com/ssh0/items/2c0f0aa1f5179efb02c3
『Tmux open new pane in same directory』
https://gist.github.com/william8th/faf23d311fc842be698a1d80737d9631