🐰

zsh(+ dotfiles)入門

2020/12/30に公開
1

はじめに

こんにちは, @kazuです.
この記事ではzshの,

  • インストール
  • 設定方法
  • dotfilesについて
  • おすすめプラグイン

等について書いていきます.

対象者

この記事は, 以下のような方を読者として想定しています.

  • ターミナルをカスタマイズしてみたい人
  • ターミナルと仲良くなりたい人
  • ターミナルでの作業効率を上げたい人
  • そもそもターミナルってカスタマイズ出来るの?って人

すでに自分でいろいろカスタマイズしている方には物足りない記事となることをご了承下さい.

この記事でやること

  • zshについて
  • zshのインストール
  • シェルの変更
  • .zshrcの記述
  • dotfiles
  • 個人的おすすめ設定
  • 最後に

zshについて

まずは本記事のメインであるzshについて軽く触れておきます.
zshとは, シェルの一種であり, 簡単に言うとMacとかのターミナル上で動いているアレの一種です.
あの黒い画面ですが, 実は中身のシェルを何にするかで使い勝手が変わってきます.
シェルには様々な種類があり, zsh以外にも,

  • bash
  • fish
  • csh
  • Nu Shell

などがあります.

上述の通りの本記事の対象読者であれば, 現在bashzshを使用していると思います.
linuxやWSL等でlinux環境,あるいはCatalina以前のMac OS Xであればbashがデフォルトであり,
Catalina以降のMac OS Xではzshがデフォルトとなっています.

両者の違いですが, 簡単に言うとbashの拡張的な位置づけにあたるものがzshとなっています.
そのため, 現在bashを使っている人でも, 特にこだわりが無いのであればbashに移行してしまっても良いように思います.
両者の細かい比較などは, [zsh bash 違い]でググればたくさん出てきますので, 本記事では割愛します.

zshのインストール

Macの場合

brewを使ってインストール出来ます.

console
brew install zsh

Linuxの場合

apt(Ubuntu等), yum(CentOS)を使ってインストールします.

console
sudo apt install zsh
# または
sudo yum install zsh

確認

whichコマンドで, zshがインストールされたpathを調べます.

console
which zsh
# -> /usr/bin/zsh 等出ればOK 

ログインシェルとして使えるように設定

/etc/shellsというファイルの中に, whichコマンドで表示されたパスが無ければ追記します.

# /etc/shellsの中身確認
cat /etc/shells

# catの出力にzshのパスが無ければ
sudo vim /etc/shells
# で末尾にwhichコマンドの出力のパスを追記する

シェルの変更

続いて, 先程インストールしたzshを, chshコマンド( ch ange sh ell)でログインシェルに設定します.
先程のwhichコマンドの出力を指定します.

console
chsh -s /usr/bin/zsh

一回ログアウトし, 再度ターミナルを開いて以下のような画面が出ればzshで起動しています.

console
This is the Z Shell configuration function for new users,
zsh-newuser-install.
You are seeing this message because you have no zsh startup files
(the files .zshenv, .zprofile, .zshrc, .zlogin in the directory
~).  This function can help you with a few settings that should
make your use of the shell easier.

You can:

(q)  Quit and do nothing.  The function will be run again next time.

(0)  Exit, creating the file ~/.zshrc containing just a comment.
     That will prevent this function being run again.

(1)  Continue to the main menu.

(2)  Populate your ~/.zshrc with the configuration recommended
     by the system administrator and exit (you will need to edit
     the file by hand, if so desired).

--- Type one of the keys in parentheses --- 

この画面では, zshの初期設定をするかどうか聞かれていますが,この後手動で設定していくので qを押して画面を閉じます.

ちなみに,選択肢は以下の通りです.

  • q: 何もせずにこの画面を抜ける.
  • 0: ほぼ空の~/.zshrcを作成して抜ける.
  • 1: メインメニューに移動する.(対話的に設定が始まります.)
  • 2: システムおすすめの設定で.zshrcを作成する.

.zshrcの記述

