macOS の zsh ではこれだけはやっておこう
Homebrew を使います
まだ Homebrew をインストールしていない場合はこちら:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
1. パスの設定
M プロセッサ (Apple Silicon) 搭載 Mac の場合は、Homebrew 向けにパスを通しておく必要があります。
# デフォルトのパスを確認
% echo $path
/usr/local/bin /usr/bin /bin /usr/sbin /sbin /Library/Apple/usr/bin /Library/Frameworks/Mono.framework/Versions/Current/Commands
Intel Mac であればこのままでも差し支えありませんが、Apple Silicon Mac では Homebrew のインストール先が /opt/homebrew
以下となるので、ここへパスを通しておきます。
ホームディレクトリ (/Users/ユーザー名
) に .zshrc
を作成します。
typeset -U path PATH
path=(
/opt/homebrew/bin(N-/)
/opt/homebrew/sbin(N-/)
/usr/bin
/usr/sbin
/bin
/sbin
/usr/local/bin(N-/)
/usr/local/sbin(N-/)
/Library/Apple/usr/bin
)
優先してほしい順にパスを指定していきます。
(N-/)
は、もしそのディレクトリが存在していれば PATH に追加し、そうでなければ無視してくれるオプションです。
上のパス設定を反映させるには ~/.zshrc
を読み込みます。
source ~/.zshrc
2. zsh-completions のインストール
コマンド入力にバシバシ補完を効かせてくれる zsh-completions をインストールします。
brew install zsh-completions
~ 略 ~
=> Caveats
To activate these completions, add the following to your .zshrc:
if type brew &>/dev/null; then
FPATH=$(brew --prefix)/share/zsh-completions:$FPATH
autoload -Uz compinit
compinit
fi
You may also need to force rebuild `zcompdump`:
rm -f ~/.zcompdump; compinit
Additionally, if you receive "zsh compinit: insecure directories" warnings when attempting
to load these completions, you may need to run this:
chmod -R go-w '/opt/homebrew/share/zsh'
~ 略 ~
インストール時の Caveats には、/opt/homebrew/share/zsh
(Intel Mac の場合は /usr/local/share/zsh
) のみを go-w
せよと表示されていますが、実際には share
ディレクトリそのものを chmod -R go-w
する必要があります。
chmod -R go-w /opt/homebrew/share
あとは Caveats の指示にしたがって、~/.zshrc
への追記と補完キャッシュファイルの再生成をおこないます。
if type brew &>/dev/null; then
FPATH=$(brew --prefix)/share/zsh-completions:$FPATH
autoload -Uz compinit && compinit
fi
% source ~/.zshrc
% rm -f ~/.zcompdump; compinit
これでコマンド入力中に Tab
キーまたは Ctrl+I
を打鍵するとその後の候補を補完表示してくれます。
% sysctl _ # <-- ここで Tab または \C-I を入力
% sysctl _
audit hw kperf machdep security vfs
debug kern ktrace net user vm
% sysctl hw._ # <-- ここでふたたび Tab
% sysctl hw._
activecpu cpufrequency l3cachesize
busfrequency cpufrequency_max logicalcpu
busfrequency_max cpufrequency_min logicalcpu_max
busfrequency_min cpusubfamily memsize
3. zsh-autosuggestions のインストール
ターミナルのコマンド履歴に基づいてコマンド候補を表示、入力補完もしてくれる zsh-autosuggestions もインストールします。
brew install zsh-autosuggestions
~ 略 ~
==> Caveats
To activate the autosuggestions, add the following at the end of your .zshrc:
source /opt/homebrew/share/zsh-autosuggestions/zsh-autosuggestions.zsh
You will also need to force reload of your .zshrc:
source ~/.zshrc
==> Analytics
~ 略 ~
Caveats にしたがって ~/.zshrc
へ追記しましょう。
if type brew &>/dev/null; then
FPATH=$(brew --prefix)/share/zsh-completions:$FPATH
+ source $(brew --prefix)/share/zsh-autosuggestions/zsh-autosuggestions.zsh
autoload -Uz compinit && compinit
fi
source ~/.zshrc
この状態から Ctrl+E で補完をコンプリート
4. プロンプトの表示を変更
プロンプトのデフォルト値を確認します。
zenn@mba ~ $ echo $PROMPT
%n@%h %1~ %#
これらは以下のことを意味しています。
-
%n
: ユーザー名 -
%h
: ホスト名 -
%~
: カレントディレクトリ(1
はディレクトリ深度) -
%#
: 一般ユーザーのときは%
、root になったときは#
を表示
カレントディレクトリの表示形式にはいくつかのバリエーションがあります。
PROMPT | 機能 | 実際の表示 |
---|---|---|
%d |
フルパス | /Users/zenn/Downloads/myapp:% _ |
%~ |
フルパス 2 | ~/Downloads/myapp:% _ |
%c |
相対パス | myapp:% _ |
%2c |
ディレクトリ深度 2
|
Downloads/myapp:% _ |
ここでは次のように設定しました。
PROMPT="%n ($(arch)):%~"$'\n'"%# "
-
$()
: カッコ内のコマンド結果を表示します -
"$'\n'"
: プロンプトが長くなってしまったので途中に改行を挿入します
% source ~/.zshrc
zenn (arm64):~/Downloads/myapp
% _
5. プロンプトへ色を付ける
zsh では簡単にプロンプトへ色をつけることができます。
まず、~/.zshrc
の冒頭で色を扱うモジュールを有効化し、
autoload -Uz colors && colors
プロンプト内の文字列に色を指定します。
%F{色の名前または色番号}hoge%f
%F
~ %f
に挟まれた文字列 (hoge
) に指定した色が付きます。
色の名前: black
red
green
yellow
blue
magenta
cyan
white
PROMPT="%F{green}%n%f %F{cyan}($(arch))%f:%F{blue}%~%f"$'\n'"%# "
色番号を調べるには以下のスクリプトを実行してみてください。
palette.sh(クリックで展開トグル)
#!/bin/sh
#
# 256色のカラーパレットを表示する
# bash と zsh にて実行可能
#
target_shell=$1
if [ -z "$1" ]; then
target_shell=$(basename "$SHELL")
fi
if [ "$target_shell" = "bash" ]; then
bash <<< 'for code in {0..255}; do echo -n "[38;05;${code}m $(printf %03d $code)"; [ $((${code} % 16)) -eq 15 ] && echo; done'
elif [ "$target_shell" = "zsh" ]; then
zsh <<< 'for code in {000..255}; do print -nP -- "%F{$code}$code %f"; [ $((${code} % 16)) -eq 15 ] && echo; done'
else
echo "error: Invalid argument ($target)"
echo "Usage: $0 [bash|zsh]"
fi
6. プロンプトへ Git リポジトリの状態を表示する
まず、zsh-git-prompt をインストールします。
brew install zsh-git-prompt
~ 略 ~
==> Caveats
Make sure zsh-git-prompt is loaded from your .zshrc:
source "/opt/homebrew/opt/zsh-git-prompt/zshrc.sh"
~ 略 ~
Caveats の指示に従い、~/.zshrc
の中でスクリプトを読み込み、
source $(brew --prefix)/opt/zsh-git-prompt/zshrc.sh
プロンプトの中で git_super_status
を展開するだけです。
PROMPT="%F{034}%h%f:%F{020}%~%f $(git_super_status)"$'\n'"%# "
$(git_super_status)
を表示させたくない場合
Git リポジトリ以外では zsh には、bash における PROMPT_COMMAND
と同等のフック関数 precmd()
が用意されています。
precmd() フックへ、そのディレクトリが Git リポジトリかどうか判定する関数を追加します。
git_prompt() {
if [ "$(git rev-parse --is-inside-work-tree 2> /dev/null)" = true ]; then
PROMPT="%F{034}%h%f:%F{020}%~%f $(git_super_status)"$'\n'"%# "
else
PROMPT="%F{034}%h%f:%F{020}%~%f "$'\n'"%# "
fi
}
precmd() {
git_prompt
}
7. コマンド実行結果のあとに空行を挿入する
コマンドの実行結果が表示されたあと、すぐにプロンプトが表示されるのはやや窮屈です。
zenn (arm64):~/Downloads
% ls -a
. .. .DS_Store .localized myapp
zenn (arm64):~/Downloads
% _
~/.zshrc
へ以下を追記します。
add_newline() {
if [[ -z $PS1_NEWLINE_LOGIN ]]; then
PS1_NEWLINE_LOGIN=true
else
printf '\n'
fi
}
precmd() {
git_prompt
add_newline
}
コマンド実行後に空行が挿入されるようになりました。
zenn (arm64):~/Downloads
% source ~/.zshrc
zenn (arm64):~/Downloads
% _
8. あたらしくインストールされたコマンドを即認識させる
デフォルト状態の zsh では、あたらしくインストールされたコマンドをただちに認識してはくれません。
~% brew install yarn
~% yarn --version
zshell: command not found: yarn
~/.zshrc
の冒頭へ以下の行を追記しましょう。
zstyle ":completion:*:commands" rehash 1
9. tarball へ macOS の特殊ファイルを含めないようにする
macOS で作成した tar.gz
を Windows などの他の OS で解凍すると、.DS_Store
ファイルや ._ (ドットアンダーバー)
ファイルなどの特殊ファイルが tarball に含まれてしまっていることがよくあります。
これを防ぐためのエイリアス関数を用意しましょう。
tgz() {
env COPYFILE_DISABLE=1 tar zcvf "$1" --exclude=".DS_Store" "${@:2}"
}
使い方:
~% tgz dotfiles.tgz .zshrc .gitconfig .ssh/
a .zshrc
a .gitconfig
a .ssh
a .ssh/id_ed25519
a .ssh/id_ed25519.pub
a .ssh/config
a .ssh/known_hosts
~% ls
dotfiles.tgz
10. その他の小技集
rm *
でいちいち確認しないで欲しい
1. setopt RM_STAR_SILENT
curl
などで ?
や &
をエスケープなしで使いたい
2. setopt nonomatch
3. ファイル名を補完した後に挿入されたスペースが消えてしまう
ZLE_REMOVE_SUFFIX_CHARS=$''
~/.zshrc
ここまでの (クリックで展開)
setopt nonomatch
setopt RM_STAR_SILENT
ZLE_REMOVE_SUFFIX_CHARS=$''
autoload -Uz colors && colors
zstyle ":completion:*:commands" rehash 1
if type brew &>/dev/null; then
FPATH=$(brew --prefix)/share/zsh-completions:$FPATH
autoload -Uz compinit && compinit
source $(brew --prefix)/share/zsh-autosuggestions/zsh-autosuggestions.zsh
source $(brew --prefix)/opt/zsh-git-prompt/zshrc.sh
fi
typeset -U path PATH
path=(
/opt/homebrew/bin(N-/)
/opt/homebrew/sbin(N-/)
/usr/local/bin(N-/)
/usr/local/sbin(N-/)
/usr/bin
/usr/sbin
/bin
/sbin
/Library/Apple/usr/bin
)
if type brew &>/dev/null && type $(brew --prefix)/bin/python3.11 &>/dev/null; then
alias python="$(brew --prefix)/bin/python3.11"
alias pip="$(brew --prefix)/bin/pip3.11"
else
alias python="/usr/bin/python3"
alias pip="/usr/bin/pip3"
fi
git_prompt() {
if [ "$(git rev-parse --is-inside-work-tree 2> /dev/null)" = true ]; then
PROMPT="%F{034}%n%f:%F{020}%~%f $(git_super_status)"$'\n'"%# "
else
PROMPT="%F{034}%n%f:%F{020}%~%f "$'\n'"%# "
fi
}
add_newline() {
if [[ -z $PS1_NEWLINE_LOGIN ]]; then
PS1_NEWLINE_LOGIN=true
else
printf '\n'
fi
}
precmd() {
git_prompt
add_newline
}
tgz() {
if [ $# -lt 2 ]; then
echo "Usage: tgz DIST SOURCE"
else
xattr -rc "${@:2}" && \
env COPYFILE_DISABLE=1 tar zcvf "$1" --exclude=".DS_Store" "${@:2}"
fi
}
x64
と arm64
の環境を行ったり来たりする (Apple Silicon)
(おまけ) M プロセッサを搭載した Mac で Rosetta 2 と arm64 の環境をコマンドラインから切り替えられるようにします。
# エイリアスを設定
if (( $+commands[arch] )); then
alias x64='exec arch -arch x86_64 "$SHELL"'
alias a64='exec arch -arch arm64e "$SHELL"'
fi
# 上記エイリアスが実行されると環境変数を書き換えます
if [[ $(uname -m) == "x86_64" ]]; then
export VOLTA_HOME="$HOME/.volta_x64"
typeset -U path PATH
path=(
$VOLTA_HOME/bin
/usr/local/bin(N-/)
/usr/local/sbin(N-/)
/usr/bin
/usr/sbin
/bin
/sbin
/Library/Apple/usr/bin
)
else
export VOLTA_HOME="$HOME/.volta"
typeset -U path PATH
path=(
$VOLTA_HOME/bin
/opt/homebrew/bin(N-/)
/opt/homebrew/sbin(N-/)
/usr/bin
/usr/sbin
/bin
/sbin
/usr/local/bin
/usr/local/sbin
/Library/Apple/usr/bin
)
fi
Discussion