about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog9
-rw-r--r--Doc/Zsh/contrib.yo17
-rw-r--r--Functions/MIME/.distfiles5
-rw-r--r--Functions/MIME/zsh-mime-handler70
4 files changed, 84 insertions, 17 deletions
diff --git a/ChangeLog b/ChangeLog
index 05c5ba28e..b72cb695c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2011-11-18  Peter Stephenson  <pws@csr.com>
+
+	* 29908: Doc/Zsh/contrib.yo, Functions/MIME/.distfiles,
+	Functions/MIME/zsh-mime-contexts, Functions/MIME/zsh-mime-handler:
+	make MIME functions handle contexts with stacked suffixes such
+	as .pdf.gz.
+
 2011-11-17  Peter Stephenson  <pws@csr.com>
 
 	* Jun T.: 29907: Src/Modules/pcre.c: remove declaration of
@@ -15582,5 +15589,5 @@
 
 *****************************************************
 * This is used by the shell to define $ZSH_PATCHLEVEL
-* $Revision: 1.5500 $
+* $Revision: 1.5501 $
 *****************************************************
diff --git a/Doc/Zsh/contrib.yo b/Doc/Zsh/contrib.yo
index b02c61c45..aee0bd7f4 100644
--- a/Doc/Zsh/contrib.yo
+++ b/Doc/Zsh/contrib.yo
@@ -2803,6 +2803,23 @@ start with tt(:mime:), with additional components in some cases.
 It is recommended that a trailing tt(*) (suitably quoted) be appended
 to style patterns in case the system is extended in future.  Some
 examples are given below.
