mirror of
https://github.com/jarun/nnn.git
synced 2024-11-28 13:51:31 +00:00
05990dc9e5
This makes it so that when the paged text is fewer lines than the preview pane, it is placed at the top instead of at the bottom
492 lines
19 KiB
Bash
Executable file
492 lines
19 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
|
|
# Description: Terminal based file previewer
|
|
#
|
|
# Note: This plugin needs a "NNN_FIFO" to work. See man.
|
|
#
|
|
# Dependencies:
|
|
# - Supports 6 independent methods to preview with:
|
|
# - tmux (>=3.0), or
|
|
# - kitty with allow_remote_control and listen_on set in kitty.conf, or
|
|
# - wezterm (https://wezfurlong.org/wezterm), or
|
|
# - QuickLook on WSL (https://github.com/QL-Win/QuickLook), or
|
|
# - Windows Terminal (https://github.com/Microsoft/Terminal | https://aka.ms/terminal) with WSL, or
|
|
# - $NNN_TERMINAL set to a terminal (it's xterm by default).
|
|
# - less or $NNN_PAGER
|
|
# - tree or exa or (GNU) ls
|
|
# - mediainfo or file
|
|
# - mktemp
|
|
# - unzip
|
|
# - tar
|
|
# - man
|
|
# - optional: bsdtar or atool for additional archive preview
|
|
# - optional: bat for code syntax highlighting
|
|
# - optional: ueberzug, kitty terminal, wezterm terminal, viu, catimg or chafa for images
|
|
# - optional: convert(ImageMagick) for playing gif preview (required for kitty image previews)
|
|
# - optional: ffmpegthumbnailer for video thumbnails (https://github.com/dirkvdb/ffmpegthumbnailer)
|
|
# - optional: ffmpeg for audio thumbnails
|
|
# - optional: libreoffce for opendocument/officedocument preview
|
|
# - optional: pdftoppm(poppler) for pdf thumbnails
|
|
# - optional: gnome-epub-thumbnailer for epub thumbnails (https://gitlab.gnome.org/GNOME/gnome-epub-thumbnailer)
|
|
# - optional: fontpreview for font preview (https://github.com/sdushantha/fontpreview)
|
|
# - optional: djvulibre for djvu
|
|
# - optional: glow or lowdown for markdown
|
|
# - optional: w3m or lynx or elinks for html
|
|
# - optional: set/export NNN_ICONLOOKUP as 1 to enable file icons in front of directory previews with .iconlookup
|
|
# Icons and colors are configurable in .iconlookup
|
|
# - optional: scope.sh file viewer from ranger.
|
|
# 1. drop scope.sh executable in $PATH
|
|
# 2. set/export $NNN_SCOPE as 1
|
|
# - optional: pistol file viewer (https://github.com/doronbehar/pistol).
|
|
# 1. install pistol
|
|
# 2. set/export $NNN_PISTOL as 1
|
|
#
|
|
# Usage:
|
|
# You need to set a NNN_FIFO path and a key for the plugin with NNN_PLUG,
|
|
# then start `nnn`:
|
|
#
|
|
# $ nnn -a
|
|
#
|
|
# or
|
|
#
|
|
# $ NNN_FIFO=/tmp/nnn.fifo nnn
|
|
#
|
|
# Then launch the `preview-tui` plugin in `nnn`.
|
|
#
|
|
# If you provide the same NNN_FIFO to all nnn instances, there will be a
|
|
# single common preview window. If you provide different FIFO path (e.g.
|
|
# with -a), they will be independent.
|
|
#
|
|
# The previews will be shown in a tmux split. If that isn't possible, it
|
|
# will try to use a kitty terminal split. And as a final fallback, a
|
|
# different terminal window will be used ($NNN_TERMINAL).
|
|
#
|
|
# Kitty users need something similar to the following in their kitty.conf:
|
|
# - `allow_remote_control yes`
|
|
# - `listen_on unix:$TMPDIR/kitty`
|
|
# - `enabled_layouts splits` (optional)
|
|
# With ImageMagick installed, this terminal can use the icat kitten to display images.
|
|
# Refer to kitty documentation for further details.
|
|
#
|
|
# Wezterm should work out of the box. If `NNN_PREVIEWIMGPROG` is not specified it will use
|
|
# built in iTerm2 image protocol.
|
|
#
|
|
# Note that GNU ls is used for its `--group-directories-first` flag.
|
|
# On MacOS this may be installed with `brew install coreutils`, or the flag can be removed.
|
|
# iTerm2 users are recommended to use viu to view images without getting pixelated.
|
|
#
|
|
# Windows Terminal users can set "Profile termination behavior" under "Profile > Advanced" settings
|
|
# to automatically close pane on quit when exit code is 0.
|
|
#
|
|
# When specifying a different terminal, additional arguments are supported. In particular, you can
|
|
# append a specific title to the terminal and set it to "nofocus" in your WM config.
|
|
# E.g for alacritty and i3, you can set $NNN_TERMINAL to 'alacritty --title preview-tui' and add
|
|
# 'no_focus [title="preview-tui"]' to your i3 config file.
|
|
#
|
|
# Shell: Bash (for environment manipulation through arrays)
|
|
# Authors: Todd Yamakawa, Léo Villeveygoux, @Recidiviste, Mario Ortiz Manero, Luuk van Baal, @WanderLanz
|
|
|
|
NNN_SPLIT=${NNN_SPLIT:-} # Set permanent split direction
|
|
NNN_TERMINAL=${NNN_TERMINAL:-} # Set external terminal to be used
|
|
NNN_SPLITSIZE=${NNN_SPLITSIZE:-50} # Set previewer split size percentage
|
|
TMPDIR=${TMPDIR:-/tmp}
|
|
NNN_PARENT=${NNN_FIFO#*.}
|
|
[ "$NNN_PARENT" -eq "$NNN_PARENT" ] 2>/dev/null || NNN_PARENT="" # Make empty if non-numeric
|
|
ENVVARS=(
|
|
"PWD=$PWD"
|
|
"PATH=$PATH"
|
|
"NNN_FIFO=$NNN_FIFO"
|
|
"NNN_SCOPE=${NNN_SCOPE:-0}"
|
|
"NNN_PISTOL=${NNN_PISTOL:-0}"
|
|
"NNN_ICONLOOKUP=${NNN_ICONLOOKUP:-0}"
|
|
"NNN_PAGER=${NNN_PAGER:-less -P?n -R -C}"
|
|
"NNN_BATTHEME=${NNN_BATTHEME:-ansi}"
|
|
"NNN_BATSTYLE=${NNN_BATSTYLE:-numbers}"
|
|
"NNN_PREVIEWWIDTH=${NNN_PREVIEWWIDTH:-1920}"
|
|
"NNN_PREVIEWHEIGHT=${NNN_PREVIEWHEIGHT:-1080}"
|
|
"NNN_PREVIEWDIR=${NNN_PREVIEWDIR:-$TMPDIR/nnn/previews}"
|
|
"NNN_PREVIEWIMGPROG=${NNN_PREVIEWIMGPROG:-}"
|
|
"FIFOPID=$TMPDIR/nnn-preview-tui-fifopid.$NNN_PARENT"
|
|
"FIFOPATH=$TMPDIR/nnn-preview-tui-fifo.$NNN_PARENT"
|
|
"PREVIEWPID=$TMPDIR/nnn-preview-tui-previewpid.$NNN_PARENT"
|
|
"CURSEL=$TMPDIR/nnn-preview-tui-selection.$NNN_PARENT"
|
|
"FIFO_UEBERZUG=$TMPDIR/nnn-preview-tui-ueberzug-fifo.$NNN_PARENT"
|
|
"POSOFFSET=$TMPDIR/nnn-preview-tui-posoffset"
|
|
)
|
|
|
|
trap '' PIPE
|
|
exists() { type "$1" >/dev/null 2>&1 ;}
|
|
pkill() { command pkill "$@" >/dev/null 2>&1 ;}
|
|
prompt() { clear; printf "%b" "$@"; cfg=$(stty -g); stty raw -echo; head -c 1; stty "$cfg" ;}
|
|
pidkill() {
|
|
if [ -f "$1" ]; then
|
|
PID="$(cat "$1" 2>/dev/null)" || return 1
|
|
kill "$PID" >/dev/null 2>&1
|
|
RET=$?
|
|
wait "$PID" 2>/dev/null
|
|
return $RET
|
|
fi
|
|
return 1
|
|
}
|
|
|
|
start_preview() {
|
|
if [ -e "${TMUX%%,*}" ] && tmux -V | grep -q '[ -][3456789]\.'; then
|
|
NNN_TERMINAL=tmux
|
|
elif [ -n "$KITTY_LISTEN_ON" ]; then
|
|
NNN_TERMINAL=kitty
|
|
elif [ -n "$WEZTERM_PANE" ]; then
|
|
NNN_TERMINAL=wezterm
|
|
elif [ -z "$NNN_TERMINAL" ] && [ "$TERM_PROGRAM" = "iTerm.app" ]; then
|
|
NNN_TERMINAL=iterm
|
|
elif [ -n "$WT_SESSION" ]; then
|
|
NNN_TERMINAL=winterm
|
|
else
|
|
NNN_TERMINAL="${NNN_TERMINAL:-xterm}"
|
|
fi
|
|
|
|
if [ -z "$NNN_SPLIT" ] && [ $(($(tput lines) * 2)) -gt "$(tput cols)" ]; then
|
|
NNN_SPLIT='h'
|
|
elif [ "$NNN_SPLIT" != 'h' ]; then
|
|
NNN_SPLIT='v'
|
|
fi
|
|
|
|
ENVVARS+=("NNN_TERMINAL=$NNN_TERMINAL" "NNN_SPLIT=$NNN_SPLIT" "QLPATH=$2" "PREVIEW_MODE=1")
|
|
case "$NNN_TERMINAL" in
|
|
iterm|winterm) # need run in separate shell command: escape
|
|
ENVVARS=("${ENVVARS[@]/#/\\\"}")
|
|
ENVVARS=("${ENVVARS[@]/%/\\\"}")
|
|
command="$SHELL -c 'env ${ENVVARS[*]} \\\"$0\\\" \\\"$1\\\"'" ;;
|
|
esac
|
|
|
|
case "$NNN_TERMINAL" in
|
|
tmux) # tmux splits are inverted
|
|
ENVVARS=("${ENVVARS[@]/#/-e}")
|
|
if [ "$NNN_SPLIT" = "v" ]; then split="h"; else split="v"; fi
|
|
tmux split-window "${ENVVARS[@]}" -d"$split" -p"$NNN_SPLITSIZE" "$0" "$1" ;;
|
|
kitty) # Setting the layout for the new window. It will be restored after the script ends.
|
|
ENVVARS=("${ENVVARS[@]/#/--env=}")
|
|
kitty @ goto-layout splits
|
|
# Trying to use kitty's integrated window management as the split window.
|
|
kitty @ launch --no-response --title "preview-tui" --keep-focus \
|
|
--cwd "$PWD" "${ENVVARS[@]}" --location "${NNN_SPLIT}split" "$0" "$1" ;;
|
|
wezterm)
|
|
export "${ENVVARS[@]}"
|
|
if [ "$NNN_SPLIT" = "v" ]; then split="--horizontal"; else split="--bottom"; fi
|
|
wezterm cli split-pane --cwd "$PWD" $split --percent "$NNN_SPLITSIZE" "$0" "$1" >/dev/null
|
|
wezterm cli activate-pane-direction Prev ;;
|
|
iterm)
|
|
if [ "$NNN_SPLIT" = "h" ]; then split="horizontally"; else split="vertically"; fi
|
|
osascript <<-EOF
|
|
tell application "iTerm"
|
|
tell current session of current window
|
|
split $split with default profile command "$command"
|
|
end tell
|
|
end tell
|
|
EOF
|
|
;;
|
|
winterm)
|
|
if [ "$NNN_SPLIT" = "h" ]; then split="H"; else split="V"; fi
|
|
wt -w 0 sp -$split -s"0.$NNN_SPLITSIZE" "$command" \; -w 0 mf previous 2>/dev/null ;;
|
|
*) if [ -n "$2" ]; then
|
|
env "${ENVVARS[@]}" QUICKLOOK=1 "$0" "$1" &
|
|
else
|
|
# shellcheck disable=SC2086 # (allow arguments)
|
|
env "${ENVVARS[@]}" $NNN_TERMINAL -e "$0" "$1" &
|
|
fi ;;
|
|
esac
|
|
}
|
|
|
|
toggle_preview() {
|
|
export "${ENVVARS[@]}"
|
|
if exists QuickLook.exe; then
|
|
QLPATH="QuickLook.exe"
|
|
elif exists Bridge.exe; then
|
|
QLPATH="Bridge.exe"
|
|
fi
|
|
if pidkill "$FIFOPID"; then
|
|
[ -p "$NNN_PPIPE" ] && printf "0" > "$NNN_PPIPE"
|
|
pidkill "$PREVIEWPID"
|
|
pkill -f "tail --follow $FIFO_UEBERZUG"
|
|
if [ -n "$QLPATH" ] && stat "$1"; then
|
|
f="$(wslpath -w "$1")" && "$QLPATH" "$f" &
|
|
fi
|
|
else
|
|
[ -p "$NNN_PPIPE" ] && printf "1" > "$NNN_PPIPE"
|
|
start_preview "$1" "$QLPATH"
|
|
fi
|
|
}
|
|
|
|
fifo_pager() {
|
|
cmd="$1"
|
|
shift
|
|
|
|
# We use a FIFO to access $NNN_PAGER PID in jobs control
|
|
mkfifo "$FIFOPATH" || return
|
|
|
|
$NNN_PAGER < "$FIFOPATH" &
|
|
printf "%s" "$!" > "$PREVIEWPID"
|
|
|
|
(
|
|
exec > "$FIFOPATH"
|
|
if [ "$cmd" = "pager" ]; then
|
|
if exists bat; then
|
|
bat --terminal-width="$cols" --decorations=always --color=always \
|
|
--paging=never --style="$NNN_BATSTYLE" --theme="$NNN_BATTHEME" "$@" &
|
|
else
|
|
$NNN_PAGER "$@" &
|
|
fi
|
|
else
|
|
"$cmd" "$@" &
|
|
fi
|
|
)
|
|
|
|
rm "$FIFOPATH"
|
|
}
|
|
|
|
# Binary file: show file info inside the pager
|
|
print_bin_info() {
|
|
printf -- "-------- \033[1;31mBinary file\033[0m --------\n"
|
|
if exists mediainfo; then
|
|
mediainfo "$1"
|
|
else
|
|
file -b "$1"
|
|
fi
|
|
}
|
|
|
|
handle_mime() {
|
|
case "$2" in
|
|
image/jpeg) image_preview "$cols" "$lines" "$1" ;;
|
|
image/gif) generate_preview "$cols" "$lines" "$1" "gif" ;;
|
|
image/vnd.djvu) generate_preview "$cols" "$lines" "$1" "djvu" ;;
|
|
image/*) generate_preview "$cols" "$lines" "$1" "image" ;;
|
|
video/*) generate_preview "$cols" "$lines" "$1" "video" ;;
|
|
audio/*) generate_preview "$cols" "$lines" "$1" "audio" ;;
|
|
application/font*|application/*opentype|font/*) generate_preview "$cols" "$lines" "$1" "font" ;;
|
|
*/*office*|*/*document*|*/*msword|*/*ms-excel) generate_preview "$cols" "$lines" "$1" "office" ;;
|
|
application/zip) fifo_pager unzip -l "$1" ;;
|
|
text/troff)
|
|
if exists man; then
|
|
fifo_pager man -Pcat -l "$1"
|
|
else
|
|
fifo_pager pager "$1"
|
|
fi ;;
|
|
*) handle_ext "$1" "$3" "$4" ;;
|
|
esac
|
|
}
|
|
|
|
handle_ext() {
|
|
case "$2" in
|
|
epub) generate_preview "$cols" "$lines" "$1" "epub" ;;
|
|
pdf) generate_preview "$cols" "$lines" "$1" "pdf" ;;
|
|
gz|bz2) fifo_pager tar -tvf "$1" ;;
|
|
md) if exists glow; then
|
|
fifo_pager glow -s dark "$1"
|
|
elif exists lowdown; then
|
|
fifo_pager lowdown -Tterm "$1"
|
|
else
|
|
fifo_pager pager "$1"
|
|
fi ;;
|
|
htm|html|xhtml)
|
|
if exists w3m; then
|
|
fifo_pager w3m "$1"
|
|
elif exists lynx; then
|
|
fifo_pager lynx "$1"
|
|
elif exists elinks; then
|
|
fifo_pager elinks "$1"
|
|
else
|
|
fifo_pager pager "$1"
|
|
fi ;;
|
|
7z|a|ace|alz|arc|arj|bz|cab|cpio|deb|jar|lha|lz|lzh|lzma|lzo\
|
|
|rar|rpm|rz|t7z|tar|tbz|tbz2|tgz|tlz|txz|tZ|tzo|war|xpi|xz|Z)
|
|
if exists atool; then
|
|
fifo_pager atool -l "$1"
|
|
elif exists bsdtar; then
|
|
fifo_pager bsdtar -tvf "$1"
|
|
fi ;;
|
|
*) if [ "$3" = "bin" ]; then
|
|
fifo_pager print_bin_info "$1"
|
|
else
|
|
fifo_pager pager "$1"
|
|
fi ;;
|
|
esac
|
|
}
|
|
|
|
preview_file() {
|
|
clear
|
|
# Trying to use pistol if it's available.
|
|
if [ "$NNN_PISTOL" -ne 0 ] && exists pistol; then
|
|
fifo_pager pistol "$1"
|
|
return
|
|
fi
|
|
|
|
# Trying to use scope.sh if it's available.
|
|
if [ "$NNN_SCOPE" -ne 0 ] && exists scope.sh; then
|
|
fifo_pager scope.sh "$1" "$cols" "$lines" "$(mktemp -d)" "True"
|
|
return
|
|
fi
|
|
|
|
# Use QuickLook if it's available.
|
|
if [ -n "$QUICKLOOK" ]; then
|
|
stat "$1" && f="$(wslpath -w "$1")" && "$QLPATH" "$f" &
|
|
return
|
|
fi
|
|
|
|
# Detecting the exact type of the file: the encoding, mime type, and extension in lowercase.
|
|
encoding="$(file -bL --mime-encoding -- "$1")"
|
|
mimetype="$(file -bL --mime-type -- "$1")"
|
|
ext="${1##*.}"
|
|
[ -n "$ext" ] && ext="$(printf "%s" "${ext}" | tr '[:upper:]' '[:lower:]')"
|
|
lines=$(tput lines)
|
|
cols=$(tput cols)
|
|
|
|
# Otherwise, falling back to the defaults.
|
|
if [ -d "$1" ]; then
|
|
cd "$1" || return
|
|
if [ "$NNN_ICONLOOKUP" -ne 0 ] && [ -f "$(dirname "$0")"/.iconlookup ]; then
|
|
[ "$NNN_SPLIT" = v ] && BSTR="\n"
|
|
# shellcheck disable=SC2012
|
|
ls -F --group-directories-first | head -n "$((lines - 3))" | "$(dirname "$0")"/.iconlookup -l "$cols" -B "$BSTR" -b " "
|
|
elif exists tree; then
|
|
fifo_pager tree --filelimit "$(find . -maxdepth 1 | wc -l)" -L 3 -C -F --dirsfirst --noreport
|
|
elif exists exa; then
|
|
exa -G --group-directories-first --colour=always
|
|
else
|
|
fifo_pager ls -F --group-directories-first --color=always
|
|
fi
|
|
cd ..
|
|
elif [ "${encoding#*)}" = "binary" ]; then
|
|
handle_mime "$1" "$mimetype" "$ext" "bin"
|
|
else
|
|
handle_mime "$1" "$mimetype" "$ext"
|
|
fi
|
|
}
|
|
|
|
generate_preview() {
|
|
if [ -n "$QLPATH" ] && stat "$3"; then
|
|
f="$(wslpath -w "$3")" && "$QLPATH" "$f" &
|
|
elif [ ! -f "$NNN_PREVIEWDIR/$3.jpg" ] || [ -n "$(find -L "$3" -newer "$NNN_PREVIEWDIR/$3.jpg")" ]; then
|
|
mkdir -p "$NNN_PREVIEWDIR/${3%/*}"
|
|
case $4 in
|
|
audio) ffmpeg -i "$3" -filter_complex "scale=iw*min(1\,min($NNN_PREVIEWWIDTH/iw\,ih)):-1" "$NNN_PREVIEWDIR/$3.jpg" -y ;;
|
|
epub) gnome-epub-thumbnailer "$3" "$NNN_PREVIEWDIR/$3.jpg" ;;
|
|
font) fontpreview -i "$3" -o "$NNN_PREVIEWDIR/$3.jpg" ;;
|
|
gif) if [ -p "$FIFO_UEBERZUG" ] && exists convert; then
|
|
frameprefix="$NNN_PREVIEWDIR/$3/${3##*/}"
|
|
if [ ! -d "$NNN_PREVIEWDIR/$3" ]; then
|
|
mkdir -p "$NNN_PREVIEWDIR/$3"
|
|
convert -coalesce -resize "$NNN_PREVIEWWIDTH"x"$NNN_PREVIEWHEIGHT"\> "$3" "$frameprefix.jpg" ||
|
|
MAGICK_TMPDIR="/tmp" convert -coalesce -resize "$NNN_PREVIEWWIDTH"x"$NNN_PREVIEWHEIGHT"\> "$3" "$frameprefix.jpg"
|
|
fi
|
|
frames=$(($(find "$NNN_PREVIEWDIR/$3" | wc -l) - 2))
|
|
[ $frames -lt 0 ] && return
|
|
while true; do
|
|
for i in $(seq 0 $frames); do
|
|
image_preview "$1" "$2" "$frameprefix-$i.jpg"
|
|
sleep 0.1
|
|
done
|
|
done &
|
|
printf "%s" "$!" > "$PREVIEWPID"
|
|
return
|
|
else
|
|
image_preview "$1" "$2" "$3"
|
|
return
|
|
fi ;;
|
|
image) if exists convert; then
|
|
convert "$3" -flatten -resize "$NNN_PREVIEWWIDTH"x"$NNN_PREVIEWHEIGHT"\> "$NNN_PREVIEWDIR/$3.jpg"
|
|
else
|
|
image_preview "$1" "$2" "$3" && return
|
|
fi ;;
|
|
office) libreoffice --convert-to jpg "$3" --outdir "$NNN_PREVIEWDIR/${3%/*}"
|
|
filename="$(printf "%s" "${3##*/}" | cut -d. -f1)"
|
|
mv "$NNN_PREVIEWDIR/${3%/*}/$filename.jpg" "$NNN_PREVIEWDIR/$3.jpg" ;;
|
|
pdf) pdftoppm -jpeg -f 1 -singlefile "$3" "$NNN_PREVIEWDIR/$3" ;;
|
|
djvu) ddjvu -format=ppm -page=1 "$3" "$NNN_PREVIEWDIR/$3.jpg" ;;
|
|
video) ffmpegthumbnailer -m -s0 -i "$3" -o "$NNN_PREVIEWDIR/$3.jpg" || rm "$NNN_PREVIEWDIR/$3.jpg" ;;
|
|
esac
|
|
fi
|
|
if [ -f "$NNN_PREVIEWDIR/$3.jpg" ]; then
|
|
image_preview "$1" "$2" "$NNN_PREVIEWDIR/$3.jpg"
|
|
else
|
|
fifo_pager print_bin_info "$3"
|
|
fi
|
|
} >/dev/null 2>&1
|
|
|
|
image_preview() {
|
|
clear
|
|
exec >/dev/tty
|
|
if [ "$NNN_TERMINAL" = "kitty" ] && [ -z "$NNN_PREVIEWIMGPROG" ]; then
|
|
kitty +kitten icat --silent --scale-up --place "$1"x"$2"@0x0 --transfer-mode=stream --stdin=no "$3" &
|
|
elif [ "$NNN_TERMINAL" = "wezterm" ] && [ -z "$NNN_PREVIEWIMGPROG" ]; then
|
|
wezterm imgcat "$3" &
|
|
elif exists ueberzug && { [ -z "$NNN_PREVIEWIMGPROG" ] || [ "$NNN_PREVIEWIMGPROG" = "ueberzug" ] ;}; then
|
|
ueberzug_layer "$1" "$2" "$3" && return
|
|
elif exists catimg && { [ -z "$NNN_PREVIEWIMGPROG" ] || [ "$NNN_PREVIEWIMGPROG" = "catimg" ] ;}; then
|
|
catimg "$3" &
|
|
elif exists viu && { [ -z "$NNN_PREVIEWIMGPROG" ] || [ "$NNN_PREVIEWIMGPROG" = "viu" ] ;}; then
|
|
viu -t "$3" &
|
|
elif exists chafa && { [ -z "$NNN_PREVIEWIMGPROG" ] || [ "$NNN_PREVIEWIMGPROG" = "chafa" ] ;}; then
|
|
chafa "$3" &
|
|
else
|
|
fifo_pager print_bin_info "$3" && return
|
|
fi
|
|
printf "%s" "$!" > "$PREVIEWPID"
|
|
}
|
|
|
|
ueberzug_layer() {
|
|
[ -f "$POSOFFSET" ] && read -r x y < "$POSOFFSET"
|
|
printf '{"action": "add", "identifier": "nnn_ueberzug", "x": %d, "y": %d, "width": "%d", "height": "%d", "scaler": "fit_contain", "path": "%s"}\n'\
|
|
"${x:-0}" "${y:-0}" "$1" "$2" "$3" > "$FIFO_UEBERZUG"
|
|
}
|
|
|
|
ueberzug_remove() {
|
|
printf '{"action": "remove", "identifier": "nnn_ueberzug"}\n' > "$FIFO_UEBERZUG"
|
|
}
|
|
|
|
winch_handler() {
|
|
clear
|
|
pidkill "$PREVIEWPID"
|
|
if [ -p "$FIFO_UEBERZUG" ]; then
|
|
pkill -f "tail --follow $FIFO_UEBERZUG"
|
|
tail --follow "$FIFO_UEBERZUG" | ueberzug layer --silent --parser json &
|
|
fi
|
|
preview_file "$(cat "$CURSEL")"
|
|
}
|
|
|
|
preview_fifo() {
|
|
while read -r selection; do
|
|
if [ -n "$selection" ]; then
|
|
pidkill "$PREVIEWPID"
|
|
[ -p "$FIFO_UEBERZUG" ] && ueberzug_remove
|
|
[ "$selection" = "close" ] && break
|
|
preview_file "$selection"
|
|
printf "%s" "$selection" > "$CURSEL"
|
|
fi
|
|
done < "$NNN_FIFO"
|
|
sleep 0.1 # make sure potential preview by winch_handler is killed
|
|
pkill -P "$$"
|
|
}
|
|
|
|
if [ "$PREVIEW_MODE" -eq 1 ] 2>/dev/null; then
|
|
if [ "$NNN_TERMINAL" != "kitty" ] && exists ueberzug; then
|
|
mkfifo "$FIFO_UEBERZUG"
|
|
tail --follow "$FIFO_UEBERZUG" | ueberzug layer --silent --parser json &
|
|
fi
|
|
|
|
preview_file "$PWD/$1"
|
|
preview_fifo &
|
|
printf "%s" "$!" > "$FIFOPID"
|
|
printf "%s" "$PWD/$1" > "$CURSEL"
|
|
trap 'winch_handler; wait' WINCH
|
|
trap 'rm "$PREVIEWPID" "$CURSEL" "$FIFO_UEBERZUG" "$FIFOPID" "$POSOFFSET" 2>/dev/null' INT HUP EXIT
|
|
wait "$!" 2>/dev/null
|
|
exit 0
|
|
else
|
|
if [ ! -r "$NNN_FIFO" ]; then
|
|
prompt "No FIFO available! (\$NNN_FIFO='$NNN_FIFO')\nPlease read Usage in '$0'."
|
|
elif [ "$KITTY_WINDOW_ID" ] && [ -z "$TMUX" ] && [ -z "$KITTY_LISTEN_ON" ]; then
|
|
prompt "\$KITTY_LISTEN_ON not set!\nPlease read Usage in '$0'."
|
|
else
|
|
toggle_preview "$1" &
|
|
fi
|
|
fi
|