Back to list
dev_to 2026年3月21日

fzf を大規模リポジトリで再びスナップ動作に復帰する方法: 高速なファジー検索によるディレクトリとファイルの探索

How I Made fzf Feel Snappy Again in Large Repositories

Translated: 2026/3/21 3:06:29

Japanese Translation

終末端末 (Terminal) で作業を行う際、多くの時間をファイルのナビゲーションに費やし、通常は `cd`, `ls`, `find`, `grep` の組み合わせで行います。これはプロジェクトが小さい限り問題ありませんが、プロジェクトが大きくなると、以下のようになるためです。 ```bash cd src cd components cd something find . -iname '*something*' ``` 私は編集器の `Ctrl+P` に近い機能を望んでいました。ファイルやディレクトリに瞬時にジャンプできる、高速なファジー検索機能です。 そのため、私は自分の `.bashrc` に小さな関数を追加し、`fzf` を使用して、まるで小さなインタラクティブなファイルブラウザのようにファイルシステムを閲覧する機能を実装しました。この関数により、ファイルをファジー検索し、プレビュー表示、ディレクトリ contents をプレビュー表示、`$EDITOR` でファイルをオープン、ディレクトリに `cd` することができます。 ここでは、私の dotfiles からの関数コードです。 ```bash # fzf を使用してディレクトリとファイルをBrowseする # ディレクトリに cd し、ファイルを $EDITOR でオープンする function browse() { command -v fzf >/dev/null || { echo

Original Content

Most of the time when I’m working in the terminal, I’m navigating files. Usually that looks like some combination of: cd ls find grep Which works fine… until a project gets large. Then it turns into: cd src ls cd components ls cd something find . -iname something I wanted something closer to Ctrl+P in an editor. A quick fuzzy search that lets me jump to files or directories instantly. So I added a small function to my .bashrc that lets me browse the filesystem with fzf like a tiny interactive file browser: fuzzy search files and directories preview files preview directory contents open files in $EDITOR cd into directories Here’s the function from my dotfiles. # Browse files and directories with fzf - cd to directories, open files with $EDITOR function browse() { command -v fzf >/dev/null || { echo "fzf not found" >&2; return 1; } local selection fifo="/tmp/browse_$$" # Create named pipe mkfifo "$fifo" # Run find (or fd if available) in background, writing to named pipe (suppress job control) if command -v fd >/dev/null 2>&1; then { fd -H -t f -t d . > "$fifo"; } & else { (find . -type f -o -type d 2>/dev/null | sed 's|^\./||') > "$fifo"; } & fi local find_pid=$! # Run fzf reading from named pipe selection=$(fzf ${1:+-q "$1"} --preview 'if [[ -d {} ]]; then ls -la {}; else bat --style=numbers --color=always --line-range :50 {} 2>/dev/null || cat {} 2>/dev/null || echo "Cannot preview file"; fi' < "$fifo") local exit_code=$? # Kill background process and cleanup (suppress all output) kill $find_pid >/dev/null 2>&1 wait $find_pid >/dev/null 2>&1 rm -f "$fifo" [[ $exit_code -ne 0 ]] && return $exit_code [[ -z "$selection" ]] && return if [[ -d "$selection" ]]; then builtin cd "$selection" elif [[ -f "$selection" ]]; then ${EDITOR:-vim} "$selection" else echo "Selection is neither a file nor a directory: $selection" >&2 return 1 fi } Now I can run: browse or even: browse bash And instantly fuzzy-search everything under the current directory. fzf with a Named Pipe This is the most interesting part. Instead of running find first and piping into fzf, the function uses a named pipe. mkfifo "$fifo" Then find (or fd for better performance) runs in the background writing results into the pipe: fd ... > "$fifo" & And fzf reads from the pipe: fzf < "$fifo" This means: fzf can start immediately while results are still being discovered. For large directories this feels much faster and allows you to make a selection before find completes. Instead of triggering browse by injecting a command into the prompt, I prefer binding it directly to a key in Bash. Here’s the helper I use: ## Bindings ## bind_bash_function() { local key="$1" local fn="$2" local wrapper="__bind_${fn//[^a-zA-Z0-9_]/_}" eval " $wrapper() { local __line=\$READLINE_LINE local __point=\$READLINE_POINT $fn READLINE_LINE=\$__line READLINE_POINT=\$__point } " bind -m emacs-standard -x "\"$key\": $wrapper" bind -m vi-insert -x "\"$key\": $wrapper" } bind_bash_function '\C-f' browse This binds Ctrl+F directly to the browse function. This makes the interaction feel much smoother, especially if you trigger it while you’re in the middle of typing a command. The helper also binds the key for both Emacs-style and vi-style editing modes so the behavior stays consistent regardless of the editing mode in use. There are plenty of file navigation tools out there, but I like this approach because it stays simple and fits naturally into my shell. It: lives entirely in my .bashrc only depends on fzf (and bat if you want color) can be bound directly to a key like Ctrl+F returns you to exactly the same command line after it runs Binding it directly to a key makes it feel less like a command I have to remember and more like a built-in capability of the shell. It’s just a small shell upgrade, but it removes a surprising amount of friction from everyday workflows. I treat my dotfiles like a collection of tiny productivity improvements. Each one only saves a few seconds, but when you run thousands of shell commands every week, those seconds add up. This browse function ended up being one of my favorites.