Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: suffix alias problem



On Fri, 11 Nov 2011 18:39:27 +0000
Peter Stephenson <p.w.stephenson@xxxxxxxxxxxx> wrote:
> On Thu, 10 Nov 2011 17:36:55 +0100
> Dieter Faulbaum <Dieter.Faulbaum@xxxxxxxxxxxxxxxxxxx> wrote:
> > is it possible that the zsh-mime-setup can use something like this:
> > 
> > zstyle ':mime:.pdf(|.gz):' handler 'evince %s'
> > 
> > because evince can gunzip files "on the fly"?
> 
> In principle it ought to be possible to do something like that, or 
> 
> zstyle ':mime:.pdf:' handler 'evince %s'
> zstyle ':mime:.pdf.gz:' handler 'evince %s'
> 
> though the shell doesn't do a search for the longest suffix match at the
> moment.  I'll try to remember to look into it.

OK, it does now.  I think both forms of style work.

Index: Doc/Zsh/contrib.yo
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/contrib.yo,v
retrieving revision 1.137
diff -p -u -r1.137 contrib.yo
--- Doc/Zsh/contrib.yo	3 Jul 2011 11:54:12 -0000	1.137
+++ Doc/Zsh/contrib.yo	17 Nov 2011 20:16:34 -0000
@@ -2798,6 +2798,23 @@ start with tt(:mime:), with additional c
 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))(
Index: Functions/MIME/.distfiles
===================================================================
RCS file: /cvsroot/zsh/zsh/Functions/MIME/.distfiles,v
retrieving revision 1.2
diff -p -u -r1.2 .distfiles
--- Functions/MIME/.distfiles	21 Jul 2005 13:45:27 -0000	1.2
+++ Functions/MIME/.distfiles	17 Nov 2011 20:16:34 -0000
@@ -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
 '
Index: Functions/MIME/zsh-mime-contexts
===================================================================
RCS file: Functions/MIME/zsh-mime-contexts
diff -N Functions/MIME/zsh-mime-contexts
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ Functions/MIME/zsh-mime-contexts	17 Nov 2011 20:16:34 -0000
@@ -0,0 +1,24 @@
+# Helper for zsh-mime-handler.
+#
+# Pass in a zstyle option, a suffix, which might include multiple parts
+# (e.g. pdf.gz), plus remaining zstyle arguments plus arguments to zstyle.
+# Try to match the style starting with the longest possible suffix.
+
+local context suffix option
+
+option=$1
+shift
+suffix=$1
+shift
+
+while true; do
+  context=":mime:.${suffix}:"
+  zstyle $option $context "$@" && return 0
+  if [[ $suffix = *.* ]]; then
+    suffix=${suffix#*.}
+  else
+    break
+  fi
+done
+
+return 1
Index: Functions/MIME/zsh-mime-handler
===================================================================
RCS file: /cvsroot/zsh/zsh/Functions/MIME/zsh-mime-handler,v
retrieving revision 1.14
diff -p -u -r1.14 zsh-mime-handler
--- Functions/MIME/zsh-mime-handler	25 Nov 2010 15:43:14 -0000	1.14
+++ Functions/MIME/zsh-mime-handler	17 Nov 2011 20:16:34 -0000
@@ -34,6 +34,8 @@ setopt extendedglob cbases nullglob $aut
 # 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

-- 
Peter Stephenson <p.w.stephenson@xxxxxxxxxxxx>
Web page now at http://homepage.ntlworld.com/p.w.stephenson/



Messages sorted by: Reverse Date, Date, Thread, Author