これは快適！ Windows ターミナルでfish を使おう

## はじめに

Windows のターミナルといえば Powershell ですが、Windows でも Unix 系のシェルを使いたい！ ということで **fish（Friendly Interactive Shell）** を導入する手順をまとめました。WSL を利用する方法ではなく、**MSYS2** を使用することで、より Windows 上安定した環境を構築できます。この記事では、fish のインストールから VSCode との連携方法、便利な機能の活用までを解説します。

> 🐣 fish shell って書くとシェルシェルになってしまうので fish で統一します

---
## シェルについて

シェルは、コンピュータでターミナルを立ち上げたとき最初に立ち上がるプログラムです。
ユーザとカーネルの間を取り持つ「殻（shell）」という意味が由来なのだそうです。
CUI ベースで一番お世話になるプログラムですね。Windows だと以前はコマンドプロンプト、最近だと Powershell に相当します。Windows ではあまりバリエーションがありませんが、Unix だと以下のように多彩なシェルがあります。

- **sh**: ほぼすべての現代シェルの始祖的存在です。これより古いシェルは Thompson shell しかありません。
- **bash (Bourne Again Shell)**: sh の拡張版で Linux の標準シェルです。多くの機能拡張あり。読み方はバッシュﾘ=ﾜ_です。Windows でも ***Open Git Bash here*** のメニューでお馴染み？ですね。ちなみに Bourne は sh を開発した Stephen R. Bourne さんの名前からだそうです。知らなかった…

> 🐣 ずっと生まれ変わった sh だと思ってました

- **csh/tcsh**: C 言語風の文法を採用した独自路線のシェル。その拡張版 tcsh はその昔大人気だったらしいですが、最近ではあまり見かけません。

- **zsh (Z Shell)**: bash 互換で超多機能シェルです。macOS Catalina 以降の標準シェルとして採用。設定が少し面倒です。
- **fish (Friendly Interactive Shell)**: 最近人気の今回のターゲットです。シェルの名前は通常 sh で終わるため、お魚と掛けたユニークな命名と言われています。

では Windows でこの fish を動かしてみましょう。

> 🐣 お魚といえばやっぱりサーモン！

---

## Windows で fish を使うには？

Windows で fish を利用するには、いくつかの方法があります。

- **WSL (Windows Subsystem for Linux)**: Linux 環境を利用でき、fish も問題なく動作。ただし、Windows との親和性がやや低い。
- **Cygwin**: Windows 上で動作するほぼ完璧な UNIX 環境。ネイティブな Windows アプリとの互換性が少し低く、やや重い。
- **MSYS2**: 軽量で、Windows アプリとの相性が良い。ただし、UNIX 環境としての再現性は劣る。

WSL から VSCode を立ち上げれば Linux 環境との連携は容易ですが、微妙にもたつきを感じることがあるので見送りました。というわけで、今回は「fish を手軽に使いたい」という目的から、**MSYS2** を使用する方法を選択します。
> 🐣  正直 WSL からだと以下の一行だけで終わってしまって書くことがない…

```bash
sudo apt install fish
```

---

## MSYS2 のインストール

### MSYS2 のセットアップ

1. [MSYS2 公式サイト](https://www.msys2.org/)からインストーラーをダウンロードします。
2. インストール先は `C:\msys64` を推奨します（パスの問題が起きにくいです）。
3．MSYS2 のターミナルを立ち上げる。MSYS2 には複数のターミナル（MSYS、MINGW64、UCRT64 など）がありますが、fish のインストールや起動にはどれを使っても問題ありません。こだわりがなければ MSYS2 MSYS でいいでしょう。
4. インストール後、MSYS2 を起動して以下のコマンドを実行します。
   ```bash
   pacman -Syu
   ```
   **補足**: このコマンドは、MSYS2 のパッケージマネージャである `pacman` を使用して、システムを更新します。初回インストール時に必須のステップです。

### Windows の PATH について

MSYS2 の主要なコマンド群は `C:\msys64\usr\bin` に格納されています。

**PATH 設定の注意点**:
- Windows 標準の実行ファイルを優先したい場合は、MSYS2 の PATH を後ろに追加します。
- MSYS2 のコマンドを優先したい場合は、PATH の前に追加します。

これにより、Powershell からでも `less` や `grep` などのコマンドが使用可能になります。

---

## fish のインストールと初期設定

### fish のインストール

MSYS2 のターミナルで以下のコマンドを実行して fish をインストールします。

```bash
pacman -S fish
```

問題がなければ、`C:\msys64\usr\bin` に `fish.exe` がインストールされているはずです。

### 設定ファイルの作成

シェルの導入で一番の難関は最初の設定ファイルを準備する手間です。
でもご安心ください！ fish はほとんど何も設定しなくても、そのままでもバッチリ使えます。fish の設定ファイルは `~/.config/fish/config.fish` です。編集用のエディタは Windows のメモ帳や VSCode を使用しても構いませんが、せっかくなので以下のコマンドで Vim をインストールしておきましょう。

```bash
pacman -S vim
```

### 設定例

以下は fish の設定ファイルに記述する最低限の PATH 設定例です。必要に応じて内容を変更してください。

```bash
# PATH の設定
set -gx PATH /usr/local/bin /usr/bin /bin $PATH
```

基本的には、fish のデフォルト設定で問題なく動作します。ただし、**VSCode から直接 `fish.exe` を実行する場合**は、最低限の PATH 設定をしておくと安全です。

### ホームディレクトリの確認

fish ではホームディレクトリ `~` はデフォルトで以下に設定されています。

```
C:\msys64\home\ユーザ名
```

設定や環境によってはホームディレクトリの場所が異なります。その場合は、以下のコマンドで現在の `$HOME` を確認できます。

```bash
echo $HOME
```

> 🐣 Windows だと %USERPROFILE% (C:\Users\ユーザー名) が HOME の代わりなことも
---

## VSCode との連携

### VSCode のターミナルに fish を設定

VSCode の `settings.json` に以下を追加します。

```json
"terminal.integrated.profiles.windows": {
    "MSYS2 (fish)": {
        "path": "C:\\msys64\\usr\\bin\\fish.exe"
    }
},
"terminal.integrated.defaultProfile.windows": "MSYS2 (fish)"
```

これで、VSCode のターミナルで fish がデフォルトのシェルとして使用できるようになります。また、ターミナルから `powershell` と入力することで、いつでも PowerShell に戻れます。

---

### fish の便利機能の紹介

#### **プロンプト**
fish では、便利なプロンプトがデフォルトで利用できます。例えば、Git リポジトリ内で作業している場合、現在のブランチ名がプロンプトに表示されます。また、深いディレクトリでの作業時には、上位ディレクトリを一文字で短縮して表示してくれます。

**例**:
`~/ABC/EDF/XYZ` の `main` ブランチで作業中の場合、以下のように表示されます。

```bash
~/A/E/XYZ (main)>
```

#### **履歴検索**
fish では、`Ctrl+R` を押すと、履歴検索のインターフェースが表示され、キーワードを入力することで簡単に過去のコマンドを検索できます。

- 入力欄にキーワードを入力すると、その文字列を含むコマンド履歴が即座に絞り込まれます。
- 結果一覧がターミナル内に表示され、カーソルキーで選択できます。
- Enter キーで選択したコマンドをそのまま実行可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3935950/bd672239-9419-4dc3-8a28-505a9fba3b30.png)


