Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
101
Help us understand the problem. What is going on with this article?

More than 1 year has passed since last update.

@kompiro

fzfを使おう

これはなに?

インクリメンタル検索ができる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

他のOS用パッケージ

プレビューウィンドウの起動方法

選択中の文字列を任意のコマンドにわたすことでプレビューウィンドウにこんな感じで実行結果を表示します。

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を使うよう、下記のように設定しています。

.zshrc
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を便利にするには fzffzf.vim 双方を入れておくと良いでしょう。

fzfを開発している方がvimのプラグインマネージャvim-plugも開発されています。vim-plug を使ってインストールする場合は下記のように書きますが、お使いのプラグインマネージャでインストールしましょう。

vimrc
Plug '/usr/local/opt/fzf'
Plug 'junegunn/fzf.vim'

fzf.vim でよく使うコマンドや設定

コマンド 一覧されるもの
Files ファイル
GFiles git ls-files の結果
History 最近使ったファイル
Buffers 開いているバッファ
Rg ripgrep 結果
vimrc
" 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ファイルをプレビューできるようにしておくと便利です。

zshrc
alias gcd='ghq look `ghq list |fzf --preview "bat --color=always --style=header,grid --line-range :80 $(ghq root)/{}/README.*"`'

git連携

ブランチの内容を確認しつつcheckoutしたいんや

.zshrc
# 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のツールチェーンの強みだなぁ、と改めて思いました。

101
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
101
Help us understand the problem. What is going on with this article?