fzf と bat で簡易ファイル・ディレクトリピッカーを作ったら便利だった

fzfbat を組み合わせて、簡易的なファイル・ディレクトリピッカーを用意したらいろいろ便利だったので、メモ。

fzfbat のほか、fdlsd を使ってます。

Alt + f でファイル・ディレクトリピッカーを起動.sh
fzf-file-widget-preview() {
local preview='
if [[ -d {} ]]; then lsd -la {}
else bat --color=always --style=numbers --line-range=:500 {} 2>/dev/null || cat {}
fi
'
local selected=$(fd . | fzf --preview "$preview" --preview-window 'right:50%:wrap')
[[ -n "$selected" ]] && LBUFFER+="$selected"
zle redisplay
}
zle -N fzf-file-widget-preview
bindkey '^[f' fzf-file-widget-preview

このように、プレビューを見ながら、ファイルやディレクトリを選択できます。

今までは、補完を駆使して手で入力をするか、IDE 上でのファイルツリーなどからパスをコピーすることが多かったのですが、、この方法を使うと簡単にパスを取得できて便利です。

完全版

いろいろ付け足した完全版がこちらです。

パスの途中からでも検索できるようにし、画像や PDF のプレビューも追加しています。

pdf はプレビューは tdf を使いたかったんですが、fzf のプレビューでうまく動かなかったので、pdftoppmchafa を組み合わせています。

Alt + f でファイル・ディレクトリピッカーを起動(完全版).sh
fzf-file-widget-preview() {
local prefix="${LBUFFER##* }"
local lbuf_prefix="${LBUFFER% *} "
local search_dir="." query="" path_prefix=""
if [[ "$LBUFFER" != *" "* ]]; then
prefix="$LBUFFER"
lbuf_prefix=""
elif [[ "$LBUFFER" == *" " ]]; then
prefix=""
lbuf_prefix="$LBUFFER"
fi
if [[ -n "$prefix" ]]; then
local expanded="${prefix/#\~/$HOME}"
if [[ -d "$expanded" ]]; then
search_dir="$expanded"
path_prefix="${prefix%/}/"
elif [[ "$prefix" == */* ]]; then
local dir="${expanded%/*}"
[[ -z "$dir" ]] && dir="/"
if [[ -d "$dir" ]]; then
search_dir="$dir"
path_prefix="${prefix%/*}/"
query="${prefix##*/}"
fi
else
query="$prefix"
fi
fi
local preview='
f={}; [[ "$f" != /* ]] && f="'"$search_dir"'/$f"
if [[ -d "$f" ]]; then
lsd --color=always --icon=always -la "$f"
elif [[ "$f" =~ \.(png|jpe?g|gif|bmp|webp|svg|ico)$ ]]; then
chafa -s 80x24 "$f" 2>/dev/null || file "$f"
elif [[ "$f" =~ \.pdf$ ]]; then
pdftoppm -f 1 -l 1 -png "$f" 2>/dev/null | chafa -s 80x24 || file "$f"
else
bat --color=always --style=numbers --line-range=:500 "$f" 2>/dev/null || cat "$f"
fi
'
local selected=$(cd "$search_dir" 2>/dev/null && fd --hidden . 2>/dev/null | fzf --query "$query" --preview "$preview" --preview-window 'right:50%:wrap')
[[ -n "$selected" ]] && LBUFFER="${lbuf_prefix}${path_prefix}${selected}"
zle redisplay
}
zle -N fzf-file-widget-preview
bindkey '^[f' fzf-file-widget-preview