-
Notifications
You must be signed in to change notification settings - Fork 330
Previews
With Überzug
If you wish to use Überzug for image previews, it is necessary to start both lf and Überzug in a wrapper script. Place a file with the following contents in your PATH:
#!/bin/sh
set -e
if [ -n "$DISPLAY" ]; then
export FIFO_UEBERZUG="${TMPDIR:-/tmp}/lf-ueberzug-$$"
cleanup() {
exec 3>&-
rm "$FIFO_UEBERZUG"
}
mkfifo "$FIFO_UEBERZUG"
ueberzug layer -s <"$FIFO_UEBERZUG" &
exec 3>"$FIFO_UEBERZUG"
trap cleanup EXIT
if ! [ -d "$HOME/.cache/lf" ]; then
mkdir -p "$HOME/.cache/lf"
fi
lf "$@" 3>&-
else
exec lf "$@"
fi
Make sure the file is executable. Using a preview cache in ~/.cache/lf
is optional. You may remove those lines if you don't need them, but take note that the previewer script must also be modified so as not to use an image cache as well.
Now, make a file named draw_img.sh
in the lf
configuration folder with the contents below:
#!/bin/sh
if [ -n "$FIFO_UEBERZUG" ]; then
path="$(printf '%s' "$1" | sed 's/\\/\\\\/g;s/"/\\"/g')"
printf '{"action": "add", "identifier": "preview", "x": %d, "y": %d, "width": %d, "height": %d, "scaler": "contain", "scaling_position_x": 0.5, "scaling_position_y": 0.5, "path": "%s"}\n' \
"$4" "$5" "$2" "$3" "$1" >"$FIFO_UEBERZUG"
fi
And also a file named clear_img.sh
in the lf
configuration folder:
#!/bin/sh
if [ -n "$FIFO_UEBERZUG" ]; then
printf '{"action": "remove", "identifier": "preview"}\n' >"$FIFO_UEBERZUG"
fi
It will now be necessary to modify your previewer script to call our draw_img.sh
script. Your previewer script may look like this:
#!/bin/sh
draw() {
~/.config/lf/draw_img.sh "$@"
exit 1
}
hash() {
printf '%s/.cache/lf/%s' "$HOME" \
"$(stat --printf '%n\0%i\0%F\0%s\0%W\0%Y' -- "$(readlink -f "$1")" | sha256sum | awk '{print $1}')"
}
cache() {
if [ -f "$1" ]; then
draw "$@"
fi
}
file="$1"
shift
if [ -n "$FIFO_UEBERZUG" ]; then
case "$(file -Lb --mime-type -- "$file")" in
image/*)
orientation="$(identify -format '%[EXIF:Orientation]\n' -- "$file")"
if [ -n "$orientation" ] && [ "$orientation" != 1 ]; then
cache="$(hash "$file").jpg"
cache "$cache" "$@"
convert -- "$file" -auto-orient "$cache"
draw "$cache" "$@"
else
draw "$file" "$@"
fi
;;
video/*)
cache="$(hash "$file").jpg"
cache "$cache" "$@"
ffmpegthumbnailer -i "$file" -o "$cache" -s 0
draw "$cache" "$@"
;;
esac
fi
file -Lb -- "$1" | fold -s -w "$width"
exit 0
Take note that the draw()
function exits with code 1. This is to signal lf
not to cache the result of the previewer script so that the next time the user selects the same file the previewer script will be executed again.
Now place the following lines in your lfrc:
set previewer ~/.config/lf/previewer.sh
set cleaner ~/.config/lf/clear_img.sh
More extensive examples are available at the following repositories:
- https://github.com/neeshy/lfimg
- https://github.com/slavistan/howto-lf-image-previews
- https://github.com/slavistan/lf-gadgets/tree/master/lf-ueberzug
- https://github.com/OliverLew/dotfiles/tree/master/lf
- https://github.com/cirala/lfimg
stpv and ctpv are standalone programs for adding previews. Read more on how to integrate them into lf.
Make a file named draw_img.sh
in the lf
configuration folder with the contents below.
#!/usr/bin/env bash
clear_screen() {
printf '\e[%sH\e[9999C\e[1J%b\e[1;%sr' \
"$((LINES-2))" "${TMUX:+\e[2J}" "$max_items"
}
# Get a file's mime_type.
mime_type=$(file -bi "$1")
# File isn't an image file, give warning.
if [[ $mime_type != image/* ]]; then
lf -remote "send $id echoerr 'Not an image'"
exit
fi
w3m_paths=(/usr/{local/,}{lib,libexec,lib64,libexec64}/w3m/w3mi*)
read -r w3m _ < <(type -p w3mimgdisplay "${w3m_paths[@]}")
read -r LINES COLUMNS < <(stty size)
# Get terminal window size in pixels and set it to WIDTH and HEIGHT.
export $(xdotool getactivewindow getwindowgeometry --shell)
# Get the image size in pixels.
read -r img_width img_height < <("$w3m" <<< "5;${CACHE:-$1}")
((img_width > WIDTH)) && {
((img_height=img_height*WIDTH/img_width))
((img_width=WIDTH))
}
((img_height > HEIGHT)) && {
((img_width=img_width*HEIGHT/img_height))
((img_height=HEIGHT))
}
# Variable needed for centering image.
HALF_HEIGHT=$(expr $HEIGHT / 2)
HALF_WIDTH=$(expr $WIDTH / 2)
HALF_IMG_HEIGHT=$(expr $img_height / 2)
HALF_IMG_WIDTH=$(expr $img_width / 2)
X_POS=$(expr $HALF_WIDTH - $HALF_IMG_WIDTH)
Y_POS=$(expr $HALF_HEIGHT - $HALF_IMG_HEIGHT)
clear_screen
# Hide the cursor.
printf '\e[?25l'
# Display the image.
printf '0;1;%s;%s;%s;%s;;;;;%s\n3;\n4\n' \
${X_POS:-0} \
${Y_POS:-0} \
"$img_width" \
"$img_height" \
"${CACHE:-$1}" | "$w3m" &>/dev/null
# Wait for user input.
read -ern 1
# Clear the image.
printf '6;%s;%s;%s;%s\n3;' \
"${X_POS:-0}" \
"${Y_POS:-0}" \
"$WIDTH" \
"$HEIGHT" | "$w3m" &>/dev/null
clear_screen
Now add key mappings corresponding to the script.
If you only want to preview images on a case by case basis, you may map the draw_img.sh
script to a key:
map - $~/.config/lf/draw_img.sh "$f"
And likewise for video previews:
cmd video_preview ${{
cache="$(mktemp "${TMPDIR:-/tmp}/thumb_cache.XXXXX")"
ffmpegthumbnailer -i "$f" -o "$cache" -s 0
~/.config/lf/draw_img.sh "$cache"
}}
map + :video_preview
The following setup will use kitty to display images, and fall back to pistol for everything else.
As usual, we'll specify a previewer and a cleaner in ~/.config/lf/lfrc:
set previewer ~/.config/lf/lf_kitty_preview
set cleaner ~/.config/lf/lf_kitty_clean
The cleaner script is ~/.config/lf/lf_kitty_clean:
#!/usr/bin/env bash
kitty +icat --clear --silent --transfer-mode file
And the previewer is at ~/.config/lf/lf_kitty_preview:
#!/usr/bin/env bash
file=$1
w=$2
h=$3
x=$4
y=$5
if [[ "$( file -Lb --mime-type "$file")" =~ ^image ]]; then
kitty +icat --silent --transfer-mode file --place "${w}x${h}@${x}x${y}" "$file"
exit 1
fi
pistol "$file"
Don't forget to mark the files as executable: chmod +x ~/.config/lf/lf_kitty_{clean,preview}
As with the setups above, you can integrate ffmpegthumbnailer into the previewer to it to support videos. The following modification, for example, uses the vidthumb script:
#!/usr/bin/env bash
file=$1
w=$2
h=$3
x=$4
y=$5
filetype="$( file -Lb --mime-type "$file")"
if [[ "$filetype" =~ ^image ]]; then
kitty +icat --silent --transfer-mode file --place "${w}x${h}@${x}x${y}" "$file"
exit 1
fi
if [[ "$filetype" =~ ^video ]]; then
# vidthumb is from here:
# https://raw.githubusercontent.com/duganchen/kitty-pistol-previewer/main/vidthumb
kitty +icat --silent --transfer-mode file --place "${w}x${h}@${x}x${y}" "$(vidthumb "$file")"
exit 1
fi
pistol "$file"
stpv and ctpv are previewer utilities made for integration into lf. No wrapper scripts needed, you only need to add 4 lines in lf config to make one of them work.
stpv is a POSIX shell script, while ctpv is a rewrite of stpv written in C. ctpv is faster and has a few additional features.
stpv:
set previewer stpv
set cleaner stpvimgclr
&stpvimg --listen $id
cmd on-quit $stpvimg --end $id
ctpv:
set previewer ctpv
set cleaner ctpvclear
&ctpv -s $id
&ctpvquit $id