zshをログインシェルとして設定が出来たので, 次は.zshrcに設定を書き込んでいきます.
.zshrcは, bashで言うところの.bashrcaのようなもので, コマンド履歴や補完の仕方などについて記述していきます.
以下は僕の.zshrcから基本的な部分を抜粋してきたものです.
オプション等については, ここ ここ に詳しいドキュメントがあります.
最初からいろいろ設定するのは大変だと思うので, コピペから初めて都度ドキュメントを見て自分好みに変えていくと良いと思います.
では, 以下の内容で.zshrcを作成し, ホームディレクトリに保存してください.

.zshrc
#################################  HISTORY  #################################
# history
HISTFILE=$HOME/.zsh-history # 履歴を保存するファイル
HISTSIZE=100000             # メモリ上に保存する履歴のサイズ
SAVEHIST=1000000            # 上述のファイルに保存する履歴のサイズ

# share .zshhistory
setopt inc_append_history   # 実行時に履歴をファイルにに追加していく
setopt share_history        # 履歴を他のシェルとリアルタイム共有する

#################################  COMPLEMENT  #################################
# enable completion
autoload -Uz compinit && compinit

# 補完候補をそのまま探す -> 小文字を大文字に変えて探す -> 大文字を小文字に変えて探す
zstyle ':completion:*' matcher-list '' 'm:{[:lower:]}={[:upper:]}' '+m:{[:upper:]}={[:lower:]}'

### 補完方法毎にグループ化する。
zstyle ':completion:*' format '%B%F{blue}%d%f%b'
zstyle ':completion:*' group-name ''


### 補完侯補をメニューから選択する。
### select=2: 補完候補を一覧から選択する。補完候補が2つ以上なければすぐに補完する。
zstyle ':completion:*:default' menu select=2
#################################  OTHERS  #################################
# automatically change directory when dir name is typed
setopt auto_cd

# disable ctrl+s, ctrl+q
setopt no_flow_control

ファイルを保存したら,

console
source ~/.zshrc

を実行して, 保存した.zshrcを読み込んで適応させます.
設定が反映されていれば, lscatコマンドでタブ補完を行った時にfilesのように補完の種類が表示されます.
下の画像では, 自分の環境でlsでタブ補完を行った時のスクリーンショットです.
Image from Gyazo
external commandaliasのように, 種類ごとに補完の候補が表示されていることが解ると思います.

これで基本的な.zshrcの設定を行うことが出来ました.

dotfiles

dotfiles とは

続いて, dotfilesについて説明していきます.
先程作成した.zshrcですが, 長く使っていると

  • 他の環境でも同じ設定をしたい
  • バージョン管理したい

などの要望が出てくると思います.
そういう時に便利なのがdotfilesです.
dotfilesとは, 簡単に言うと「設定ファイルを一元管理しよう」という概念(?)です.
専用のソフトウェアが有るわけではありませんが,

  • .zshrcなどの設定ファイルを
  • 一元的にバージョン管理し,
  • 簡単に環境の再現を可能にする

ことを一般的にdotfilesといいます.
.zshrcの他にも, .vimrc.tmux.confなどの設定ファイルもdotfilesで一緒に管理することが多いです.

dotfilesは, 基本的に

  • 管理したいファイルを1つのディレクトリにまとめる
  • gitで管理出来るようにする
  • 設定ファイルを所定の位置に配置するスクリプトを書く

という3つの手順が必要となります.

実践

では, 実際に先程作成した.zshrcdotfilesで管理出来るようにしましょう.

管理したいファイルを1つのディレクトリにまとめる

まずは設定ファイルを纏めておくディレクトリを作成します.
ここでは, 自分のホームディレクトリ直下に作成します.

console
mkdir ~/dotfiles

続いて, 管理したいファイル(今は.zshrc)をdotfilesディレクトリに移動させます,

console
mv ~/.zshrc ~/dotfiles/

# 確認
ls -la ~/dotfiles
# -> .zshrcがあればOK

gitで管理出来るようにする

