【Mac】ターミナル、シェル環境の初期設定

[Mac を買ったら必ずやっておきたい初期設定](https://qiita.com/ucan-lab/items/c1a12c20c878d6fb1e21)の続きです。

# 構成

- Mac
- ターミナル(Mac標準アプリ)
- [zsh](https://github.com/zsh-users/zsh)
  - [zsh-autosuggestions](https://github.com/zsh-users/zsh-autosuggestions)
- [tmux](https://github.com/tmux/tmux)
- [starship](https://github.com/starship/starship)
- [firacode](https://github.com/tonsky/FiraCode)
- [zoxide](https://github.com/ajeetdsouza/zoxide)

## 元のターミナル

<img width="837" alt="ScreenShot 2020-07-27 9.32.44.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52879/3028869d-d135-b370-e49e-d80a619effa2.png">

だ、ダサすぎる...

## 完成したターミナル

![ScreenShot 2020-07-25 2.07.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52879/59f576d4-829d-fc3e-77dd-c6ee717c119d.png)

か、カッコよすぎる...！

## リポジトリ

※準備中です。

## Terminal

Macに標準搭載されているターミナルアプリです。
[iTerm2](https://www.iterm2.com) や [Alacritty](https://github.com/alacritty/alacritty), [Hyper](https://hyper.is) も試しましたが、標準のターミナルで不便はなかったので一周して戻ってきました。
純正アプリなだけあって高速なのが良いです🤩

### 設定

ターミナルの設定ファイルはこちらに置いておきます。
https://gist.github.com/ucan-lab/72510f4460202560ba589248f53b981d

![ScreenShot 2020-08-17 11.03.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52879/743eec45-aa84-81fc-06f6-bd7839c36928.png)

### フォント:
Fira Code Retina 12 pt.

### Text:
✅ テキストアンチエイリアス処理
✅ ボールドフォントを使用
✅ 点滅テキストの使用を許可
✅ ANSIカラーを表示
□ ボールドテキストに明るい色を使用

(多分デフォルトのまま)

Text: `#FFFFFF`
ボールドテキスト: `#FFFFFF`
選択部分: `#A22042`

### ANSIカラー:

ブラック(0): `#000000`
レッド(1): `#E82972`
グリーン(2): `#A3DD2D`
イエロー(3): `#EE9621`
ブルー(4): `#71A6D2`
マゼンタ(5): `#AE81FF`
シアン(6): `#6AD9EF`
ホワイト(7): `#BFBFBF`
ブラック(8): `#75715E`
レッド(9): `#E82972`
グリーン(10): `#A3DD2D`
イエロー(11): `#EE9621`
ブルー(12): `#71A6D2`
マゼンタ(13): `#AE81FF`
シアン(14): `#6AD9EF`
ホワイト(15): `#E6E6E6`

### カーソル: 

✅ ブロック
✅ 点滅カーソル
カーソル: `#DC143C`

## zsh

最近のMacをお使いでしたら、`zsh` がデフォルトシェルになっているはずです。

```
$ echo $SHELL
/bin/zsh
```

と表示されていればokです。

## tmux

Unixライクなオペレーティングシステム用の端末多重接続ソフトウェアってwikiに書いてありました。
Mac標準のターミナルは画面分割機能が弱いので、tmuxの画面(ペイン)分割機能を使って補完してます。

また、ターミナルを閉じても端末の状態を保持しているのでアタッチすれば元の状態に復元できます。

### インストール

```shell-session
$ brew install tmux reattach-to-user-namespace
```

```shell-session
$ tmux -V
tmux 3.1b
```

### 設定

`~/.tmux.conf` を下記の内容に書き換えます。
デフォルトのprefixは `control` + `b` となっていますが、少し打ちづらい位置にあります。
そのため、 `control` + `q` にキーバインドを変更しています。

```:~/.tmux.conf
# prefixキーをC-qに変更する
set -g prefix C-q
# C-bのキーバインドを解除する
unbind C-b
# C-q*2でtmux内のプログラムにC-qを送る
bind C-q send-prefix

# キーストロークのディレイを減らす
set -sg escape-time 1

# ウィンドウのインデックスを1から始める
set -g base-index 1

# ペインのインデックスを1から始める
setw -g pane-base-index 1

# スクロールバックバッファサイズ
set -g history-limit 10000

# 設定ファイルをリロードする
bind r source-file ~/.tmux.conf \; display "Reloaded!"

# 新規ウィンドウ作成時にカレントパスを引き継ぐ
bind c new-window -c "#{pane_current_path}"

# | でペインを縦に分割する
bind | split-window -hc "#{pane_current_path}"
bind % split-window -hc "#{pane_current_path}"

# - でペインを横に分割する
bind - split-window -vc "#{pane_current_path}"
bind '"' split-window -vc "#{pane_current_path}"

# Vimのキーバインドでペインを移動する
bind h select-pane -L
bind j select-pane -D
bind k select-pane -U
bind l select-pane -R
bind -r C-h select-window -t :-
bind -r C-l select-window -t :+

# Vimのキーバインドでペインをリサイズする
bind -r H resize-pane -L 5
bind -r J resize-pane -D 5
bind -r K resize-pane -U 5
bind -r L resize-pane -R 5

# 256色端末を使用する
set -g default-terminal "screen-256color"

# ウィンドウリストの色を設定する
setw -g window-status-style bg="default","dim",fg="cyan"
# アクティブなウィンドウを目立たせる
setw -g window-status-current-style bg="red","bright",fg="white"

# ペインボーダーの色を設定する
set -g pane-border-style bg="black",fg="green"
# アクティブなペインを目立たせる
set -g pane-border-style bg="yellow",fg="white"

# コマンドラインの色を設定する
set -g message-style bg="black","bright",fg="white"

# ステータスバーを設定する
## ステータスバーの更新頻度の設定(秒)
set -g status-interval 1
## ステータスバーを上部に表示する
set -g status-position top
## ステータスバーの背景色を指定する
# ステータスバーの色を設定する
set -g status-bg "#1e2132"
## ステータスバーの文字色を指定する。
set -g status-fg "colour255"
## window-status のフォーマットを指定する。
setw -g window-status-format " #I: #W "
# カレントウィンドウの window-status のフォーマットを指定する
setw -g window-status-current-format "#[fg=colour255,bg=colour27,bold] #I: #W #[default]"
## 左パネルを設定する
set -g status-left-length 40
set -g status-left "#[fg=green]Session: #S #[fg=yellow]#I #[fg=cyan]#P"
## 右パネルを設定する
set -g status-right "#[fg=cyan][%Y-%m-%d(%a) %H:%M]"
## ウィンドウリストの位置を中心寄せにする
set -g status-justify centre
## ヴィジュアルノーティフィケーションを有効にする
setw -g monitor-activity on
set -g visual-activity on

# 操作
## マウス操作を有効化
setw -g mouse on
bind -n WheelUpPane if-shell -F -t = "#{mouse_any_flag}" "send-keys -M" "if -Ft= '#{pane_in_mode}' 'send-keys -M' 'copy-mode -e'"
bind -n WheelDownPane select-pane -t= \; send-keys -M
## クリップボートと連携(macOS)
unbind -T copy-mode-vi MouseDragEnd1Pane
bind-key -T copy-mode-vi Enter send-keys -X copy-pipe-and-cancel "reattach-to-user-namespace pbcopy"

# デフォルトシェル
set -g default-shell "${SHELL}"
set -g default-command "${SHELL}"
```

### 使い方

```shell-session
$ tmux
```

#### コマンド上でのセッション操作

| 操作|コマンド
|---|---|
| セッションの作成 | tmux, tmux new |
| 名前を付けて作成 | tmux new -s ProjectA |
| セッションの削除 | tmux kill-session -t ProjectA |
| 現在のセッション以外を削除 | tmux kill-session -a |
| セッションの一覧表示 | tmux ls |
| セッションを再開 | tmux attach、tmux a |
| 名前指定でセッションを再開 | tmux attach -t ProjectA、tmux a -t ProjectA |

#### セッション操作

| 操作 | コマンド |
|---|---|
| セッションの一覧表示と選択 | `control`+`q`, `s` (Select) |
| セッションから離脱 | `control`+`q`, `d` (Detach) |
| セッション名の変更 | `control`+`q`, `$` |

#### ウィンドウ操作

| 操作 | コマンド |
|---|---|
| ウィンドウの作成 | `control`+`q`, `c` (Create) |
| ウィンドウの切り替え | `control`+`q`, `n` (Next)、Ctrl+b, p (Previous) |
| ウィンドウの一覧選択 | `control`+`q`, `w` (Window) |
| ウィンドウの移動 | `control`+`q`, `0-9` |
| 以前のウィンドウに移動 | `control`+`q`, `l` (Latest) |
| ウィンドウ名の変更 | `control`+`q`, `,` |

#### ペイン操作

| 操作 | コマンド |
|---|---|
| 左右分割 | `control`+`q`, `\|` |
| 上下分割 | `control`+`q`, `=` |
| ペインを閉じる | `control`+`q`, `X` (Exit) |
| 次のペインに移動 | `control`+`q`, `o` |
| ペイン間の移動 | `control`+`q`, `矢印` |
| 以前のペインに移動 | `control`+`q`, `;` |
| レイアウトの変更 | `control`+`q`, `space` |
| ペインを移動 | `control`+`q`, `{` / control`+`q`, `}` |
| ペインの最大化/元に戻す | `control`+`q`, `z` (Zoom) |
| ペインをウィンドウ化 | `control`+`q`, `!` |
| ペイン番号の表示 | `control`+`q`, `q` |
| ペイン番号の表示と選択 | `control`+`q`, `q`, `0-9` |

```shell-session
$ exit
```

`exit` または `control` + `d` でtmuxから抜けることができます。
tmuxの詳しい使い方はドットインストールやYouTube等ご覧ください。

- https://dotinstall.com/lessons/basic_tmux
- https://www.youtube.com/watch?v=xTplsyQaGFs

## starship

https://starship.rs/ja-jp

Rust製のクロスシェルプロンプトツールです。
bash, fish, zshで動作します。

### インストール

```shell-session
$ brew install starship
```

```:~/.zshrc
eval "$(starship init zsh)"
```

```shell-session
$ exec $SHELL -l
```

### 設定

`~/.config/starship.toml` でstarshipの設定を行います。

```:~/.config/starship.toml
add_newline = false

[directory]
truncation_length = 0
truncate_to_repo = false

[time]
disabled = false
```

## firacode

https://github.com/tonsky/FiraCode

プログラミング用フォントです。
starshipを入れると一部の文字が文字化けするので入れておくと良いです。

```shell-session
$ brew tap homebrew/cask-fonts
$ brew cask install font-fira-code
```

フォントの設定はターミナルアプリの設定から変更してください。

## zoxide(ゾキサイド)

https://github.com/ajeetdsouza/zoxide

Rust製、利用頻度の高いディレクトリに移動できるコマンドラインツール。

### インストール

```shell-session
$ brew install zoxide
```

```:~/.zshrc
eval "$(zoxide init zsh)"
```

```shell-session
$ exec $SHELL -l
```

### 使い方

```shell-session
$ z foo       # cd to highest ranked directory matching foo
$ z foo bar   # cd to highest ranked directory matching foo and bar

$ z foo/      # can also cd into actual directories

$ zi foo      # cd with interactive selection using fzf

$ zq foo      # echo the best match, don't cd

$ za /foo     # add /foo to the database
$ zr /foo     # remove /foo from the database
```

## hstr

- https://github.com/dvorka/hstr
- https://www.youtube.com/watch?v=sPF29NyXe2U

コマンド履歴のサジェストツール

### インストール

```shell-session
$ brew install hstr
$ hstr --show-configuration >> ~/.zshrc
$ exec $SHELL -l
```

`~/.zshrc` に出力される内容

```:~/.zshrc
# HSTR configuration - add this to ~/.zshrc
alias hh=hstr                    # hh to be alias for hstr
setopt histignorespace           # skip cmds w/ leading space from history
export HSTR_CONFIG=hicolor       # get more colors
bindkey -s "\C-r" "\C-a hstr -- \C-j"     # bind hstr to Ctrl-r (for Vi mode check doc)
```

### 使い方

```shell-session
$ hh
```

または、 `control` + `r` でコマンド履歴を一覧表示、選択して実行できます。

## zsh-autosuggestions

https://github.com/zsh-users/zsh-autosuggestions

### スクリーンショット

![ScreenShot 2020-07-25 19.24.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52879/7a635527-763b-91a7-b04e-a3f933c613de.png)

コマンド入力の際、直近入力したコマンドが薄い灰色でサジェスト表示される機能です。
この状態で `→` または `control` + `e` または `control` + `f` で補完されます。

### インストール

```shell-session
$ git clone https://github.com/zsh-users/zsh-autosuggestions ~/.zsh/zsh-autosuggestions
```

```:~/.zshrc
. ~/.zsh/zsh-autosuggestions/zsh-autosuggestions.zsh
```

```shell-session
$ exec $SHELL -l
```

### 使い方

コマンドを入力するとカーソルの後に灰色でコマンドの補完が表示されます。
補完が表示されている状態で `→` または `control` + `e` で補完が入力されます。

## オススメのツール

[こちらの記事](https://qiita.com/ucan-lab/items/c1a12c20c878d6fb1e21)で紹介した内容と被りますが、標準コマンドの代替となるRust製ツールを紹介します。

こちらの記事に移動しました。
[Rust製の便利なコマンドラインツール](https://qiita.com/ucan-lab/items/ce98af1b069ee8d87644)

## エイリアス

```
alias ..='cd ..'
alias mkdir='mkdir -p'
alias relogin='exec $SHELL -l'
alias ls='exa --time-style=long-iso -g'
alias ll='exa --time-style=long-iso -gl'
alias la='exa --time-style=long-iso -agl'
alias l1='exa -1'
alias md='vim ./*.md'
alias f='open .'
alias diff='diff -u'

function tm() {
  if [ -n "${1}" ]; then
    tmux attach-session -t ${1} || \
    tmux new-session -s ${1}
  else
    tmux attach-session || \
    tmux new-session
  fi
}

function docker-tags {
  curl -s https://registry.hub.docker.com/v1/repositories/$1/tags | jq -r '.[].name'
}
```

## 参考

- https://qiita.com/nl0_blu/items/9d207a70ccc8467f7bab
- https://qiita.com/kalafinalice/items/c02c0345293fe60af6e5
- https://qastack.jp/unix/318281/how-to-copy-and-paste-with-a-mouse-with-tmux
- https://tex2e.github.io/blog/linux/tmux-tutorial