diff options
author | nfnty <git@nfnty.se> | 2017-01-28 19:35:10 +0100 |
---|---|---|
committer | nfnty <git@nfnty.se> | 2017-01-28 22:46:18 +0100 |
commit | 60efe50d786de496471ea14356b793fd8032b0d7 (patch) | |
tree | a30c990da0ad5c99ab8defc95814a3fa0e6ef73b | |
parent | 6a788eb1b280132b64ce648254c4bfe5edc2c12d (diff) | |
download | ranger-60efe50d786de496471ea14356b793fd8032b0d7.tar.gz |
data/scope.sh: Complete refactor
Enforce `bash` (bashisms were previously used without proper shebang) Improve performance Do not trim output Do not try to highlight huge files Increase readability Fixes #112
-rwxr-xr-x | ranger/data/scope.sh | 259 |
1 files changed, 147 insertions, 112 deletions
diff --git a/ranger/data/scope.sh b/ranger/data/scope.sh index 5144649a..4fc720d3 100755 --- a/ranger/data/scope.sh +++ b/ranger/data/scope.sh @@ -1,123 +1,158 @@ -#!/usr/bin/env sh -# ranger supports enhanced previews. If the option "use_preview_script" -# is set to True and this file exists, this script will be called and its -# output is displayed in ranger. ANSI color codes are supported. +#!/usr/bin/env bash -# NOTES: This script is considered a configuration file. If you upgrade -# ranger, it will be left untouched. (You must update it yourself.) -# Also, ranger disables STDIN here, so interactive scripts won't work properly +set -o noclobber -o noglob -o nounset -o pipefail +IFS=$'\n' + +# If the option `use_preview_script` is set to `true`, +# then this script will be called and its output will be displayed in ranger. +# ANSI color codes are supported. +# STDIN is disabled, so interactive scripts won't work properly + +# This script is considered a configuration file and must be updated manually. +# It will be left untouched if you upgrade ranger. # Meanings of exit codes: # code | meaning | action of ranger # -----+------------+------------------------------------------- -# 0 | success | success. display stdout as preview -# 1 | no preview | failure. display no preview at all -# 2 | plain text | display the plain content of the file -# 3 | fix width | success. Don't reload when width changes -# 4 | fix height | success. Don't reload when height changes -# 5 | fix both | success. Don't ever reload -# 6 | image | success. display the image $cached points to as an image preview -# 7 | image | success. display the file directly as an image - -# Meaningful aliases for arguments: -path="$1" # Full path of the selected file -width="$2" # Width of the preview pane (number of fitting characters) -height="$3" # Height of the preview pane (number of fitting characters) -cached="$4" # Path that should be used to cache image previews -preview_images="$5" # "True" if image previews are enabled, "False" otherwise. - -maxln=200 # Stop after $maxln lines. Can be used like ls | head -n $maxln - -# Find out something about the file: -mimetype=$(file --mime-type -Lb "$path") -extension=$(/bin/echo "${path##*.}" | awk '{print tolower($0)}') - -# Functions: -# runs a command and saves its output into $output. Useful if you need -# the return value AND want to use the output in a pipe -try() { output=$(eval '"$@"'); } - -# writes the output of the previously used "try" command -dump() { /bin/echo "$output"; } - -# a common post-processing function used after most commands -trim() { head -n "$maxln"; } - -# wraps highlight to treat exit code 141 (killed by SIGPIPE) as success -safepipe() { "$@"; test $? = 0 -o $? = 141; } - -# Image previews, if enabled in ranger. -if [ "$preview_images" = "True" ]; then - case "$mimetype" in - # Image previews for SVG files, disabled by default. - ###image/svg+xml) - ### convert "$path" "$cached" && exit 6 || exit 1;; - # Image previews for image files. w3mimgdisplay will be called for all - # image files (unless overriden as above), but might fail for - # unsupported types. +# 0 | success | Display stdout as preview +# 1 | no preview | Display no preview at all +# 2 | plain text | Display the plain content of the file +# 3 | fix width | Don't reload when width changes +# 4 | fix height | Don't reload when height changes +# 5 | fix both | Don't ever reload +# 6 | image | Display the image `$IMAGE_CACHE_PATH` points to as an image preview +# 7 | image | Display the file directly as an image + +# Script arguments +FILE_PATH="${1}" # Full path of the highlighted file +PV_WIDTH="${2}" # Width of the preview pane (number of fitting characters) +PV_HEIGHT="${3}" # Height of the preview pane (number of fitting characters) +IMAGE_CACHE_PATH="${4}" # Full path that should be used to cache image preview +PV_IMAGE_ENABLED="${5}" # 'True' if image previews are enabled, 'False' otherwise. + +EXTENSION="${FILE_PATH##*.}" +EXTENSION_LOWER="${EXTENSION,,}" + +# Settings +HIGHLIGHT_SIZE_MAX=262143 # 256KiB +HIGHLIGHT_STYLE='pablo' +PYGMENTIZE_STYLE='autumn' + + +handle_extension() { + case "${EXTENSION_LOWER}" in + # Archive + a|ace|alz|arc|arj|bz|bz2|cab|cpio|deb|gz|jar|lha|lz|lzh|lzma|lzo|\ + rpm|rz|t7z|tar|tbz|tbz2|tgz|tlz|txz|tZ|tzo|war|xpi|xz|Z|zip) + atool --list -- "${FILE_PATH}" && exit 5 + bsdtar --list --file "${FILE_PATH}" && exit 5 + exit 1;; + rar) + # Avoid password prompt by providing empty password + unrar lt -p- -- "${FILE_PATH}" && exit 5 + exit 1;; + 7z) + # Avoid password prompt by providing empty password + 7z l -p -- "${FILE_PATH}" && exit 5 + exit 1;; + + # PDF + pdf) + # Preview as text conversion + pdftotext -l 10 -nopgbrk -q -- "${FILE_PATH}" - && exit 5 + exiftool "${FILE_PATH}" && exit 5 + exit 1;; + + # BitTorrent + torrent) + transmission-show -- "${FILE_PATH}" && exit 5 + exit 1;; + + # OpenDocument + odt|ods|odp|sxw) + # Preview as text conversion + odt2txt "${FILE_PATH}" && exit 5 + exit 1;; + + # HTML + htm|html|xhtml) + # Preview as text conversion + w3m -dump "${FILE_PATH}" && exit 5 + lynx -dump -- "${FILE_PATH}" && exit 5 + elinks -dump "${FILE_PATH}" && exit 5 + ;; # Continue with next handler on failure + esac +} + +handle_image() { + local mimetype="${1}" + case "${mimetype}" in + # SVG + # image/svg+xml) + # convert "${FILE_PATH}" "${IMAGE_CACHE_PATH}" && exit 6 + # exit 1;; + + # Image image/*) + # `w3mimgdisplay` will be called for all images (unless overriden as above), + # but might fail for unsupported types. exit 7;; - # Image preview for video, disabled by default.: - ###video/*) - ### ffmpegthumbnailer -i "$path" -o "$cached" -s 0 && exit 6 || exit 1;; + + # Video + # video/*) + # # Thumbnail + # ffmpegthumbnailer -i "${FILE_PATH}" -o "${IMAGE_CACHE_PATH}" -s 0 && exit 6 + # exit 1;; esac -fi +} + +handle_mime() { + local mimetype="${1}" + case "${mimetype}" in + # Text + text/* | */xml) + # Syntax highlight + if [[ "$( stat --printf='%s' -- "${FILE_PATH}" )" -gt "${HIGHLIGHT_SIZE_MAX}" ]]; then + exit 2 + fi + if [[ "$( tput colors )" -ge 256 ]]; then + local pygmentize_format='terminal256' + local highlight_format='xterm256' + else + local pygmentize_format='terminal' + local highlight_format='ansi' + fi + highlight --out-format="${highlight_format}" --style="${HIGHLIGHT_STYLE}" -- "${FILE_PATH}" && exit 5 + # pygmentize -f "${pygmentize_format}" -O "style=${PYGMENTIZE_STYLE}" -- "${FILE_PATH}" && exit 5 + exit 2;; + + # Image + image/*) + # Preview as text conversion + # img2txt --gamma=0.6 --width="${PV_WIDTH}" -- "${FILE_PATH}" && exit 4 + exiftool "${FILE_PATH}" && exit 5 + exit 1;; + + # Video and audio + video/* | audio/*) + mediainfo "${FILE_PATH}" && exit 5 + exiftool "${FILE_PATH}" && exit 5 + exit 1;; + esac +} -case "$extension" in - # Archive extensions: - a|ace|alz|arc|arj|bz|bz2|cab|cpio|deb|gz|jar|lha|lz|lzh|lzma|lzo|\ - rpm|rz|t7z|tar|tbz|tbz2|tgz|tlz|txz|tZ|tzo|war|xpi|xz|Z|zip) - try als "$path" && { dump | trim; exit 0; } - try acat "$path" && { dump | trim; exit 3; } - try bsdtar -lf "$path" && { dump | trim; exit 0; } - exit 1;; - rar) - # avoid password prompt by providing empty password - try unrar -p- lt "$path" && { dump | trim; exit 0; } || exit 1;; - 7z) - # avoid password prompt by providing empty password - try 7z -p l "$path" && { dump | trim; exit 0; } || exit 1;; - # PDF documents: - pdf) - try pdftotext -l 10 -nopgbrk -q "$path" - && \ - { dump | trim | fmt -s -w $width; exit 0; } || exit 1;; - # BitTorrent Files - torrent) - try transmission-show "$path" && { dump | trim; exit 5; } || exit 1;; - # ODT Files - odt|ods|odp|sxw) - try odt2txt "$path" && { dump | trim; exit 5; } || exit 1;; - # HTML Pages: - htm|html|xhtml) - try w3m -dump "$path" && { dump | trim | fmt -s -w $width; exit 4; } - try lynx -dump "$path" && { dump | trim | fmt -s -w $width; exit 4; } - try elinks -dump "$path" && { dump | trim | fmt -s -w $width; exit 4; } - ;; # fall back to highlight/cat if the text browsers fail -esac - -case "$mimetype" in - # Syntax highlight for text files: - text/* | */xml) - if [ "$(tput colors)" -ge 256 ]; then - pygmentize_format=terminal256 - highlight_format=xterm256 - else - pygmentize_format=terminal - highlight_format=ansi - fi - try safepipe highlight --out-format=${highlight_format} "$path" && { dump | trim; exit 5; } - try safepipe pygmentize -f ${pygmentize_format} "$path" && { dump | trim; exit 5; } - exit 2;; - # Ascii-previews of images: - image/*) - img2txt --gamma=0.6 --width="$width" "$path" && exit 4 || exit 1;; - # Display information about media files: - video/* | audio/*) - exiftool "$path" && exit 5 - # Use sed to remove spaces so the output fits into the narrow window - try mediainfo "$path" && { dump | trim | sed 's/ \+:/: /;'; exit 5; } || exit 1;; -esac - -echo '----- File Type Classification -----' && file -Lb "${path}" && exit 5 || exit 1 +handle_fallback() { + echo '----- File Type Classification -----' && file --dereference --brief -- "${FILE_PATH}" && exit 5 + exit 1 +} + + +handle_extension +MIMETYPE="$( file --dereference --brief --mime-type -- "${FILE_PATH}" )" +if [[ "${PV_IMAGE_ENABLED}" == 'True' ]]; then + handle_image "${MIMETYPE}" +fi +handle_mime "${MIMETYPE}" +handle_fallback exit 1 |