summary refs log tree commit diff stats
diff options
context:
space:
mode:
authornfnty <git@nfnty.se>2017-01-28 19:35:10 +0100
committernfnty <git@nfnty.se>2017-01-28 22:46:18 +0100
commit60efe50d786de496471ea14356b793fd8032b0d7 (patch)
treea30c990da0ad5c99ab8defc95814a3fa0e6ef73b
parent6a788eb1b280132b64ce648254c4bfe5edc2c12d (diff)
downloadranger-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-xranger/data/scope.sh259
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