fzf
fzf(fuzzy finder)はコマンドラインであいまい検索ができるツール(類似ツールとしてはpercol, peco, selecta, pick, pmenuなどがある)。ファイル名やコマンド履歴などをインタラクティブに絞り込んでいくことができるので慣れると手放せないツールになる。
今までfzfを履歴検索などで何となく使っていたが、見た目の細かい変更方法やプレビュー機能などを知らなかったのでREADME, Wikiを読んで使い方を調べてみる。

インストール
READMEには複数のインストール方法が書いてあるが今回はgitでインストールする(なおシェルはZshを使う)。macOSのHomebrewやWindowsのChocolately、Vimのプラグインとしてインストールする方法はREADMEを参照。
gitでインストールする場合は下記2つのコマンドを実行する。
$ git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf $ ~/.fzf/install
~/.fzf/installを実行すると以下のように3回y/nの質問をされるが特に問題がなければ全部yにすればよい。
Downloading bin/fzf ...
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 616 0 616 0 0 624 0 --:--:-- --:--:-- --:--:-- 623
100 894k 100 894k 0 0 13905 0 0:01:02 0:01:02 --:--:-- 8323
- Checking fzf executable ... 0.17.0
Do you want to enable fuzzy auto-completion? ([y]/n) y
Do you want to enable key bindings? ([y]/n) y
Generate ~/.fzf.bash ... OK
Generate ~/.fzf.zsh ... OK
Do you want to update your shell configuration files? ([y]/n) y
Update /home/vagrant/.bashrc:
- [ -f ~/.fzf.bash ] && source ~/.fzf.bash
+ Added
Update /home/vagrant/.zshrc:
- [ -f ~/.fzf.zsh ] && source ~/.fzf.zsh
+ Added
Finished. Restart your shell or reload config file.
source ~/.bashrc # bash
source ~/.zshrc # zsh
Use uninstall script to remove fzf.
For more information, see: https://github.com/junegunn/fzf
具体的には、オートコンプリートを有効にしたい場合は下記質問に対してyにする。
Do you want to enable fuzzy auto-completion? ([y]/n) y
キーバインドを有効にしたい場合は下記質問に対してyにする。
Do you want to enable key bindings? ([y]/n) y
.zshrcにfzfの起動設定を追加する場合は下記質問に対してyにする。
Do you want to update your shell configuration files? ([y]/n) y
最後の質問をyにすると.zshrcの末尾に下記コードが追加される。
[ -f ~/.fzf.zsh ] && source ~/.fzf.zsh
~/.fzf.zshの中ではオートコンプリート、キーバインドの設定がされておりnにした場合は下記コードがコメントアウトされるようだ。
# Auto-completion # --------------- [[ $- == *i* ]] && source "/home/vagrant/.fzf/shell/completion.zsh" 2> /dev/null # Key bindings # ------------ source "/home/vagrant/.fzf/shell/key-bindings.zsh"
アップデート
fzfは今も開発を継続しているのでアップデートする場合は下記コマンドを実行する(gitでインストールした場合)。Homebrewなどでインストールした場合のアップデート方法はREADMEを参照。
$ cd ~/.fzf && git pull && ./install
使い方:基本
動作確認
インストールが成功していればfzfとfzf-tmuxというコマンドが使えるようになっている。
$ fzf --version 0.17.0 (e89eebb) $ fzf-tmux --version fzf-tmux (with fzf 0.17.0 (e89eebb))
fzfはメインコマンドでfzf-tmuxはfzfをtmuxペインで開くコマンドなので、まずはfzfコマンドを使ってみる。
基本的には標準入力からリストを読み込んで、fzfで絞り込みをして、標準出力するという流れになる。
下記コマンドを実行するとカレントディレクトリ以下のファイル一覧が表示されるので、適当な文字を入力して絞り込んでから、リターンキーを押すとselectedファイルに選択したファイル名が出力される(fzfの便利さはわからない例だけど)。
$ find * -type f | fzf > selected

標準入力がない場合はfzfはfindコマンドでカレントディレクトリ以下のファイルを読み込む(デフォルトはfindだがFZF_DEFAULT_COMMANDで変更可能)。
下記コマンドを実行するとカレントディレクトリ以下のファイルが表示されるので、絞り込みをしてEnterを押すとそのファイルをvimで開くことができる。
$ vim $(fzf)
絞り込み画面での操作
絞り込み画面でのキー操作は以下のようになっている。また、Ctrl-aやCtrl-eなどのEmacsキーバインドも使える。
| キー | 動作 |
|---|---|
| Ctrl-k または Ctrl-p | カーソルを上に移動 |
| Ctrl-j または Ctrl-n | カーソルを下に移動 |
| Enter | アイテム選択 |
| Ctrl-c または Ctrl-g または ESC | 終了 |
| Tab または Shift-Tab | 複数アイテム選択(-mのマルチセレクトモード時) |
絞り込み画面の表示変更
fzfはデフォルトではフルスクリーンモードで表示するが、オプションで表示の変更をすることができる。
絞り込み画面の高さを変更する場合は--heightを、表示を上から下に変更する場合は--reverseを、上下に枠線を表示する場合は--borderオプションを指定する。
$ vim $(fzf --height 40% --reverse --border)
毎回オプションを指定するのは大変なのでお気に入りのオプションは環境変数FZF_DEFAULT_OPTSに指定しておくとよい。
export FZF_DEFAULT_OPTS='--height 40% --reverse --border'

