Files
dotfiles/vis/.config/vis/fzf.sh

292 lines
5.8 KiB
Bash
Executable File

#!/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"