---
title: Zsh 環境
url: https://doc.liz6.com/ja/tools/shell
locale: ja
area: tools
tags:
- tools
date: null
modified: 2026-07-16
description: zsh で書く価値があるのは補完のみ。ネイティブを基盤とし、carapace でフォールバックし、fzf-tab がコマンドごとにプレビューを提供する。
---

# Zsh 環境

zsh の設定は200行程度で、プロンプトは starship、エイリアスは多数あるが、これらについて語ることはほとんどない。唯一手間をかけ、かつ書く価値があるのは**補完**だ。私は Tab キーでプレビュー付きのメニュー表示にし、そのために carapace と少し格闘した。

補完の優先順位は、ネイティブな `compinit` を基盤とし、carapace はフォールバックとしてのみ機能する。この順序は重要だ。carapace のデフォルト初期化では `compdef` を使って700以上のコマンドを乗っ取るが、これは一見楽に見えるが、実際には zsh ネイティブのより細かな補完や、fzf-tab が依存するサブコマンドのコンテキスト（例えば `git checkout` でブランチごとにプレビューを表示するなど）をすべて上書きしてしまう。そのため、carapace の compdef をフィルタリングし、ネイティブ補完が失敗した場合のみ carapace が呼ばれるようにしている：

```zsh
source <(carapace _carapace zsh | grep -v '^compdef ')
zstyle ':completion:*' completer _complete _carapace _ignored
```

補完が完了すると、fzf-tab が候補を fzf に渡し、コマンドごとに異なるプレビューを表示する。ファイルは bat でレンダリング、ディレクトリは eza で一覧表示、`kill` はプロセスを表示、`systemctl` はユニットのステータスを直接表示、`git checkout` は最近のコミットを5件表示、`git add` は diff を表示する。これが日常の操作性を最も向上させる部分だ。多くの場合、コマンドを打ち切って Enter を押して結果を見る必要はなく、Tab でプレビューを見るだけで判断できる。

```zsh
zstyle ':fzf-tab:complete:systemctl:*' fzf-preview 'systemctl status --no-pager $word | head -30'
zstyle ':fzf-tab:complete:git-(checkout|switch):*' fzf-preview 'git log --oneline -n 5 $word'
```

このプレビュー機能は華やかに見えるが、落とし穴も多い。すべてコメントに記した。fzf が認識しないフラグを与えると、補完リストが突然空になったり fzf が終了したりする。また、`fzf-min-height` を大きすぎると、候補が少ない場合に下部に空白が生じる。そのため、`--no-sort` や `fzf-pad 0` といった設定は単にコピーしたのではなく、実際に調整して導き出したものだ。

補完以外にも、シェルを「手に馴染む」ようにする小さな工夫がいくつかある。それぞれ一言で説明する。

**zsh-autosuggestions** は fish シェルのような履歴のグレー表示ヒントを提供する。入力の途中に、直近で一致したコマンド全体をグレー文字で後ろに補完し、`→` または `Ctrl+f` で受け入れる。非同期で候補を取得するため（`ZSH_AUTOSUGGEST_USE_ASYNC`）、履歴が長くてもキー入力がブロックされない。

**zsh-syntax-highlighting** は入力しながら検証を行う。コマンドが存在すれば緑、存在しなければ赤、引用符が閉じていなければ即座に色が変わるため、Enter を押す前にタイプミスに気づける。このプラグインは**`.zshrc` の最後に source する必要がある**。すべての ZLE 部品を包む最外層フックに設定する必要があるため、先に読み込むと後続のプラグインに上書きされてしまう。

**starship** はプロンプトとして使用する。単一の TOML 設定でシェルの種類を問わず通用し、ディレクトリのコンテキストに応じて git ブランチ/ステータス、言語バージョン、k8s コンテキストなどを表示する。関連する時のみ表示され、常に表示されて画面を埋め尽くすことはない。

**ssh 補完**のソースを変更した。デフォルトでは `known_hosts`（多数の IP アドレス、ハッシュ化されているため読めないものもある）を参照するが、これを `~/.ssh/config` の `Host` エイリアスのみから補完するように変更した。`ssh <TAB>` を押すと、私が名前をつけたマシンが直接リストされ、誰が誰だか一目でわかる。

`zoxide` の `z` によるディレクトリジャンプ、`ls` の eza への完全置換、git pager の delta への切り替えなど、これらの詳細は [CLI ツールボックス](cli-toolbox.md) のセクションで解説する。