その他のオプションとしては、入力プロンプトやヘッダ文字列を指定する--prompt, --header、マージンを指定する--margin、ファイル数情報をインライン表示する--inline-infoなどがある。
$ fzf --prompt="P " --header="H" --margin=1,3 --inline-info
絞り込み画面での検索パターン
絞り込み画面での検索パターンは以下のようになっている。fzfはデフォルトでは"extended-search mode"と呼ばれるモードになっており、^music .mp3$ sbtrkt !fireのように検索語をスペース区切りで複数指定できる。
| 文字 | 説明 |
|---|---|
| sbrtkt | sbrtktの文字がどこかにある文字列(あいまい一致) |
| ^music | musicで始まる文字列 |
| .mp3$ | .mp3で終わる文字列 |
| 'wild | wildという並びがある文字列(完全一致) |
| !fire | fireを含まない文字列 |
| !.mp3$ | .mp3で終わらない文字列 |
あいまい一致が嫌な場合はfzf -eオプションを指定すると'を付けなくても完全一致になる。
また|はORの意味なので以下のようにすればgo, rb, pyで終わる文字列に一致する。
go$ | rb$ | py$
キーバインド
インストール時にキーバインドを有効にした場合は下記キーバインドが使えるようになっている。
Ctrl-t
カレントディレクトリ以下のファイル、ディレクトリが表示され、選択したファイルをコマンドラインにペーストする。コマンドの変更はFZF_CTRL_T_COMMAND、オプションの変更はFZF_CTRL_T_OPTSで指定する。
Ctrl-r
コマンド履歴からあいまい検索ができるのでコマンドを再実行したいときに便利。Ctrl-rをさらに押すと時系列順、関連順のソート切り替えができる。追加のオプションはFZF_CTRL_R_OPTSで指定する。

Alt-c
カレントディレクトリ以下のディレクトリが表示され、選択したディレクトリにcdできる。コマンドの変更はFZF_ALT_C_COMMAND、オプションの変更はFZF_ALT_C_OPTSで指定する。
オートコンプリート
インストール時にオートコンプリートを有効にした場合は**を押した後にTabを押すと補完が効くようになっている。例えば以下のようにvim **と入力した後でTabを押すと、カレントディレクトリ以下のファイル、ディレクトリが補完される。
$ vim **<TAB>

