From 5d13b073adf2f82d3744df787d7394e587868eca Mon Sep 17 00:00:00 2001 From: ItsDrike Date: Mon, 26 Jul 2021 19:10:56 +0200 Subject: [PATCH] Add image previews to lf --- home/.config/lf/clear_img.sh | 6 ++ home/.config/lf/draw_img.sh | 11 +++ home/.config/lf/lfrc | 3 +- home/.config/lf/previewer.sh | 129 +++++++++++++++++++++++++++++++++++ 4 files changed, 148 insertions(+), 1 deletion(-) create mode 100755 home/.config/lf/clear_img.sh create mode 100755 home/.config/lf/draw_img.sh create mode 100755 home/.config/lf/previewer.sh diff --git a/home/.config/lf/clear_img.sh b/home/.config/lf/clear_img.sh new file mode 100755 index 0000000..dbc35d7 --- /dev/null +++ b/home/.config/lf/clear_img.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +readonly PREVIEW_ID="preview" + +printf '{"action": "remove", "identifier": "%s"}\n' "$PREVIEW_ID" > "$FIFO_UEBERZUG" + diff --git a/home/.config/lf/draw_img.sh b/home/.config/lf/draw_img.sh new file mode 100755 index 0000000..e735652 --- /dev/null +++ b/home/.config/lf/draw_img.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +readonly PREVIEW_ID="preview" + +printf '{"action": "add", "identifier": "%s", "x": %d, "y": %d, "width": %d, "height": %d, "scaler": "contain", "scaling_position_x": 0.5, "scaling_position_y": 0.5, "path": "%s"}\n' \ + "$PREVIEW_ID" "$2" "$3" "$4" "$5" "$1" > "$FIFO_UEBERZUG" + +#declare -p -A cmd=([action]=add [identifier]="$PREVIEW_ID" \ +# [x]="$2" [y]="$3" [max_width]="$4" [max_height]="$5" \ +# [path]="$1") > "$FIFO_UEBERZUG" + diff --git a/home/.config/lf/lfrc b/home/.config/lf/lfrc index be3844e..572914e 100644 --- a/home/.config/lf/lfrc +++ b/home/.config/lf/lfrc @@ -1,5 +1,6 @@ # Basic settings -set previewer ~/.config/lf/previewer +set previewer ~/.config/lf/previewer.sh +set cleaner ~/.config/lf/clear_img.sh set preview true set hidden true set drawbox true diff --git a/home/.config/lf/previewer.sh b/home/.config/lf/previewer.sh new file mode 100755 index 0000000..2b787b8 --- /dev/null +++ b/home/.config/lf/previewer.sh @@ -0,0 +1,129 @@ +#!/bin/sh +# This script handles showing file-previews within lf. +# It can also show image previews using ueberzug, however +# that requires lf to be start with a script that also starts +# ueberzug alongside of it. +# (In my dotfiles, this script is in '~/.local/bin/scripts/lfu') + +run_cmd() { + # Try to run given command, if it is installed. + # If it isn't try to fallback to text_handle, + # otherwise fail completely. + cmd="$1" + shift + + if command -v "$cmd" > /dev/null; then + $cmd $@ + else + # If we didn't found the requested command, check if + # the file is text-like and try to use the text_handle + # to show the preview, this may not be ideal for given + # file-format, but at least we won't fail. + case $(file --mime-type "$1" -bL) in + # TODO: Consider checking for UTF-8 formatting instead, + # or show previews for any file-type + text/*|application/json) + echo "@@PREVIEW FALLBACK: Using text handle, $cmd command not found!" + text_handle "$1" + ;; + *) + echo "@@PREVIEW ERROR: Preview failed, $cmd command not found!" + ;; + esac + fi +} + +draw_image() { + # Draw passed image with use of given draw_script. + # If the image contains EXIF (metadata) orientation info, + # handle it and draw the rotated image. + draw_script="$1" + file="$2" + shift + shift + + # Calculate where the image should be placed on the screen. + num=$(printf "%0.f\n" "`echo "$(tput cols) / 2" | bc`") + numb=$(printf "%0.f\n" "`echo "$(tput cols) - $num - 1" | bc`") + numc=$(printf "%0.f\n" "`echo "$(tput lines) - 2" | bc`") + + # Handle EXIF (metadata) orientation. + exif_orientation="$(identify -format '%[EXIF:Orientation]\n' -- "$file")" + if [ -n "$exif_orientation" ] && [ "$exif_orientation" != 1 ]; then + # In case `convert` command isn't aviable, ignore EXIF rotation + if command -v convert > /dev/null; then + cache=$(mktemp /tmp/thumbcache.XXXXX) + convert -- "$file" -auto-orient "$cache" + $draw_script "$cache" $num 1 $numb $numc + else + $draw_script "$file" $num 1 $numb $numc + fi + else + $draw_script "$file" $num 1 $numb $numc + fi + + # Exit with status code 1 to signal lf that the function + # should be re-ran next time instead of caching the result. + exit 1 +} + +image_handle() { + # Control function for showing/cleaning image previews + draw_script="${XDG_CONFIG_HOME:-$HOME/.config}/lf/draw_img.sh" + file="$1" + shift + + if [ -n "$FIFO_UEBERZUG" ] && [ -f "$draw_script" ]; then + draw_image $draw_script $file + else + # Fallback to mediainfo preview + echo "@@PREVIEW FALLBACK: Using mediainfo, ueberzug isn't aviable." + run_cmd mediainfo "$file" + fi +} + +text_handle() { + width="$(tput cols)" + echo "Limiting to $width" + # Handle all other formats as text and cat them + # if highlighting tools are aviable, try to use them + if command -v bat > /dev/null; then + bat -pp --color=always "$1" + elif command -v highlight > /dev/null; then + highlight "$1" --out-format ansi --force + else + cat "$1" + fi +} + +# Capture all directories at first, since they could +# potentionally match one of the file case statements +if [ -d "$1" ]; then + tree "$1" -La 1 +elif [ -f "$1" ]; then + case "$1" in + *.tgz|*.tar.gz) run_cmd tar tzf "$1";; + *.tar.bz2|*.tbz2) run_cmd tar tjf "$1";; + *.tar.txz|*.txz) run_cmd xz --list "$1";; + *.tar) run_cmd tar tf "$1";; + *.zip|*.jar|*.war|*.ear|*.oxt) run_cmd unzip -l "$1";; + *.rar) run_cmd unrar l "$1";; + *.7z) run_cmd 7z l "$1";; + *.iso) run_cmd iso-info --no-header -l "$1";; + *.o) run_cmd nm "$1" | less ;; + *.csv) cat "$1" | sed s/,/\\n/g ;; + *odt,*.ods,*.odp,*.sxw) run_cmd odt2txt "$1";; + *.doc) run_cmd catdoc "$1" ;; + *.docx) run_cmd docx2txt "$1" - ;; + *.torrent) run_cmd transmission-show "$1";; + *.pdf) run_cmd pdftotext "$1";; + *.bmp|*.jpg|*.jpeg|*.png|*.xpm) image_handle "$1" ;; + *.wav|*.mp3|*.flac|*.m4a|*.wma|*.ape|*.ac3|*.og[agx]|*.spx|*.opus|*.as[fx]|*.flac) run_cmd exiftool "$1";; + *.avi|*.mp4|*.wmv|*.dat|*.3gp|*.ogv|*.mkv|*.mpg|*.mpeg|*.vob|*.fl[icv]|*.m2v|*.mov|*.webm|*.ts|*.mts|*.m4v|*.r[am]|*.qt|*.divx) + cache="$(mktemp /tmp/thumbcache.XXXXX)" + ffmpegthumbnailer -i "$1" -o "$cache" -s 0 + image_handle "$cache" + ;; + *) text_handle "$1" ;; + esac +fi