不具合がある場合や, 設定が気に食わない時に気軽に前の設定に戻したり出来るように, gitで管理します.

console
cd dotfiles
git init
git add .zshrc
git commit -m "init"

必要に応じてgithubでレポジトリを作っておくと便利です.

設定ファイルを所定の位置に配置するスクリプトを書く

.zshrcdotfilesに移動させたのは良いですが, .zshrcはホームディレクトリ直下に置く必要があり, このままでは設定を読み込んでくれません.
そこで, dotfiles/.zshrcのシンボリックリンクをホームディレクトリに配置します.

console
ln -sv ~/dotfiles/.zshrc ~/

# 確認
ls -la ~/
# .zshrc のシンボリックリンクがあればOK

上記のようにlnコマンドを利用すればシンボリックリンクの配置が出来ます.

実際は, 環境の再現を簡単に行えるように, 設定ファイルを配置する以下のようなスクリプトを書いていたほうが楽です.(.zshrc.tmux.confを配置する場合の例)

dotfiles/deploy.sh
#!/bin/bash
# 配置したい設定ファイル
dotfiles=(.zshrc .tmux.conf)

# .zshrc と .tmux.conf という設定ファイルのシンボリックリンクを
# ホームディレクトリ直下に作成する
for file in "${dotfiles[@]}"; do
        ln -svf $file ~/
done

このようなスクリプトを作成した場合は, dotfilesの中で

console
# 初回は実行権限の付与が必要
chmod +x deploy.sh

# スクリプトを実行しシンボリックリンクを一気に作成する
./deploy.sh

とするだけで簡単にシンボリックリンク作成が行えます.
このスクリプトもgit addしてコミットしておいてください.

後は設定ファイルを編集するたびにきちんとコミットしておけば, 安心してカスタマイズが出来ます.

個人的おすすめ設定

とりあえず前項で基本的な設定・構築が終わったので, ここからは僕が気に入っている設定(プラグイン)について紹介していきます.

zdharma/zinit

まず, 他のプラグインの前に, zinitを入れておく事をおすすめします.
zinitは, いわゆるプラグイン管理のためのプラグインです.
zinitに限らずですが, プラグイン管理ツールを使うことで,

  • プラグインをコード上で管理できる.
  • プラグインのインストールを手軽に行える.
  • 何より設定ファイルをdotfilesで管理できる.

などのメリットがあります.

インストール方法

基本的には以下のように公式のインストール方法に従えばOKです.

console
sh -c "$(curl -fsSL https://raw.githubusercontent.com/zdharma/zinit/master/doc/install.sh)"

インストール中に, いくつかAnnexes(プラグインのようなもの)をインストールするかと聞かれます.
Annexesについては, ここに説明があります.
僕は要らないのでnを押してキャンセルしました.

インストールが終わると,.zshrc最下部に以下のような記述が追加されます.

.zshrc
### Added by Zinit's installer
if [[ ! -f $HOME/.zinit/bin/zinit.zsh ]]; then
    print -P "%F{33}▓▒░ %F{220}Installing %F{33}DHARMA%F{220} Initiative Plugin Manager (%F{33}zdharma/zinit%F{220})…%f"
    command mkdir -p "$HOME/.zinit" && command chmod g-rwX "$HOME/.zinit"
    command git clone https://github.com/zdharma/zinit "$HOME/.zinit/bin" && \
        print -P "%F{33}▓▒░ %F{34}Installation successful.%f%b" || \
        print -P "%F{160}▓▒░ The clone has failed.%f%b"
fi

source "$HOME/.zinit/bin/zinit.zsh"
autoload -Uz _zinit
(( ${+_comps} )) && _comps[zinit]=_zinit
### End of Zinit's installer chunk

プラグインを追加する時は, この追加された箇所より下に決められた構文で記述していきます.
このまま.zshrcに書いていっても良いのですが, ファイルが肥大化しそうなので別ファイルに分けましょう.
僕は以下のようなファイル構成にしています.

