From 7c4a81113448b4177bd9c35fd5b04b60dcaf35a7 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Fri, 18 Nov 2011 09:52:50 +0000 Subject: 29908: make MIME functions handle stacked suffixes --- ChangeLog | 9 +++++- Doc/Zsh/contrib.yo | 17 ++++++++++ Functions/MIME/.distfiles | 5 ++- Functions/MIME/zsh-mime-handler | 70 ++++++++++++++++++++++++++++++++--------- 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 + + * 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 * 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 -- cgit 1.4.1