From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 7516 invoked by alias); 17 Nov 2011 20:19:26 -0000 Mailing-List: contact zsh-workers-help@zsh.org; run by ezmlm Precedence: bulk X-No-Archive: yes List-Id: Zsh Workers List List-Post: List-Help: X-Seq: 29908 Received: (qmail 15354 invoked from network); 17 Nov 2011 20:19:13 -0000 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.2 Received-SPF: neutral (ns1.primenet.com.au: 74.125.82.43 is neither permitted nor denied by SPF record at ntlworld.com) X-ProxyUser-IP: 86.6.29.42 Date: Thu, 17 Nov 2011 20:19:02 +0000 From: Peter Stephenson To: zsh-workers@zsh.org Subject: Re: suffix alias problem Message-ID: <20111117201902.6efafcd7@pws-pc.ntlworld.com> In-Reply-To: <20111111183927.4d06c703@pws-pc.ntlworld.com> References: <20111111183927.4d06c703@pws-pc.ntlworld.com> X-Mailer: Claws Mail 3.7.9 (GTK+ 2.24.7; x86_64-redhat-linux-gnu) Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit On Fri, 11 Nov 2011 18:39:27 +0000 Peter Stephenson wrote: > On Thu, 10 Nov 2011 17:36:55 +0100 > Dieter Faulbaum 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 Web page now at http://homepage.ntlworld.com/p.w.stephenson/