console
e89b547847c7% tree -a dotfiles
dotfiles
|-- .zshrc
`-- zsh
    |-- config.zsh
    `-- plugins.zsh

1 directory, 3 files

まず,zsh/config.zshには, 「.zshrcの記述」の項で述べた内容をそのまま書いています.
そして,zsh/plugins.zshには, プラグイン追加のための設定を記述しています.
最後に, それらの2つのファイルを, .zshrcから読み込むような設定にしています.
従って, 最終的な.zshrcの中身は以下のようになっています.

.zshrc
### Added by Zinit's installer
# 上記と同じなので省略
### End of Zinit's installer chunk

SCRIPT_DIR=$HOME/dotfiles

source $SCRIPT_DIR/zsh/plugins.zsh
source $SCRIPT_DIR/zsh/config.zsh
console
# 設定の反映
source ~/.zshrc

同様にエイリアスを記述するためのalias.zshなんかも作っています.
plugins.zshの記述の仕方は, 必要に応じてこれ以降の項で説明します.
詳しく知りたい方は公式wikiをご参照ください.

romkatv/powerlevel10k

まず最初におすすめしたいのは, powerlevel10k(以下p10k)です.
p10kとは, 以下の画像のようにターミナルの見た目を変えるプラグインです.
(画像はromkatv/powerlevel10kより)

p10k

p10kを入れることで,

  • 黒い画面をカラフルに出来る(!!)
  • gitのステータスを表示できる
  • 現在時刻を表示できる
  • その他, PCの情報(CPU使用率やメモリ使用率等)も表示できる

などのメリットがあります.
ぶっちゃけ見た目に関しては好みがあると思いますが, コマンドを打たなくてもgitのステータスがひと目で確認できるところが気に入っています.

インストール方法

基本的にはzsh/plugins.zshに記述するだけでよいのですが, p10kに関してはフォントの設定が推奨されています.
ターミナルにNerd Fontsという種類のフォントを設定することにより, アイコンなどが表示できるようになります.

フォントのインストール

普通はNerd Fontsの中から好きなものを選べばよいのですが, 我々は日本人なので日本語に対応してくれているフォントを選択する必要があります.
僕は, こちらで紹介されている, Hack GenHackGenNerd Consoleを使用しています.
フォントをPCにインストールした後に, お使いのターミナルの設定画面からHackGenNerd Consoleを指定してください.

plugins.zshに追加

フォントのインストールが終わったら, zsh/plugins.zshを記述していきます.
書く内容は, 公式に従います.

zsh/plugins.zsh
zinit ice depth=1; zinit light romkatv/powerlevel10k

この1行を追加したら, 設定ファイルをリロードして設定を反映させます.

console
source ~/.zshrc

すると, p10kのダウンロードが始まり, 続けて初期設定が対話的に行われます.
「この記号がひし形に見えるか?」等表示に関する質問や, 好みのスタイルについての質問が表示されるので, 指示に従って答えていけば大丈夫です.
初期設定が終わると, コンソールの表示が以下のようにカラフルになります(質問にどう答えたかによります.)

Image from Gyazo

無味乾燥だったコンソールが少し賑やかになりましたね!!

設定ファイルをdotfilesの管理下に移す

さて, p10kの設定ファイルは, ~/.p10k.zshというパスで作成されます.
見た目を弄りたかったらこのファイルを書き換えるのですが, その前にこれもdotfilesの管理に入れておきましょう.

console
mv ~/.p10k.zsh ~/dotfiles/zsh/p10k.zsh  #あえてファイル名先頭のピリオドを消しています.

# 確認
# tree -a ~/dotfiles
# dotfiles
# |-- .zshrc
# `-- zsh
#     |-- config.zsh
#     |-- p10k.zsh
#     `-- plugins.zsh
# 
# 1 directory, 4 files

次に, .zshrcを編集します.
実は, p10kを入れた時点で最下部に以下のような記述が追記されています.

.zshrc
# 前略
source $SCRIPT_DIR/zsh/plugins.zsh
source $SCRIPT_DIR/zsh/config.zsh

