😎

あいまい検索 fzfのすゝめ

2023/07/01に公開

fzfで何できるん?

fzfは曖昧検索をしてくれる優れものです。
ターミナルで生活されている方は大体入っていると思います。

この記事では
fzfを入れてみた/興味がある が活用方法が分からない…。

そんなあなたへ
簡単な具体例をいくつか紹介します。
この記事を見て、ぜひ使い方を学んでみてください。

使用環境

wsl2の環境を想定。
ディストリビューションは特にありません。UbuntuでもArch Linuxでもお好きなもので。
macでもほぼ変わりないです。(多分)

初期設定完了後の状態からスタートとします。

使用方法

早速fzfを入れてみましょう。
https://github.com/junegunn/fzf

インストール

READMEのInstallationを参考。

brew

# brew
brew install fzf

# インストールコマンド
$(brew --prefix)/opt/fzf/install

# =====

# git clone
git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf

# インストールコマンド
~/.fzf/install

インストールコマンド実行後
~/.bashrcまたは~/.zshrcに以下が追加されます。

~/.bashrc
[ -f ~/.fzf.bash ] && source ~/.fzf.bash

インストールは以上です。

基本的な使い方

fzfコマンドを実行してみましょう。
カレントディレクトリ以下のファイル一覧がずらっと出てきます。

fzf
fzfの基本

キーを入力すると、検索を行えます。
目的のファイルが見つかったらEnterを押しましょう。

標準出力にファイルパスが出力されます。
これが大事です。

fzfは検索結果が出力されます。
つまり、選択結果を任意のコマンドに渡せるということです。

結果を別コマンドに渡してみる

公式にvim $(fzf)の紹介があります。
早速使ってみましょう。

fzf_vim
vim $(fzf) 選択したパスをvimで開く

vim ${fzf}だけで編集画面を開くことが可能になります。

fzfのオプション

fzfには沢山オプションがあります。
正直覚えるのは大変なので
まずは以下に紹介するものを抑えてください。

-1 --select-1

検索対象が一つしかなかった場合、自動で選択されるオプションです。

+m -m --multi

複数選択を行うオプションです。

  • -m --multiはtabキーによる複数選択が可
  • +mは複数選択が不可

デフォルトでは+mが選択されているっぽいです。(確証が取れませんが…)
複数選択でない場合は+mを明示的につけてあげると良いと思います。

--ansi

ANSIカラーコードを有効にします。
但し、fzfのスキャンが遅くなるので後述するデフォルトオプション指定は非推奨。

以下公式引用

--ansi tells fzf to extract and parse ANSI color codes in the input, and it makes the initial scanning slower. So it's not recommended that you add it to your $FZF_DEFAULT_OPTS.

$FZF_DEFAULT_OPTS

~/.bashrcに記載します。
列挙しておけばfzfコマンドでオプションが適用されます。

スクリプトと組み合わせる

前述までの内容で、fzfの概要と基本操作が分かってきたと思います。
ここからは、具体的な使い方をいくつか紹介します。

fzf+ghqでリポジトリ移動を行う

ghqはgitのリポジトリ管理が一元化できます。
https://github.com/x-motemen/ghq

ghq get {リポジトリURL}で起点ディレクトリ配下にリポジトリを配置してくれます。

一元化されると

{起点ディレクトリ}/{urlで自動的にパスが切られる}/お目当てのリポジトリ名

みたいなパス構成になります。

開発リポジトリをひとまとめにする。
この仕様とfzfを組み合わせた移動スクリプトを紹介します。

インストール方法

READMEのINSTALLATIONを参考。
お好きな方法でどうぞ。

# brew
brew install ghq

# go
go install github.com/x-motemen/ghq@latest

# git clone
git clone https://github.com/x-motemen/ghq .
make install

初期設定

一元化するにあたり、起点ディレクトリを設定します。

~/.gitconfigに設定を追加するだけです。
今回は~/srcを起点にします。

git config --global ghq.root '~/src'

起点ディレクトリはghq rootで確認可能です。

ghq root
# /home/{username}/src

後はリポジトリをghq get {url}でひたすら取得しましょう!

該当リポジトリに移動する

ここからが本番。
~/.bashrcに以下を追記してください。

~/.bashrc
# ghq cd
cdrepo() {
  local repodir=$(ghq list | fzf -1 +m) && cd $(ghq root)/$repodir
}

fzfの基本的使い方を見た後であれば
何となくやりたい事が分かると思います。

  • ghq listでリポジトリ(パス一覧)を取得
  • リポジトリ一覧をfzfの検索対象にする。
  • 決定したパスに起点ディレクトリパスを追加してcd

