これはなに?
インクリメンタル検索ができるGo製のツールです。同様でよく使われるツールにpecoがあります。fzfはプレビューウィンドウ表示ができるのが一番の違いでしょうか。
その他、tmuxと連携する fzf-tmux が同梱されていたり、 vim と連携する fzf.vim が開発されていたりするなど、関連ツールが充実しています。
インストール方法
fzf は homebrew 等でも配布されていますが、go製のツールなので、リポジトリをcloneしてビルドしたほうが手っ取り早いかもしれません。
homebrew/Linuxbrewでのインストール
$ brew install fzf
# shellのキーバインディングへの追加やfuzzy finder(ゆるふわ検索)機能を追加したい場合は下記のコマンドを実行しましょう
$ $(brew --prefix)/opt/fzf/install
git clone
$ git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf
$ ~/.fzf/install
使い方
peco と同様に標準出力に食わせましょう。
$ vi `find * -type f | fzf`
上記は選択したファイルをviで開きます。このままだと .git
配下なども検索対象に含まれるので、ripgrepや、シンタックスハイライトをしてくれるbatも入れちゃいましょう。
一緒に入れとくと便利奴
ripgrep
ripgrep
はgrepを強化したツールですが、gitでignoreしたファイルを無視できるツールなので一緒に入れてあげると良いでしょう。ripgrepはrust製ツールです。
インストール方法
こいつも Homebrew に公開されているので下記でOKです。
$ brew install ripgrep
他のOSの場合 release ページにDistributionに対応したパッケージがおいてあるのでそれを入れると良いでしょう。
rust製ツールはrust用のパッケージマネージャcargoを使えば各OS用のパッケージを作成できます。そのせいかrust製のツールは大体パッケージも用意されているのも便利ですね。
bat
bat
は rust製cat のクローンです。標準で様々な言語のシンタックスハイライトを提供してくれます。
インストール方法
同上です。
$ brew install bat
プレビューウィンドウの起動方法
選択中の文字列を任意のコマンドにわたすことでプレビューウィンドウにこんな感じで実行結果を表示します。
fzf --preview [command]
例えば head -100 {}
という文字列を [command]
に入れてみましょう。選択中のファイル(文字列ですが)の先頭100行が表示されるはずです。{}
にfzfで選択中の文字列が渡ります。例えば、fzfでREADME.md
を選択しているのであれば、プレビューウィンドウには head -100 README.md
のように渡ります。batと連携するなら、
fzf --preview "bat --color=always --style=header,grid --line-range :100 {}"
としたらOKです。
キーバインド
fzfをインストールするとき、キーバインドの設定を勧められます。ついでに設定しておくと便利です。
冒頭のasciinemaは <CTRL+T>
を叩いたもので、カレントディレクトリ配下のファイルをインクリメンタル検索できます。
これをripgrepとbatを使うよう、下記のように設定しています。
export FZF_CTRL_T_COMMAND='rg --files --hidden --follow --glob "!.git/*"'
export FZF_CTRL_T_OPTS='--preview "bat --color=always --style=header,grid --line-range :100 {}"'
他にも用意されているキーバインドには <CTRL+R>
と <ALT+C>
があります。<CTRL+R>
はコマンド履歴、 <ALT+C>
はディレクトリ移動です。
** を活用する
カレントディレクトリではなく、入力している文字列からインクリメンタル検索をしたいときは **
を使うと良いでしょう。
例えば、 src/github.com/motemen/ghq
配下のファイルを検索したい場合は下記のように src/github.com/motemen/ghq/**
と入力したあとに <TAB>
を入力すると fzf
が起動し、補完できます。
もし、batを使ってプレビューしたいのであれば、環境変数FZF_DEFAULT_OPTS
を使って指定すると良いでしょう。fzfは環境変数で諸々指定できる点も便利です。巨大なgitリポジトリの場合、git ls-tree -r --name-only HEAD
を使ったほうが高速にリストを作成できるようです。そういった場合は、そのリポジトリ配下のみ環境変数が有効になるように direnv を設定しておくとよいでしょう。
ファイル以外にも使える **
# 現在実行中のプロセスをkillする
$ kill -9 **<TAB>
# 接続先のホストをインクリメンタル検索(/etc/hosts等から絞り込み)
$ ssh **<TAB>
# 環境変数をunset
$ unset **<TAB>
vim連携
fzfはvim と連携する fzf.vim が開発されていると冒頭に紹介したりしました。vimから呼び出すコマンド自体はfzf本体に内包され、fzf.vim
はそれを使ったプラグイン、という構成になっています。そのため、vimを便利にするには fzf
と fzf.vim
双方を入れておくと良いでしょう。
fzfを開発している方がvimのプラグインマネージャvim-plugも開発されています。vim-plug を使ってインストールする場合は下記のように書きますが、お使いのプラグインマネージャでインストールしましょう。
Plug '/usr/local/opt/fzf'
Plug 'junegunn/fzf.vim'
fzf.vim でよく使うコマンドや設定
コマンド | 一覧されるもの |
---|---|
Files | ファイル |
GFiles | git ls-files の結果 |
History | 最近使ったファイル |
Buffers | 開いているバッファ |
Rg | ripgrep 結果 |
" ripgrepで検索中、?を押すとプレビュー:
command! -bang -nargs=* Rg
\ call fzf#vim#grep(
\ 'rg --column --line-number --no-heading --color=always --smart-case '.shellescape(<q-args>), 1,
\ <bang>0 ? fzf#vim#with_preview('up:60%')
\ : fzf#vim#with_preview('right:50%:hidden', '?'),
\ <bang>0)
" Filesコマンドにもプレビューを出す
command! -bang -nargs=? -complete=dir Files
\ call fzf#vim#files(<q-args>, fzf#vim#with_preview(), <bang>0)
上記の例で登場するfzf#vim#with_preview
等のコマンドが本体で提供されているようです。vim-fzf連携は Terminal モードを使っているようで、Terminalモードの利用例としても興味深いです。
その他便利奴
ghq連携
scmリポジトリマネージャghqも勢いにまかせてget
しまくると知らないリポジトリだらけになるので、READMEファイルをプレビューできるようにしておくと便利です。
alias gcd='ghq look `ghq list |fzf --preview "bat --color=always --style=header,grid --line-range :80 $(ghq root)/{}/README.*"`'
git連携
ブランチの内容を確認しつつcheckoutしたいんや
# fbr - checkout git branch
function fzf-checkout-branch() {
local branches branch
branches=$(git branch | sed -e 's/\(^\* \|^ \)//g' | cut -d " " -f 1) &&
branch=$(echo "$branches" | fzf --preview "git show --color=always {}") &&
git checkout $(echo "$branch")
}
zle -N fzf-checkout-branch
bindkey "^b" fzf-checkout-branch
最後に
以上ざっくりまとめてみましたが、プレビューウィンドウが追加されるだけで、IDEで実装しようとするといろいろ大変な諸々が、コマンドを組み合わせるだけで実現できるのがCUIというか、Unixのツールチェーンの強みだなぁ、と改めて思いました。