+
+For files that have multiple suffixes, e.g. tt(.pdf.gz), where the
+context includes the suffix it will be looked up starting with the
+longest possible suffix until a match for the style is found.
+For example, if tt(.pdf.gz) produces a match for the handler, that
+will be used; otherwise the handler for tt(.gz) will be used.  Note
+that, owing to the way suffix aliases work, it is always required that
+there be a handler for the shortest possible suffix, so in this example
+tt(.pdf.gz) can only be handled if tt(.gz) is also handled (though
+not necessarily in the same way).  Alternatively, if no handling
+for tt(.gz) on its own is needed, simply adding the command
+
+example(alias -s gz=zsh-mime-handler)
+
+to the initialisation code is sufficient; tt(.gz) will not be handled
+on its own, but may be in combination with other suffixes.
+
 startitem()
 kindex(current-shell, MIME style)
 item(tt(current-shell))(
diff --git a/Functions/MIME/.distfiles b/Functions/MIME/.distfiles
index 01ac0d7ef..93c13f7da 100644
--- a/Functions/MIME/.distfiles
+++ b/Functions/MIME/.distfiles
@@ -1,4 +1,7 @@
 DISTFILES_SRC='
 .distfiles
-zsh-mime-setup zsh-mime-handler pick-web-browser
+pick-web-browser
+zsh-mime-contexts
+zsh-mime-handler
+zsh-mime-setup
 '
diff --git a/Functions/MIME/zsh-mime-handler b/Functions/MIME/zsh-mime-handler
index 9a40e67bb..abaf0b6e3 100644
--- a/Functions/MIME/zsh-mime-handler
+++ b/Functions/MIME/zsh-mime-handler
@@ -34,6 +34,8 @@ setopt extendedglob cbases nullglob $autocd
 # We need zformat from zsh/zutil for %s replacement.
 zmodload -i zsh/zutil
 
+autoload -Uz zsh-mime-contexts
+
 # Look for options.  Because of the way this is usually invoked,
 # (there is always a command to be handled), only handle options
 # up to second last argument.
@@ -62,12 +64,15 @@ shift $(( OPTIND - 1 ))
 # just as well pass them all down.  However, we just take the
 # suffix from the first since that's what invoked us via suffix -s.
 
-local suffix context
+local suffix s
 local -a match mbegin mend
 
-[[ $1 = (#b)*.([^.]##) ]] || return 1
-suffix=${(L)match[1]}
-context=":mime:.${suffix}:"
+suffix=${1:t}
+if [[ $suffix != *.* ]]; then
+  "No suffix in command: $1" >&2
+  return 1
+fi
+suffix=${suffix#*.}
 
 local handler flags no_sh no_bg arg
 integer i
@@ -77,11 +82,11 @@ local -a exec_asis hand_nonex
 # despite being called for interpretation by the mime handler.
 # Defaults to executable files, which ensures that they are executed as
 # they are, even if they have a suffix.
-zstyle -a $context execute-as-is exec_asis || exec_asis=('*(*)' '*(/)')
+zsh-mime-contexts -a $suffix execute-as-is exec_asis || exec_asis=('*(*)' '*(/)')
 
 # Set to a list of patterns for which the handler will be used even
 # if the file doesn't exist on the disk.
-zstyle -a $context handle-nonexistent hand_nonex ||
+zsh-mime-contexts -a $suffix handle-nonexistent hand_nonex ||
   hand_nonex=('[[:alpha:]]#:/*')
 
 local pattern
@@ -92,9 +97,9 @@ local -a files
 # actual file or its directory.
 local dir
 local -a filepath
-if zstyle -t $context find-file-in-path && [[ $1 != /* ]] &&
+if zsh-mime-contexts -t $suffix find-file-in-path && [[ $1 != /* ]] &&
   [[ $1 != */* || -o pathdirs ]]; then
-  zstyle -a $context file-path filepath || filepath=($path)
+  zsh-mime-contexts -a $suffix file-path filepath || filepath=($path)
   for dir in $filepath; do
     if [[ -e $dir/$1 ]]; then
       1=$dir/$1
@@ -153,19 +158,54 @@ if [[ ! -e $1 ]]; then
   fi
 fi
 
-zstyle -s $context handler handler ||
-  handler="${zsh_mime_handlers[$suffix]}"
-zstyle -s $context flags flags ||
-  flags="${zsh_mime_flags[$suffix]}"
+if ! zsh-mime-contexts -s $suffix handler handler; then
+  # Look for handler starting with longest suffix match.
+  # Typically we'd only get a match for the shortest, but don't assume so.
+  s=$suffix
+  while true; do
+    handler="${zsh_mime_handlers[$s]}"
+    if [[ -n $handler ]]; then
+      break
+    fi
+    if [[ $s = *.* ]]; then
+      s=${s#*.}
+    else
+      break
+    fi
+  done
+  if [[ -z $handler ]]; then
+    if [[ $suffix = *.* ]]; then
+      print "No handler specified for suffix .$suffix or any final part" >&2
+    else
+      print "No handler specified for suffix .$suffix" >&2
+    fi
+    return 1
+  fi
+fi
+if ! zsh-mime-contexts -s $suffix flags flags; then
+  # Same again for flags.
+  s=$suffix
+  while true; do
+    flags="${zsh_mime_flags[$suffix]}"
+    if [[ -n $flags ]]; then
+      break
+    fi
+    if [[ $s = *.* ]]; then
+      s=${s#*.}
+    else
+      break
+    fi
+  done
+fi
 
 # Set to yes if we use eval instead of sh -c for complicated mailcap lines
 # Can possibly break some mailcap entries which expect sh compatibility,
 # but is faster, as a new process is not spawned.
-zstyle -t $context current-shell && no_sh=yes
+zsh-mime-contexts -t $suffix current-shell && no_sh=yes
 
 # Set to yes if the process shouldn't be backgrounded even if it doesn't need a
 # terminal and display is set.
-zstyle -t $context never-background && no_bg=yes
+zsh-mime-contexts -t $suffix never-background && no_bg=yes
 
 local hasmeta stdin
 
@@ -241,7 +281,7 @@ if [[ $flags = *copiousoutput* ]]; then
   # We need to page the output.
   # Careful in case PAGER is a set of commands and arguments.
   local -a pager
-  zstyle -a $context pager pager || pager=(${=PAGER:-more})
+  zsh-mime-contexts -a $suffix pager pager || pager=(${=PAGER:-more})
   if [[ -n $stdin ]]; then
     cat $argv | $execargs | $pager
   else