-
I'm basically trying to implement a relatively simple file/folder explorer using FZF. Currently, I have this split across two commands: one for files and one for directories. Here's the code for the directories explorer: #!/bin/zsh
local -r dir=${1}
find_dir() {
if [ ! -z ${dir} ]; then
fd -L -t d . "$dir" | awk '{print $1}'
else
fd -L -t d | awk '{print $1}'
fi
}
local selection=$(find_dir | fzf --multi --height=80% --border=rounded \
--preview="tree -C {}" --preview-window="45%,border-rounded" \
--prompt="Dirs > " \
--bind="del:execute(rm -ri {+})" \
--bind="?:toggle-preview" \
--bind="ctrl-a:select-all" \
--bind="ctrl-x:deselect-all" \
--header "
CTRL-a to select all | CTRL-x to deselect all
ENTER to switch | DEL to delete
CTRL-q to exit
? to toggle preview
"
)
if [ -z "$selection" ]; then
return
fi
cd "$selection" || exit As you can see, the main point of this is to allow me to do:
The file explorer is effectively the same, with the only difference being passing #!/bin/zsh
local -r dir=${1}
find_file() {
if [ ! -z ${dir} ]; then
fd -I -t f . "$dir" | awk '{print $1}'
else
fd -I -t f | awk '{print $1}'
fi
}
find_dir() {
if [ ! -z ${dir} ]; then
fd -I -L -t d . "$dir" | awk '{print $1}'
else
fd -I -L -t d | awk '{print $1}'
fi
}
export FIND_FILE=$(functions find_file)
export FIND_DIR=$(functions find_dir)
find_dir | fzf --multi --height=80% --border=rounded \
--preview="tree -C {}" --preview-window="45%,border-rounded" \
--prompt="Dirs > " \
--bind="del:execute(rm -ri {+})" \
--bind="?:toggle-preview" \
--bind="ctrl-d:change-prompt(Dirs > )" \
--bind="ctrl-d:+reload(eval $FIND_DIR && find_dir)" \
--bind="ctrl-d:+change-preview(tree -C {})" \
--bind="ctrl-d:+refresh-preview" \
--bind="ctrl-f:change-prompt(Files > )" \
--bind="ctrl-f:+reload(eval $FIND_FILE && find_file)" \
--bind="ctrl-f:+change-preview(bat --color=always {})" \
--bind="ctrl-f:+refresh-preview" \
--bind="ctrl-a:select-all" \
--bind="ctrl-x:deselect-all" \
--header "
CTRL-D to display directories | CTRL-F to display files
CTRL-A to select all | CTRL-X to deselect all
ENTER to edit | DEL to delete
? to toggle preview
"
if [ -z "$selection" ]; then
exit
fi
if [ -d "$selection" ]; then
cd "$selection" || exit
else
eval $EDITOR $(echo $selection | sed -e "s/\x00/ /g")
fi This works when I first invoke the script, but if I press |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 1 reply
-
What is your |
Beta Was this translation helpful? Give feedback.
-
I like your idea of assigning a variable with the function definition as a workaround for the missing An alternative idea would be to take advantage of an anonymous zsh function by removing the preceding name and allowing the function to execute immediately. # ✅ zsh - double quotes
run_seq() { seq 3; }; RUN_SEQ=$(typeset -f run_seq); fzf --bind "start:become:${RUN_SEQ#* }" --with-shell 'zsh -c'
# ✅ zsh - single quotes without 'eval', parse the string again and execute
run_seq() { seq 3; }; export RUN_SEQ=$(typeset -f run_seq); fzf --bind 'start:become:. <(<<<${RUN_SEQ#* })' --with-shell 'zsh -c' |
Beta Was this translation helpful? Give feedback.
-
Word splitting in zsh for quoted and unquoted variables is different from bash/sh. That might have been the issue here. |
Beta Was this translation helpful? Give feedback.
What is your
$SHELL
value? Your script works for me if I add--with-shell='zsh -c'
to ensurezsh
is used to start commands.(
export SHELL=zsh
also has the same effect.)