# To customize prompt, run `p10k configure` or edit ~/.p10k.zsh.
[[ ! -f ~/.p10k.zsh ]] || source ~/.p10k.zsh

この部分は, ~/.p10k.zshがあれば読み込むという挙動なのですが, 今はdotfiles/zsh/p10k.zshに移動させたので以下のように書き換えます.

console
# 前略
source $SCRIPT_DIR/zsh/plugins.zsh
source $SCRIPT_DIR/zsh/config.zsh
source $SCRIPT_DIR/zsh/p10k.zsh  # <- 変更箇所

これでp10kの設定ファイルもdotfilesで管理できるようになりました.

p10k.zshを編集する

ここはお好みですが, 簡単にp10k.zshファイルを変更しておきます.
とりあえず,

  • cpu負荷
  • メモリ負荷
  • ストレージ使用容量

を表示させようと思います.

お好きなエディタでdotfiles/zsh/p10k.zshを開いてください.
30行目付近の,

p10k.zsh
# The list of segments shown on the left. Fill it with the most important segments.
typeset -g POWERLEVEL9K_LEFT_PROMPT_ELEMENTS=(
  os_icon                 # os identifier
  dir                     # current directory
  vcs                     # git status
  prompt_char             # prompt symbol
)

と書かれた箇所が, プロンプトの左側に表示される情報で, その下の長いセグメントが右側に表示される情報です.
以下抜粋

p10k.zsh
typeset -g POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS=(
 # 省略
     # load                  # CPU load
     # disk_usage            # disk usage
     # ram                   # free RAM
 # 省略
)

この中の,

  • load
  • disk_usage
  • ram

をそれぞれコメントアウトを外して設定のリロードを行えば, コンソールにそれらの情報を表示させることが出来ます.

Image from Gyazo

画像のように, 右側にそれぞれの情報が増えていると思います.
同様の手順で自分好みに見た目をカスタマイズすることが出来ます.

変更をコミットして, p10kの設定は終わりです.
長くなってきたので,次のプラグインからはサクサク行きます.

zdharma/fast-syntax-highlighting

続いてのおすすめプラグインは, zdharma/fast-syntax-highlightingです.
これは, その名の通りコマンドに対してシンタックスハイライトをしてくれるプラグインです.
(画像はzdharma/fast-syntax-highlightingより引用)
zdharma/fast-syntax-highlighting

以下の画像と, p10kの項で貼ったスクリーンショットを見比べると, シンタックスハイライトが効いていることが解ると思います.
Image from Gyazo

有効なコマンドや引数の場合にハイライトが効くので地味に便利です.

インストール

zsh/plugins.zsh
zinit light zdharma/fast-syntax-highlighting

追加後にsource ~/.zshrcすることで自動的にダウンロードされます.

zsh-users/zsh-autosuggestions

以下の画像のように, 入力中のコマンドと一致するコマンドを履歴から探してサジェストしてくれます.
Image from Gyazo
1回目のechoコマンドの後に, eと入力するだけでechoコマンドを引数とともにサジェストしてくれています.

インストール

zsh/plugins.zsh
zinit light zsh-users/zsh-autosuggestions
bindkey '^j' autosuggest-accept

1行目はプラグインのインストールのための記述で,
2行目がサジェストを受け入れるためのキーバインドを設定しています.
例えば, 上記の画像のようにサジェストされた状態で, <Control + j>でサジェストを受け入れるように設定しています.

paulirish/git-open

以下のようにして現在のgitレポジトリをブラウザで開いてくれます.

console
git open

他にもいろいろな開き方があるので, ぜひ公式githubを見てみてください.

インストール

zsh/plugins.zsh
zinit light paulirish/git-open

sharkdp/bat

batに関しては別のzshのプラグインではありませんが, 便利なのでついでに紹介しておきます.
batは, 簡単にいうと見やすいcatです.

Image from Gyazo

上記のようにシンタックスハイライトが効く他, 長いファイルだとlessみたいにページャー的に表示してくれたりもします.

