-
Notifications
You must be signed in to change notification settings - Fork 129
Preview
You can make full use of fzf's --preview option when using fzf-tab .
If you don't know what it is, please read junegunn/fzf#preview-window first.
An example:
zstyle ':fzf-tab:complete:cd:*' fzf-preview 'eza -1 --color=always $realpath' # remember to use single quote here!!!
fzf-tab defines some variables for better previewing.
This is the string fzf shows to you.
Example: --accessed use the accessed timestamp field, README.md
This is the real string to be insert into your commandline.
For example, if the $desc is --accessed use the accessed timestamp field, the $word is --accessed.
This is the description of the group which the $word belongs to.
For example, --accessed belongs to group named [option], and README.md belongs to [filename].
README.md belongs to [filename] to completing eza, but belongs to [files] when completing ls.
NOTE: To use this variable, please make sure you have set zstyle ':completion:*:descriptions' format '[%d]'.
If you are completing a path and want to access this path when previewing, then you should use $realpath.
For example, if you are completing directories in /usr/, $word will be something like bin, lib,
but $realpath will be /usr/bin, /usr/lib.
Any array of your current input.
Note: if you don't want to spend time to write these configs by yourself, you can try this zsh plugin.
Feel free to contribute your preview~

# give a preview of commandline arguments when completing `kill`
zstyle ':completion:*:*:*:*:processes' command "ps -u $USER -o pid,user,comm -w -w"
zstyle ':fzf-tab:complete:(kill|ps):argument-rest' fzf-preview \
'[[ $group == "[process ID]" ]] && ps --pid=$word -o cmd --no-headers -w -w'
zstyle ':fzf-tab:complete:(kill|ps):argument-rest' fzf-flags --preview-window=down:3:wrap
zstyle ':fzf-tab:complete:systemctl-*:*' fzf-preview 'SYSTEMD_COLORS=1 systemctl status $word'- directory:
- plain text:
- image:
and more! (xls, xlsx, tar.gz, etc)
zstyle ':fzf-tab:complete:*:*' fzf-preview 'less ${(Q)realpath}'
export LESSOPEN='|~/.lessfilter %s'#! /usr/bin/env sh
# this is a example of .lessfilter, you can change it
mime=$(file -bL --mime-type "$1")
category=${mime%%/*}
kind=${mime##*/}
if [ -d "$1" ]; then
eza --git -hl --color=always --icons "$1"
elif [ "$category" = image ]; then
chafa "$1"
exiftool "$1"
elif [ "$kind" = vnd.openxmlformats-officedocument.spreadsheetml.sheet ] || \
[ "$kind" = vnd.ms-excel ]; then
in2csv "$1" | xsv table | bat -ltsv --color=always
elif [ "$category" = text ]; then
bat --color=always "$1"
else
lesspipe.sh "$1" | bat --color=always
fi
# lesspipe.sh don't use eza, bat and chafa, it use ls and exiftool. so we create a lessfilter.NOTE: To disable or override preview for command options and subcommands, use
zstyle ':fzf-tab:complete:*:options' fzf-preview
zstyle ':fzf-tab:complete:*:argument-1' fzf-preview
zstyle ':fzf-tab:complete:(-command-|-parameter-|-brace-parameter-|export|unset|expand):*' \
fzf-preview 'echo ${(P)word}'
# it is an example. you can change it
zstyle ':fzf-tab:complete:git-(add|diff|restore):*' fzf-preview \
'git diff $word | delta'
zstyle ':fzf-tab:complete:git-log:*' fzf-preview \
'git log --color=always $word'
zstyle ':fzf-tab:complete:git-help:*' fzf-preview \
'git help $word | bat -plman --color=always'
zstyle ':fzf-tab:complete:git-show:*' fzf-preview \
'case "$group" in
"commit tag") git show --color=always $word ;;
*) git show --color=always $word | delta ;;
esac'
zstyle ':fzf-tab:complete:git-checkout:*' fzf-preview \
'case "$group" in
"modified file") git diff $word | delta ;;
"recent commit object name") git show --color=always $word | delta ;;
*) git log --color=always $word ;;
esac'Note: This doesn't work if you are using Homebrew's completion for git.
zstyle ':fzf-tab:complete:brew-(install|uninstall|search|info):*-argument-rest' fzf-preview 'HOMEBREW_COLOR=1 brew info $word'
zstyle ':fzf-tab:complete:tldr:argument-1' fzf-preview 'tldr --color always $word'
zstyle ':fzf-tab:complete:-command-:*' fzf-preview \
'(out=$(tldr --color always "$word") 2>/dev/null && echo $out) || (out=$(MANWIDTH=$FZF_PREVIEW_COLUMNS man "$word") 2>/dev/null && echo $out) || (out=$(which "$word") && echo $out) || echo "${(P)word}"'

