#!/bin/sh prompt=${FZF_PROMPT%> } cmd=${prompt%+*} hidden=${prompt#$cmd} ripgrep='rg --column --line-number --color=always --smart-case' if [ "$1" = list ]; then case "$FZF_HEADER_LABEL" in :?*) dir=${FZF_HEADER_LABEL#?} ;; *) dir= ;; esac case "$prompt" in dir:*) dir=${FZF_HEADER_LABEL#?} fd -t d '' ~/src ~/dotfiles 2 -H -E '\.git' -E node_modules zoxide query -l echo $dir exit ;; files) exec fd --type f '' $dir ;; files+hidden) exec fd --type f -H '' $dir ;; find-files*) exec find $dir -type f ;; search) exec $ripgrep "$FZF_QUERY" $dir ;; search+hidden) exec $ripgrep -. "$FZF_QUERY" $dir ;; git-files*) if [ -z "$dir" ]; then exec git ls-files else exec git -C $dir ls-files --format "$dir/%(path)" fi ;; git-search*) if [ -z "$dir" ]; then exec git grep --column --line-number --color=always "$FZF_QUERY" else exec git -C $dir grep --column --line-number --color=always "$FZF_QUERY" | sed "s:^:$dir/:" fi ;; jj-files*) if [ -z "$dir" ]; then exec jj file list --ignore-working-copy else jj=$(cd $dir && jj root --ignore-working-copy 2> /dev/null) exec jj -R $jj file list --ignore-working-copy $dir fi ;; jj-search*) if [ -z "$dir" ]; then exec $ripgrep "$FZF_QUERY" $(jj file list --ignore-working-copy) else jj=$(cd $dir && jj root --ignore-working-copy 2> /dev/null) exec $ripgrep "$FZF_QUERY" $(jj -R $jj file list --ignore-working-copy $dir) fi ;; esac exit fi if [ "$1" = preview ]; then if [ -n "$3" ]; then start=$(( $3 - $FZF_PREVIEW_LINES / 2 )) if [ $start -lt 1 ]; then start=1 fi end=$(( $start + $FZF_PREVIEW_LINES )) exec bat --style=numbers --color=always --highlight-line $3 --line-range $start:$end $2 else exec bat --style=numbers --color=always $2 fi fi reload="reload(sh $0 list || true)" no_search="rebind(change)+disable-search" search="unbind(change)+enable-search" if [ "$1" = key ]; then case "$FZF_KEY" in alt-a) prompt=${FZF_PROMPT#dir:} if [ $prompt = $FZF_PROMPT ]; then echo "change-prompt(dir:$FZF_PROMPT)+$search+$reload" else case "$cmd" in *files) infix="$search" ;; *) infix="$no_search" ;; esac echo "change-prompt($prompt)+$infix+$reload" fi ;; alt-d) dir=${FZF_HEADER_LABEL#?} case "$FZF_HEADER_LABEL" in .?*) echo "change-header(path: $dir)+change-header-label(:$dir)+$reload" ;; *) echo "change-header()+change-header-label(.$dir)+$reload" ;; esac ;; alt-f) case "$cmd" in files) prompt="find-files$hidden" ;; *files|search) prompt="files$hidden" ;; *search) prompt="${cmd%-*}-files$hidden" ;; esac echo "change-prompt($prompt> )+$search+$reload" ;; alt-g) case "$cmd" in *files) prompt="git-files$hidden" echo "change-prompt($prompt> )+$search+$reload" ;; *search) prompt="git-search$hidden" echo "change-prompt($prompt> )+$no_search+$reload" ;; esac ;; alt-h) if [ -z "$hidden" ]; then prompt="$cmd+hidden" else prompt="$cmd" fi echo "change-prompt($prompt> )+$reload" ;; alt-j) case "$cmd" in *files) prompt="jj-files$hidden" echo "change-prompt($prompt> )+$search+$reload" ;; *search) prompt="jj-search$hidden" echo "change-prompt($prompt> )+$no_search+$reload" ;; esac ;; alt-s) case "$cmd" in *search|files) prompt="search$hidden" ;; *files) prompt="${cmd%-*}-search$hidden" ;; esac echo "change-prompt($prompt> )+$no_search+$reload" ;; esac exit fi if [ "$1" = chdir ]; then dir="$2" prompt=${FZF_PROMPT#dir:} case "$cmd" in *files) infix="$search" ;; *) infix="$no_search" ;; esac echo "change-header(path: $dir)+change-header-label(:$dir)+change-prompt($prompt)+$infix+$reload" exit fi if [ -n "$2" ]; then label=".$2" else label=".." fi case ${1%+hidden} in auto-files) git=$(git rev-parse --show-toplevel 2> /dev/null) jj=$(jj root --ignore-working-copy 2> /dev/null) if [ -n "$jj" ] && [ "${git#$jj}" = "$git" -o "$git" = "$jj" ]; then cmd="jj-files$hidden" elif [ -n "$git" ] && [ "${jj#$git}" = "$jj" ]; then cmd="git-files$hidden" else cmd="files" fi action="$search" prompt="$cmd> " ;; auto-search) git=$(git rev-parse --show-toplevel 2> /dev/null) jj=$(jj root --ignore-working-copy 2> /dev/null) if [ -n "$jj" ] && [ "${git#$jj}" = "$git" -o "$git" = "$jj" ]; then cmd="jj-search$hidden" elif [ -n "$git" ] && [ "${jj#$git}" = "$jj" ]; then cmd="git-search$hidden" else cmd="search" fi action="$no_search" prompt="$cmd> " ;; files|git-files|jj-files|find-files) cmd="$1" action="$search" prompt="$1> " ;; search|git-search|jj-search) cmd="$1" action="$no_search" prompt="$1> " ;; *) cmd="files" action="$search" prompt="files> " ;; esac key="transform(sh $0 key)" HELP='Keys: alt-? help alt-a select alternative directory alt-d toggle alternative directory alt-f switch to files (twice for plain files) alt-g switch to git alt-j switch to jj alt-h toggle hidden alt-p toggle preview (also to turn off help) alt-s switch to search (twice for plain search) alt-u toggle preview window position (right or up) ' accept=" if [ \${FZF_PROMPT#dir:} = \$FZF_PROMPT ]; then echo accept else sh $0 chdir {1} fi " exec fzf --query "$3" \ --prompt "$prompt" \ --header-label "$label" \ --multi \ --ansi \ --scheme path \ --delimiter : \ --ghost ' (Use alt-? for help)' \ --bind "enter:transform($accept)" \ --bind "change:$reload" \ --bind "start:$reload+$action" \ --bind "alt-a:$key" \ --bind "alt-d:$key" \ --bind "alt-f:$key" \ --bind "alt-g:$key" \ --bind "alt-j:$key" \ --bind "alt-h:$key" \ --bind "alt-s:$key" \ --bind "alt-p:change-preview(sh $0 preview {1} {2})+toggle-preview" \ --bind "alt-u:change-preview-window(up|right)" \ --bind "alt-?:change-preview(echo '$HELP')+show-preview" \ --bind "alt-enter:unbind(change,alt-enter)+enable-search+clear-query"