インストール

zsh/plugins.zsh
zinit ice as"program" from"gh-r" mv"bat* -> bat" pick"bat/bat"
zinit light sharkdp/bat

# 以下はただのエイリアス設定
if builtin command -v bat > /dev/null; then
  alias cat="bat"
fi

さて, 先程までと記述方法が変わっています.
このように書くことで, バイナリとしてダウンロードして, pathを通すことが出来ます.
実際にダウンロードするものを指定しているのは2行目の

zinit light sharkdp/bat

ですが, 1行目でそれに対しいろいろオプションをつけてます.

  • ice: 次の行に対してオプションを付与する
  • as"program": zshのソースファイルではなく,コマンドとして扱う
  • from"gh-r": githubのリリースからダウンロードする
  • mv: ダウンロードしたものをリネームする
  • pick: pathを通すものの指定

このように, zshのプラグインに限らず, githubのリリースで配布するものもzinitで管理することで, 容易に環境復元が可能になります.

最後に

ちょっと想定より長くなってしまったので, とりあえずこのへんで終わりにしようと思います.
僕は半年掛けてちょこちょこカスタマイズしていっているのですが, まだまだ改善の余地があるなぁと感じています.
ある意味沼にハマりかけている僕のdotfilesはこちらになります.

https://github.com/kazu914/dotfiles

良ければ参考にしてください.

さらに, dotfilesを構築したり再現性を確かめたりするための環境を作るdocker-composeも置いておくので良かったら使ってください.

https://github.com/kazu914/ubuntu-test-env-in-docker

それでは, 良いzshライフを!!

追記欄

zinitのプラグイン遅延読み込み

コメントにてzinitwaitオプションとlucidオプションをおすすめして頂きました.

  • wait: プラグインを遅延読み込みすることでプロンプトの起動を速くする. プラグインの読み込みが終わるまでそのプラグインは有効にならないが,その分プロンプトの起動を速くなる.
  • lucid: waitしていたプラグインが読み込まれた時に出てくるLoaded <plugin name>というメッセージを非表示にする.

waitオプションは,条件とともに指定可能で,wait"1"ならば起動後1秒後から読み込みが開始されます. (waitwait"0"と同義)
さらに読み込む順番等も指定できます.詳しくは公式wiki.

p10kのinstant promptモード

同じくp10kのinstant promptについても教えていただきました.
こちらは,zshの起動を高速化してくれるモードです.
githubのレポジトリでは,

Powerlevel10k can remove Zsh startup lag even if it's not caused by a theme.

(p10kはzsh起動時の遅延を無くすことが出来るぜ,たとえそれがテーマに起因する遅延じゃ無くともな!)

と書いてあるので,恐らくp10kの設定のみならず他のプラグイン由来の遅延も解消してくれます.
こちらを有効にするには,

.zshrcの最初に以下の設定(公式から引用)を書き込みます.

.zshrc
# Enable Powerlevel10k instant prompt. Should stay close to the top of ~/.zshrc.
# Initialization code that may require console input (password prompts, [y/n]
# confirmations, etc.) must go above this block; everything else may go below.
if [[ -r "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" ]]; then
  source "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh"
fi

上記にコメントアウトされている通りなのですが,対話的に入力を求める処理はこの部分より上に書く必要があります.

起動時の遅延が気になるという方はぜひ2つの設定を行ってみてください.

Discussion

kikusuikikusui
# .zshrc と .tmux.conf という設定ファイルのシンボリックリンクを
# ホームディレクトリ直下に作成する
for file in "${dotfiles[@]}"; do
        ln -svf $file ~/

このシェルスクリプトだと、自分自身にシンボリックリンクを貼るという謎な挙動になる気がします。こんなふうにしてみるとうまくいきました。

# .zshrc と .tmux.conf という設定ファイルのシンボリックリンクを
# ホームディレクトリ直下に作成する
for file in "${dotfiles[@]}"; do
        ln -svf ~/dotfiles/${file} ~/${file}