これは直感的にすぐわかると思いますので是非試してみてください。

> 🐣 これがとにかく便利！

#### **過去のコマンド補完**
コマンドの入力途中で過去の履歴に基づいた候補が自動的に淡い文字で表示されるので、それでよければ右矢印キーや Ctrl+F キーで確定可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3935950/a7272768-af06-16a5-325a-4c0cc635f881.png)

#### **abbr（エイリアス）**
fish の `abbr` コマンドを使うと、エイリアス（略語）を簡単に定義できます。登録したエイリアスは次回以降も永続的に有効という点で普通のシェルの alias とは少し異なります。

**例**:
```bash
abbr -a g git
abbr -a gco 'git checkout'
```
これで、以下のように簡略化して入力できます。
```bash
> gco main
git checkout main  # 実行されるコマンド
```
#### **シンタックスハイライト**
fish は入力したコマンドの構文をリアルタイムで解析し、以下のようにハイライトで通知します。
- **青色**: 正常に実行可能なコマンド。
- **赤色**: 構文エラーまたは未定義のコマンド。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3935950/423cbb99-4c13-66ac-8ddf-b7b6f1c54d2f.png)

### Windows と Linux パスの操作

fish では、Windows と UNIX のパスを相互に変換しながら、両方のコマンドをスムーズに利用できます。以下に具体的な操作方法を説明します。

#### **fish から Windows のドライブにアクセス**

fish では、Windows のドライブ（例: `C:` や `D:`）にアクセスする際、ドライブ名の前にスラッシュ `/` を付ける形式を使用します。

**例**:
```bash
# C: ドライブに移動
cd /c

# D: ドライブに移動
cd /d

# 特定のディレクトリに移動
cd /c/Users/hiyoko/Documents
```

この形式により、Windows ドライブを UNIX のように操作できます。

#### **Windows と UNIX パスの相互変換**

MSYS2 のツール `cygpath` を利用することで、Windows と UNIX のパスを相互に変換できます。

**例**:
```bash
# Windows → UNIX パス
cygpath -u "C:\\Program Files"
# 結果: /c/Program Files

# UNIX → Windows パス
cygpath -w /usr/bin
# 結果: C:\msys64\usr\bin
```

これを活用することで、Windows のツールと UNIX 系のコマンドを混在して使用する際、パスの違いによる煩雑さを吸収できます。

##### **スペースを含むパスの扱い**:
   Windows のパスにスペースが含まれている場合は、必ずダブルクォート（`"`）で囲んでください。
   ```bash
   # エラーが発生する例
   cd /c/Program Files
   # 正しい形式
   cd "/c/Program Files"
   ```

##### **Windows の実行ファイルを直接呼び出し可能**:
   fish から Windows の `.exe` ファイルを直接実行できます。
   **例**:
   ```bash
   notepad.exe file.txt
   ```

---

## まとめ

今回の設定により、以下のようなメリットを得られます。

1. **Windows ネイティブな動作**: MSYS2 による安定した環境。
2. **優れた操作性**: fish の強力な補完機能と履歴検索。
3. **VSCode との親和性**: 統合されたターミナルでのスムーズな操作。
4. **クロスプラットフォーム**: Linux コマンドと Windows コマンドの共存。

fish は、ここで紹介した基本機能に加えて、さらに多彩な機能を備えています。興味を持ったら、公式ドキュメントを参考に高度な機能にも挑戦してみてください。特に補完機能やシンタックスハイライトの活用で、快適なシェル環境を手に入れることができます。

> 🐣 Powershell がもう少し Unix に寄せてくれればなぁ…

---
### 参考情報
- [Fish Shell 公式ドキュメント](https://fishshell.com/docs/current/)
- [MSYS2 公式サイト](https://www.msys2.org/)
- [VSCode ドキュメント（ターミナル設定）](https://code.visualstudio.com/docs/editor/integrated-terminal)