#!/usr/bin/env bash show_help() { printf """ vifm-thumbnailer Easily show images/thumbnails from the vifm file manager. Usage: vifm-thumbnailer Point it to a file whose directory you want thumbnailed. If you point it to a directory itself, it will list its contents. Options: -h Display this help. -r Show images recursively from current folder. -t Open viewer in thumbnail mode. -m Show thumbnails for video files in addition to image files. Will take longer to load up and requires ffmpeg utilities. Vifm: If the file is on your path (e.g. in ~/.vifm/scripts) from within vifm you can run the script by invoking it with: \`:!vifm-thumbnailer \%%c\` which will show all directory thumbnails with the current file initially shown. If you want to have vifm show a filtered view for selected files afterwards add a \%%u to the command. """ } TMPDIR="$(mktemp -d)" valid_files_tmp="$TMPDIR/nsxiv_rifle_$$" # get all files in directory list_img_files() { if exist fd; then fd --max-depth="$maxdepth" -tf . "${1%/*}" | is_img_extension | sort | tee -a "$valid_files_tmp" else find -L "${1%/*}" -maxdepth "$maxdepth" -type f -print | is_img_extension | sort | tee -a "$valid_files_tmp" fi } list_vid_files() { # shellcheck disable=2016 find "${1%/*}" -mindepth 1 -maxdepth "$maxdepth" \( -type f -o -type l \) -printf "%P\0" | xargs -r0 -n 20 -P 64 file -00 -L --mime-type -- | xargs -r0 -n 2 sh -c ' case "$2" in video/*) printf "%s\0" "$1";; esac ' -- | sort -z | xargs -r0 -I FILE ffmpegthumbnailer -i FILE -o "$TMPDIR/FILE.jpg" -m -s 384 find -L "$TMPDIR/" -maxdepth "$maxdepth" -type f -print | sort | tee -a "$valid_files_tmp" } img_ext="jpe?g|png|gif|svg|webp|tiff|heif|avif|ico|bmp" is_img_extension() { grep -iE "\.($img_ext)$" } # TODO if marking video thumbnail - will use wrong temporary path on output, makes e.g. vifm %u not work open() { trap 'rm -rf -- $TMPDIR' TERM INT EXIT current="$(list_img_files "$1" | grep -nF "$1")" if [ "$videos" = true ]; then list_vid_files "$1" fi [ "$thumbnails" = true ] && nsxiv_args="-t" if [ -n "$current" ]; then nsxiv "$nsxiv_args" -i -n "${current%%:*}" -o -- <"$valid_files_tmp" else # fallback incase file didn't have a valid extension, or we couldn't # find it inside the list nsxiv -o -i -- <"$valid_files_tmp" fi } maxdepth=1 while getopts "mrt?h" opt; do case "$opt" in r) maxdepth=100 ;; m) videos=true ;; t) thumbnails=true ;; h | \? | *) show_help exit 0 ;; esac done shift $((OPTIND - 1)) [ "$1" = '--' ] && shift case "$1" in "") echo "Usage: ${0##*/} PICTURES" >&2 exit 1 ;; /*) open "$1" ;; "~"/*) open "$HOME/${1#"~"/}" ;; *) open "$PWD/$1" ;; esac