1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
|
#!/usr/bin/env sh
# Description: File preview
#
# Dependencies:
# - Image preview: chafa
# - PDF preview: poppler-utils
# - Video thumbnail preview: ffmpegthumbnailertar
#
# Usage:
# When sff is running inside tmux:
# Enabling preview will split a new pane for display.
#
# When sff is running outside tmux:
# If SFF_PV_TERM is set, enabling preview will launch the terminal emulator
# specified by this variable as the previewer.
#
# If SFF_PV_TERM is not set, enabling preview will prompt you to enter
# the name of a terminal emulator to use temporarily as the previewer.
#
# The SFF_PV_TERM environment variable defines the default terminal emulator
# to be used as the previewer. You can set SFF_PV_TERM like this:
# $ export SFF_PV_TERM=xterm
#
# Note: This plugin cannot handle paths containing line breaks.
#
# Shell: POSIX compliant
#
# Author: Shi Yanling
sffpipe=$1
sffdir=${sffpipe%/*}
pvfifo="${sffpipe}.pv"
tmpdir=${TMPDIR:-/tmp}
[ ! -w "$tmpdir" ] && tmpdir=$sffdir
tmppvfile="${tmpdir}/sff-tmppv-$(id -u)"
preview_loop_tui()
{
mkfifo "$pvfifo" || exit 0
while IFS='' read -r _path; do
while _x=$(timeout 0.005 sh -c 'IFS="" read -r _x && printf "%s" "$_x"'); do
_path=$_x
done
clear
_dest=''
_mime=$(file -bL --mime-type "$_path")
case "$_mime" in
image/*) _dest=$_path
;;
application/pdf) _dest=$tmppvfile
pdftoppm -jpeg -f 1 -singlefile -scale-to 800 "$_path" "$_dest" >/dev/null 2>&1 \
&& _dest="${_dest}.jpg" || _dest=''
;;
video/*) _dest="${tmppvfile}.jpg"
ffmpegthumbnailer -m -s 0 -i "$_path" -o "$_dest" >/dev/null 2>&1 \
|| _dest=''
;;
*) _rows=$(tput lines); _cols=$(tput cols)
case "$_mime" in
text/*) { printf " --- %s ---\n" "$_mime"; head -n "$_rows" "$_path"; } | less -SX +gq
continue ;;
inode/directory) { printf " --- %s --- (%s files)\n" "$_mime" \
$(find "$_path"/ -mindepth 1 -maxdepth 1 ! -name . ! -name .. 2>/dev/null | wc -l); \
ls -1Ap "$_path"; } | head -n "$((_rows - 1))" | cut -c 1-"$_cols"
continue ;;
esac
;;
esac
if [ "$_dest" ]; then
chafa "$_dest"
tput civis
else
printf " --- %s ---" "$_mime"
fi
done <"$pvfifo"
}
check_fifo()
{
if [ -p "$pvfifo" ]; then
rm -f "$pvfifo"
printf "#q" >"$sffpipe"
exit 0
fi
}
wait_for_fifo()
{
_i=1
while [ ! -p "$pvfifo" ]; do
sleep 0.1
_i=$((_i + 1))
[ "$_i" -gt 20 ] && exit 0
done
}
case "$2" in
'tui') check_fifo
if [ "$TMUX" ]; then
[ $(($(tput lines) * 2)) -gt "$(tput cols)" ] && _layout='v' || _layout='h'
tmux split-window -d"$_layout" "$0" "$sffpipe" 'loop'
else
if [ -z "$SFF_PV_TERM" ]; then
printf "\nSFF_PV_TERM: not set\n"
printf "Terminal emulator for preview (empty to cancel): "; read -r _x
[ -z "$_x" ] && exit 0
SFF_PV_TERM=$_x
fi
case "$SFF_PV_TERM" in
'kitty'|'gnome-terminal') "$SFF_PV_TERM" -- "$0" "$sffpipe" 'loop' &
;;
'xfce4-terminal'|'terminator') "$SFF_PV_TERM" -e "\"$0\" \"$sffpipe\" loop" &
;;
*) "$SFF_PV_TERM" -e "$0" "$sffpipe" 'loop' &
;;
esac
fi
wait_for_fifo
printf "#p" >"$sffpipe"
;;
'gui') :
;;
'loop') tput civis
preview_loop_tui
;;
esac
|