zshrc: support PAGER='less -Mr' usage and fall back to vi if LESSOPEN is unset
authorMichael Prokop <mika@grml.org>
Thu, 14 Nov 2019 15:31:21 +0000 (16:31 +0100)
committerMichael Prokop <mika@grml.org>
Thu, 14 Nov 2019 16:30:59 +0000 (17:30 +0100)
It's horribly annoying when PAGER is set to less, but lesspipe isn't configured
via LESSOPEN, then `dchange $package` fails with less like this:

% dchange zsh
"/usr/share/doc/zsh/changelog.Debian.gz" may be a binary file.  See it anyway?

vi(m) handles *.gz just fine, so let's try to use vi if PAGER is set to
less and LESSOPEN is unset.

While at it fix usage of ${PAGER} vs ${=PAGER} to also handle
a setting like PAGER='less -Mr' and PAGER=(less -Mr), otherwise
failing with `command not found: less -Mr`.

Thanks: AndrĂ¡s Korn for review and improvement suggestions

etc/zsh/zshrc

index 0a7d730..2969729 100644 (file)
@@ -2928,9 +2928,6 @@ function sll () {
     return ${RTN}
 }
 
-# TODO: Is it supported to use pager settings like this?
-#   PAGER='less -Mr' - If so, the use of $PAGER here needs fixing
-# with respect to wordsplitting. (ie. ${=PAGER})
 if check_com -c $PAGER ; then
     #f3# View Debian's changelog of given package(s)
     function dchange () {
@@ -2938,13 +2935,28 @@ if check_com -c $PAGER ; then
         [[ -z "$1" ]] && printf 'Usage: %s <package_name(s)>\n' "$0" && return 1
 
         local package
+
+        # `less` as $PAGER without e.g. `|lesspipe %s` inside $LESSOPEN can't properly
+        # read *.gz files, try to detect this to use vi instead iff available
+        local viewer
+
+        if [[ ${$(typeset -p PAGER)[2]} = -a ]] ; then
+          viewer=($PAGER)    # support PAGER=(less -Mr) but leave array untouched
+        else
+          viewer=(${=PAGER}) # support PAGER='less -Mr'
+        fi
+
+        if [[ ${viewer[1]:t} = less ]] && [[ -z "${LESSOPEN}" ]] && check_com vi ; then
+          viewer='vi'
+        fi
+
         for package in "$@" ; do
             if [[ -r /usr/share/doc/${package}/changelog.Debian.gz ]] ; then
-                $PAGER /usr/share/doc/${package}/changelog.Debian.gz
+                $viewer /usr/share/doc/${package}/changelog.Debian.gz
             elif [[ -r /usr/share/doc/${package}/changelog.gz ]] ; then
-                $PAGER /usr/share/doc/${package}/changelog.gz
+                $viewer /usr/share/doc/${package}/changelog.gz
             elif [[ -r /usr/share/doc/${package}/changelog ]] ; then
-                $PAGER /usr/share/doc/${package}/changelog
+                $viewer /usr/share/doc/${package}/changelog
             else
                 if check_com -c aptitude ; then
                     echo "No changelog for package $package found, using aptitude to retrieve it."