COMMAND [DIRECTORY/][FUZZY_PATTERN]**<TAB>というパターンで補完できるので、以下のような使い方ができる。
$ vim ../**<TAB> $ vim ../fzf**<TAB> $ vim ~/**<TAB> $ cd **<TAB> $ cd ~/github/fzf**<TAB>
補完のトリガーを**から変更したい場合は以下のように設定する。
export FZF_COMPLETION_TRIGGER='~~'
補完用のオプションはFZF_COMPLETION_OPTSで設定する。
export FZF_COMPLETION_OPTS='+c -x'
環境変数
fzfはデフォルトではfindコマンドを使うようになっているが、例えばagコマンドを使うように変更する場合は以下のように設定する。
export FZF_DEFAULT_COMMAND='ag -g ""'
「絞り込み画面の表示変更」で書いたようにデフォルトオプションを指定する場合は以下のように設定する。
export FZF_DEFAULT_OPTS="--reverse --inline-info"
使い方:応用
fzf-tmux
tmuxを使っているならfzf-tmuxを使うことで絞り込み画面をtmuxペインとして表示することができる。
$ fzf-tmux --help
usage: fzf-tmux [-u|-d [HEIGHT[%]]] [-l|-r [WIDTH[%]]] [--] [FZF OPTIONS]
Layout
-u [HEIGHT[%]] Split above (up)
-d [HEIGHT[%]] Split below (down)
-l [WIDTH[%]] Split left
-r [WIDTH[%]] Split right
(default: -d 50%)
使い方はfzfとしていたところをfzf-tmuxに変更すればよい。fzfで使えるオプションは指定できるようだ。
$ vim $(fzf-tmux --reverse)

デフォルトではペインは下部に表示されるが、表示場所とサイズはオプションで変更は可能。
$ vim $(fzf-tmux -l 20% --reverse)

また、FZF_TMUX=1を設定するとCtrl-rなどで呼び出すときにfzf-tmuxを使うようになる。高さを変更する場合はFZF_TMUX_HEIGHTを設定する。
export FZF_TMUX=1 export FZF_TMUX_HEIGHT=10
オートコンプリート(プロセス、ホスト名、環境変数)
オートコンプリートはコマンドによっては適切な項目を補完できるようになっている。
killコマンドではプロセスを補完できる。マルチセレクトモードなのでTabで複数選択してkillできる。
$ kill -9 <TAB>

ホスト名も補完できる。/etc/hosts, ~/.ssh/configから抽出しているようだ。
$ ssh **<TAB> $ telnet **<TAB>
環境変数やエイリアスも補完可能。
$ unset **<TAB> $ export **<TAB> $ unalias **<TAB>
--ansi, --nth, --with-nthと性能
fzfは高速に動作するのでほとんどのケースで性能は気にならないが、下記オプションを指定すると少し遅くなるのでデフォルトオプションとして指定するのはお薦めしないとのこと。
--ansi
ANSIカラーコードを有効にする。

--nth
検索対象を指定する。図の例ではカンマ区切りで2番目のみを対象としている。

--with-nth
--with-nthは検索対象のみが表示される。
外部プログラム実行
execute, execute-silentを使うと絞り込み画面から抜けることなく外部プログラムを実行することができる。
例えば下記コマンドではF1キーを押すとファイルをlessで閲覧し、Ctrl-yを押すと選択行をクリップボードにコピーして終了する(macOSでpbcopyを使える場合)。execute-silentは画面遷移なしに実行するということらしい。
$ fzf --bind 'f1:execute(less -f {}),ctrl-y:execute-silent(echo {} | pbcopy)+abort'
プレビューウィンドウ
--previewオプションを指定すると、現在行を引数として外部プロセスを実行し、結果を別ウィンドウに表示することができる。例えば下記コマンドを実行すると現在行のファイルをcatでプレビューする。
$ fzf --preview 'cat {}'

プレビューは外部プロセスが完了したときに表示されるので実際はcatよりはheadの方がよいとのこと。
$ fzf --preview 'head -100 {}'
プレビューウィンドウはANSIカラーをサポートしているので下記ツールなどでシンタックスハイライトできる。
以下のようにツールが存在しない場合は別ツールで実行するという制御もできる(図はCodeRayを使用)。
$ fzf --preview '[[ $(file --mime {}) =~ binary ]] &&
echo {} is a binary file ||
(highlight -O ansi -l {} ||
coderay {} ||
rougify {} ||
cat {}) 2> /dev/null | head -500'

プレビューウィンドウの位置とサイズはオプションで指定可能。
$ fzf --preview 'file {}' --preview-window down:1
色変更
色変更についてはこのページに書いてある。--color=[BASE_SCHEME][,COLOR:ANSI]という形式で色を指定すればよい。
$ fzf --color=bg+:24 $ fzf --color=light,fg:232,bg:255,bg+:116,info:27
常に色を変更したい場合はFZF_DEFAULT_OPTSで指定する。
export FZF_DEFAULT_OPTS=' --color fg:124,bg:16,hl:202,fg+:214,bg+:52,hl+:231 --color info:52,prompt:196,spinner:208,pointer:196,marker:208 '
Wikiに書いてあった使用例
Wikiに色々な使用例が書いてあったので便利そうなものを見ていく。
プレビューにツリー表示
Alt-cでディレクトリツリーを表示する例。
export FZF_ALT_C_OPTS="--preview 'tree -C {} | head -200'"
--select-1, --exit-0
--select-1を指定すると選択候補が1つしかないときに自動で選択する。--exit-0を指定すると選択候補がないときに自動で終了する。これらのオプションはFZF_ALT_C_OPTSで有用とのこと。
export FZF_ALT_C_OPTS="--select-1 --exit-0"
フルコマンドプレビュー
コマンドが長すぎて画面に収まらないときに?を押すとプレビューウィンドウにコマンドを表示する。
export FZF_CTRL_R_OPTS="--preview 'echo {}' --preview-window down:3:hidden:wrap --bind '?:toggle-preview'"
fe, fkill
下記コードを.zshrcに記述すると、選択したファイルをデフォルトエディタで開くfeコマンド、選択したプロセスをkillするfkillコマンドが使えるようになる。
このようなコマンド例はExamplesに色々と書いてある。
fe() {
local files
IFS=$'\n' files=($(fzf-tmux --query="$1" --multi --select-1 --exit-0))
[[ -n "$files" ]] && ${EDITOR:-vim} "${files[@]}"
}
fkill() {
local pid
pid=$(ps -ef | sed 1d | fzf -m | awk '{print $2}')
if [ "x$pid" != "x" ]
then
echo $pid | xargs kill -${1:-9}
fi
}
Vim連携
fzfの作者によるfzf.vimの使い方は下記記事を参照。