#!/bin/bash # [b]rowse - overview of given files or current directory # depends: tput stat bat checkaccess(in my dotfiles) # optdepends: timg, neovim (compressed files), pdftoppm (PDF), mtn (video), audiowaveform # args: files to inspect # # Supports: # - listing directories # - listing contents of any compressed file with neovim # - visual files are displayed with timg # video thumbnails via mtn, pdf pages from pdftoppm # - text files are displayed through bat # Automatically requests elevation through sudo when needed set -o pipefail for last; do true; done last=${last:-.} checkperm() { checkaccess -r "$@" || elevate=sudo mime="$(test -n "$shifted" || $elevate file --dereference --mime "$@")" } checkperm "$last" fileinfo() { tput setaf 6 for arg do case "$arg" in (-*) continue;; esac $elevate file -E "$arg" && ffprobe "$arg" 2>&1 | grep Duration | grep -v '00:00:00.04' | sed 's/, start:[^,]\+,/,/' || stat --format '%A %s - birth %.10w mod %.10y' "$arg" | numfmt --field=2 --to=iec-i --padding=6 --suffix=B done } prefix=/tmp/b mkdir -p "$prefix" declare -a timg bat ls for arg; do case "$arg" in (-*) args="$args $arg"; continue;; esac checkperm "$arg" grid=$(expr $(tput cols) / 20) tmpfile="$prefix/$(basename "$arg")" case "$mime" in (*\ application/pdf\;*) test -f "$tmpfile-1.png" || pdftoppm -r 70 "$arg" "$tmpfile" -l $(expr $grid '*' 2) timg -W --grid=$grid "$tmpfile"* ;; (*\ video/*) suffix=_thumbs.jpg mtn -i -t -W -D6 -b 0,6 -c $grid -w $(expr $(tput cols) '*' 20) -O $prefix -o $suffix "$arg" 2>/dev/null timg -W "$prefix/$(basename "${arg%.*}")$suffix" ;; (*\ image/*) timg+=("$arg"); continue;; (*\ inode/directory\;*) ls+=("$arg"); continue;; (*) case "$(file "$arg")" in (*\ ?udio*) img="$tmpfile.png" if which audiowaveform 2>/dev/null >&2 then find "$img" -not -empty 2>/dev/null | grep --quiet . || audiowaveform --quiet --pixels-per-second 2 --height 36 --width 2000 --amplitude-scale auto \ --background-color 000000 --waveform-color 99BBFF --axis-label-color 000000 \ --input-filename "$arg" --output-format png >"$img" && { timg -g $(tput cols)x2 "$arg" && printf "\\033[2A " timg -g $(tput cols)x2 --auto-crop --upscale "$img" } fi ;; (*:\ *compress*|*tar\ archive) if test $# = 1 then nvim "$arg" else case "$arg" in (*.part);; (*) nvim -es "+2w$tmpfile|5,w>>$tmpfile" "$arg" bat+=("$tmpfile");; esac; fi ;; (*) bat+=("$arg"); continue;; esac ;; esac fileinfo "$arg" done if test "$timg"; then tput sgr0 $elevate timg --center -t0.3 $(test $# -gt 1 && echo "--title --grid=$(expr $(tput cols) / 30)" || echo "-g 60x$(expr $(tput lines) / 2)") "$@" 2>/dev/null for img in "${timg[@]}" do printf "%11s %-30s %s\n" "$(identify -format "%wx%h" "$img")" "$img" "$(identify -precision 3 -format "%b %m %[bit-depth]-bit %[colorspace]" "$img")" done fi if test "$bat"; then tput sgr0 test $# -gt ${#bat[@]} && test -z "$args" && $elevate head "${bat[@]}" || $elevate bat --style header --pager 'less -RF' $args "${bat[@]}" fileinfo "${bat[@]}" fi if test "$ls"; then tput sgr0 $elevate ls -l $(test $# -gt ${#ls[@]} && echo "-d") --color=always --human-readable --group-directories-first --file-type --dereference-command-line --all "${ls[@]}" | less -RF fi