【fish 版】ターミナル起動時に tmux の既存セッションをアタッチ

## この記事なに？
@ssh0 さんの [\[tmux\] 端末起動時に自動で新規セッションを作成 or 既存セッションにアタッチ \- Qiita](https://qiita.com/ssh0/items/a9956a74bff8254a606a)
という記事で解説されていた zsh の設定を、 fish 版に書き直してみたので紹介します。
軽くググってみても fish + tmux という環境で、ターミナル起動時に tmux の既存セッションをアタッチする記事がなかったので、備忘録を兼ねて書いておくことにしました。

## 実現したいこと
元記事で実現されていたのと同じ機能を fish で再現します。

1. ターミナル起動時に tmux のセッションが無ければ新しくセッションを作る
2. ターミナル起動時に tmux のセッションが残っていれば、セッションを選んでアタッチする
3. セッション選択時、`esc` キーを押すと tmux は起動しない
4. tmux のセッションをアタッチするのは fish がログインシェルで起動されたときのみ

## 前提
- fish + tmux のターミナル環境を使っている
- `~/.config/fish/config.fish` がなにかの説明はしないので、わからない方は別途調べてください🙏
- バージョン
  - fish >= 3.1
  - tmux >= 3.0

## config.fish
早速ですが、完成品の `config.fish` です。 

```shell
function attach_tmux_session_if_needed
    set ID (tmux list-sessions)
    if test -z "$ID"
        tmux new-session
        return
    end

    set new_session "Create New Session" 
    set ID (echo $ID\n$new_session | peco --on-cancel=error | cut -d: -f1)
    if test "$ID" = "$new_session"
        tmux new-session
    else if test -n "$ID"
        tmux attach-session -t "$ID"
    end
end

if test -z $TMUX && status --is-login
    attach_tmux_session_if_needed
end
```

### 1. ターミナル起動時に tmux のセッションが無ければ新しくセッションを作る
セッションが残っているかどうかは `tmux list-sessions` を実行すればわかります。
`tmux list-sessions` の結果を代入した `ID` が０文字であれば、セッションは無いので、新しいセッションを作ります。

fish は `=` で変数に代入できないので、代わりに `set` コマンドを使います。
コマンドの実行結果を変数に入れるには、コマンドを `()` で囲みます。

```shell
    set ID (tmux list-sessions)
    if test -z "$ID"
        tmux new-session
        return
    end
```

### 2. ターミナル起動時に tmux のセッションが残っていれば、セッションを選んでアタッチする
`if test -z "$sessions"` の条件を満たさなかったということは、セッションが残っているということなので、セッションをアタッチします。
まず、`peco` でアタッチするセッション一覧をユーザに選ばせます。
`fzf` を使っている方は適宜読み替えてください。
`tmux list-sessions` の結果からセッションIDだけを切り出して、`tmux attach-session` を実行しています。

```shell
    set ID (tmux list-sessions)
    # peco でセッションを選んでもらう
    set ID (echo $ID | peco | cut -d: -f1)

    #略...
    else if test -n "$ID"
        tmux attach-session -t "$ID"
    end
```

あと、セッションが残っていても、新しくセッションを作れるように、`Create New Session` という文字列をセッション一覧の最後に入れてます。

```shell
    set new_session "Create New Session" 
    set ID (echo $ID\n$new_session | peco | cut -d: -f1)
    if test "$ID" = "$new_session"
        # "Create New Session" を選ぶと新しくセッションを作る
        tmux new-session
    else if test -n "$ID"
        tmux attach-session -t "$ID"
    end
```

### 3. セッション選択時、`esc` キーを押すと tmux は起動しない
これは `peco` を使ったときの実装ですが、`peco` をキャンセルしたときの挙動をエラーにしておくと実現できます。
`peco --on-cancel=error` と書くと、`peco` を `ecs` キーでキャンセルしたとき、 `ID` の文字列が 0文字になります。
なので、`esc` キーを押したときは `else if test -n "$ID"` を満たさなくなり、 tmux はセッションをアタッチしなくなります。

```shell
    set new_session "Create New Session" 
    set ID (echo $ID\n$new_session | peco --on-cancel=error | cut -d: -f1)
    if test "$ID" = "$new_session"
        tmux new-session
    else if test -n "$ID"
        tmux attach-session -t "$ID"
    end
```

### 4. tmux のセッションをアタッチするのは fish がログインシェルで起動されたときのみ
fish は `status` というコマンドで fish の実行状態を確認できます。
`status` はいろいろな状態を判定できますが、今回はログインシェルとして起動しているか知りたいので、`status --is-login` を使います。
よって、ターミナル起動時かつログインシェルとして fish が起動された、という条件は以下のように書きます。

```shell
if test -z $TMUX && status --is-login
    attach_tmux_session_if_needed
end
```

## まとめ
こんな感じで動きます。

### 新規セッションを作成
![tmux-newsession.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76862/1c8d750f-3757-8d4f-e41e-2d4853c3a561.gif)


### 既存のセッションをアタッチ
![tmux-attach.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76862/9cdbeceb-d0ca-caa9-0359-70f5bd6e1b55.gif)