cdrepo
一元化したリポジトリに自由に移動できる

このコマンドでリポジトリへの移動が完結します。

該当リポジトリをVSCodeで開く

上記を応用して
指定リポジトリをVSCodeで開いてみます。

~/.bashrc
# 選択したリポジトリをvscodeで開く
coderepo() {
  local repodir=$(ghq list | fzf -1 +m) &&
  echo Open VSCode WorkSpace! : $(ghq root)/$repodir
  if [ -n "$repodir" ]; then
   code $(ghq root)/$repodir
  fi
}

coderepo
指定したリポジトリをVSCodeで開く

VSCodeはcode {パス}で起動する事が可能です。
出社したらターミナル開いて、コマンド叩くだけで開発環境が起動する…。
これを一度味わったらもう戻れません。

fzf + dockerで起動・停止を行う

docker。毎回コマンド叩くの面倒ですよね。
これも効率化しちゃいましょう。

~/.bashrc
# コンテナ起動コマンド
dstart() {
  # 起動するコンテナ名を取得
  local cname=$(docker ps -a --format "table {{.Names}}\t{{.ID}}\t{{.Status}}" | sed 1d | fzf -1 +m | awk '{print $1}')
  [ -n "$cname" ] && docker start $cname
}

# コンテナ停止コマンド
dstop() {
  # 停止するコンテナ名を取得
  local cname=$(docker ps --format "table {{.Names}}\t{{.ID}}\t{{.Status}}" | sed 1d | fzf -1 +m | awk '{print $1}')
  [ -n "$cname" ] && docker stop $cname
}

docker ps -a --format "table {{}}"でコンテナ一覧をフォーマットして出力。
fzfの結果をawkコマンドで整形。コンテナ名をdocker startに流します。

停止もほぼ一緒です。
docker psにして-aを抜いています。起動しているコンテナだけを選択対象にできます。

ただ、これに関してはlazydockerの方が扱いやすいかもしれません…。
https://github.com/jesseduffield/lazydocker

Tips:tmuxを使っているあなたへ

tmuxは端末多重接続ができる優れものです。
https://github.com/tmux/tmux

ターミナルを

  • セッション
  • ウィンドウ
  • ペイン

に分割する事が可能です。
そんなtmuxをお使いのあなたはfzf-tmuxでカッコよく検索する事ができます。

今回はfzfの説明のため、tmuxのインストール方法は省略します。
使ってみたい!と思った方は以下の記事を参考に導入してください。
インストールから基本操作まで把握できます。
https://www.tohoho-web.com/ex/tmux.html

記事での記載はありませんが
brew install tmuxでもインストール可能です。

tmuxの設定(~/.tmux.conf)についてはこちらを一読。
私はこれをベースに(ほぼ全部流用して)使っています。
https://qiita.com/youichiro/items/dd54c38c2f3873348c78

正直設定は沼なので、一旦コピペして
使いながら削ったり、足したりすれば良いと思います。

fzf-tmux

fzf-tmuxfzfインストール時に一緒にインストールされるため、追加作業は不要です。
fzf-tmuxを使うと、別のペインが立ち上がって検索画面(以後検索ペインと呼びます)が表示されます。
この時-pオプションを付けると検索ペインが画面中央に表示されます。

fzf-tmux
fzf-tmux カッコよく検索したいあなたへオススメ!

なお、検索ペインの高さ、幅は個別に設定可能です。-pはデフォルトで50%です。
こだわりが無ければデフォルト値で問題ありません。
fzf-tmux --helpで指定方法が出てくるので、気になったら調べてみてください。

Tips: Homebrewのインストール

今回紹介したfzftmuxbrew installで導入可能です。
毎回git clone が面倒だな…と思われた方は入れてみてください。

Homebrewの概要はこちらの記事
https://zenn.dev/sawao/articles/e7e90d43f2c7f9

インストールは公式に沿って進めれば導入できます。
https://brew.sh/index_ja

まとめ

ターミナル生活に憧れがあった私が、頑張ってパスを書いていたあの頃。

そんなある日。先輩から
fzf, tmuxの2つの神器。そして
ぼくの考えたさいきょうの.bashrcをいただきました。
今回紹介したスクリプトは先輩からいただいた.bashrcがベースになっています。
この場を借りてお礼申し上げます…。

ぜひ、皆さんもターミナル生活を少しでも豊かにしてみてください!
以上、お疲れさまでした!

参考文献

fzf

ghq

tmux

Discussion