Requirements:
In section show-file-contents, we have known how to preview a file (directory, other file...)
and we should install https://github.com/petronny/pinyin-completion.
when we press Ctrlx+h, we will see
❯ cd Desktop/dj
tags in context :completion::complete:cd::
local-directories (_cd)
tags in context :completion::user-expand:::
all-expansions expansions original (_user_expand _ftb__main_complete -ftb-complete)
just change :completion::user-expand:* to :fzf-tab:user-expand:*.
zstyle ':fzf-tab:user-expand:*' fzf-preview 'less ${(Q)word}'the (Q) unquote the word. if you don't do so, fzf-tab will execute less '大家\ 0'not less '大家 0'.
if you don't want to use any alias or you want to use the full path,
you will find the fzf-tab completion tag for man cannot work for \man and /usr/bin/man.
the method is change your zshrc to
# this is an example
zstyle ':fzf-tab:complete:(\\|)run-help:*' fzf-preview 'run-help $word'
zstyle ':fzf-tab:complete:(\\|*/|)man:*' fzf-preview 'man $word'
now, they can work, because (\\|*/|)man can match them.
Putting it all together
Uses kitty, eza, bat, hexyl and pdftoppm (from poppler).zstyle ':fzf-tab:complete:*:*' fzf-preview '
# colors (use \033 instead of \e for awk)
BLUE="\033[34m"
OCHRE="\033[33m"
ITALIC="\033[3m"
RESET="\033[0m"
# if $realpath is set, complete a path
[[ -n $realpath ]] && group="[file]"
case $group in
"[file]")
case $(file --mime-type --brief $realpath) in
# example using the kitty terminal emulator to render images
"inode/directory") eza -1al --git --group-directories-first --color=always --icons $realpath ;;
"application/pdf") pdftoppm -singlefile -jpeg -jpegopt quality=50 $realpath |
kitten icat --clear --transfer-mode=stream --unicode-placeholder \
--place=${FZF_PREVIEW_COLUMNS}x${FZF_PREVIEW_LINES}@0x0 ;;
*image*) kitty icat --clear --transfer-mode=stream --unicode-placeholder --stdin=no \
--place=${FZF_PREVIEW_COLUMNS}x${FZF_PREVIEW_LINES}@0x0 $realpath ;;
*text*) bat --plain --color=always $realpath ;;
*) hexyl --border=none --terminal-width=$FZF_PREVIEW_COLUMNS $realpath ;;
esac
;;
"[parameter]")
case $word in
path|PATH)
echo -e ${PATH//:/\\n}
;;
fpath|FPATH)
echo ${(F)fpath}
;;
*)
printenv $word
;;
esac
;;
"[external command]"|"[executable file]")
(MANWIDTH=$FZF_PREVIEW_COLUMNS man $word 2>/dev/null | bat -plman --color=always) || \
(out=which $word && echo $out) || \
echo ${(P)word}
;;
"[shell function]")
autoload +X $word
which $word | bat --plain --language=zsh
;;
"[alias]"|"[regular alias]")
source .zshrc # or wherever your aliases are defined
if [[ $aliases[$word] ]]; then
out="$aliases[$word]"
else
# Support for https://github.com/olets/zsh-abbr
# fpath+=("$HOME/.local/share/zsh/antidote//github.com/olets/zsh-abbr")
# source "/path/to/plugin/olets/zsh-abbr/zsh-abbr.plugin.zsh"
# out=$(abbr expand $word)
fi
if [[ -n $out ]]; then
echo -en "$BLUE$word $OCHRE$ITALIC-> $RESET"
echo $out | bat --plain --language=zsh
fi
;;
"[process ID]")
ps --pid=$word \
-o pid= -o ppid= -o user= -o %cpu= -o %mem= -o etime= -o stat= -o cmd= -ww |
awk -v OCHRE="$OCHRE" -v BLUE="$BLUE" -v RESET="$RESET" "{
pid=\$1; ppid=\$2; user=\$3; cpu=\$4; mem=\$5; time=\$6; state=\$7
\$1=\$2=\$3=\$4=\$5=\$6=\$7=\"\"
sub(/^ +/, \"\")
cmd=\$0
printf \"%sCmd%s: %s%s%s\n\", OCHRE, RESET, BLUE, cmd, RESET
printf \"%sCPU%s: %s%s%s\n\", OCHRE, RESET, BLUE, cpu, RESET
printf \"%sMEM%s: %s%s%s\n\", OCHRE, RESET, BLUE, mem, RESET
printf \"%sTime%s: %s%s%s\n\", OCHRE, RESET, BLUE, time, RESET
printf \"%sState%s: %s%s%s\n\", OCHRE, RESET, BLUE, state, RESET
printf \"%sPID%s: %s%s%s\n\", OCHRE, RESET, BLUE, pid, RESET
printf \"%sPPID%s: %s%s%s\n\", OCHRE, RESET, BLUE, ppid, RESET
printf \"%sUser%s: %s%s%s\n\", OCHRE, RESET, BLUE, user, RESET
}"
;;
*"unit]")
SYSTEMD_COLORS=1 systemctl status $word
;;
*)
echo ${group:1:-1}
;;
esac'