summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog9
-rw-r--r--Completion/Zsh/Function/.distfiles4
-rw-r--r--Completion/Zsh/Function/_zsh-mime-handler9
-rw-r--r--Doc/Zsh/contrib.yo8
-rw-r--r--Functions/MIME/zsh-mime-handler65
5 files changed, 86 insertions, 9 deletions
diff --git a/ChangeLog b/ChangeLog
index bef899a17..c08063ab1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2010-05-23  Peter Stephenson  <p.w.stephenson@ntlworld.com>
+
+	* users/15078: Completion/Zsh/Function/.distfiles,
+	Completion/Zsh/Function/_zsh-mime-handler, Doc/Zsh/contrib.yo,
+	Functions/MIME/zsh-mime-handler: completion for a
+	zsh-mime-handler should understand how the line will be handled.
+
 2010-05-22  Clint Adams  <clint@zsh.org>
 
 	* 27964: Doc/Zsh/contrib.yo: add back missing enditem().
@@ -13146,5 +13153,5 @@
 
 *****************************************************
 * This is used by the shell to define $ZSH_PATCHLEVEL
-* $Revision: 1.4980 $
+* $Revision: 1.4981 $
 *****************************************************
diff --git a/Completion/Zsh/Function/.distfiles b/Completion/Zsh/Function/.distfiles
new file mode 100644
index 000000000..3d13eb6fa
--- /dev/null
+++ b/Completion/Zsh/Function/.distfiles
@@ -0,0 +1,4 @@
+DISTFILES_SRC='
+.distfiles
+zsh-mime-handler
+'
diff --git a/Completion/Zsh/Function/_zsh-mime-handler b/Completion/Zsh/Function/_zsh-mime-handler
new file mode 100644
index 000000000..c11e5aba9
--- /dev/null
+++ b/Completion/Zsh/Function/_zsh-mime-handler
@@ -0,0 +1,9 @@
+#compdef zsh-mime-handler
+
+# zsh-mime-handler -l is supposed to print out the command line
+# with quoting to turn it into a full executable line.  So
+# we need to use shell splitting to turn it into words and
+# then unquoting on those words.
+words=(${(Q)${(z)"$(zsh-mime-handler -l ${words[2,-1]})"}})
+
+_normal
diff --git a/Doc/Zsh/contrib.yo b/Doc/Zsh/contrib.yo
index ae071c129..c512f89d9 100644
--- a/Doc/Zsh/contrib.yo
+++ b/Doc/Zsh/contrib.yo
@@ -2412,7 +2412,7 @@ startitem()
 findex(zsh-mime-setup)
 findex(zsh-mime-handler)
 xitem(tt(zsh-mime-setup) [ tt(-fv) ] [ tt(-l) [ var(suffix ...) ] ])
-item(tt(zsh-mime-handler))(
+item(tt(zsh-mime-handler [-l] var(command arguments ...)))(
 These two functions use the files tt(~/.mime.types) and tt(/etc/mime.types),
 which associate types and extensions, as well as tt(~/.mailcap) and
 tt(/etc/mailcap) files, which associate types and the programs that
@@ -2636,6 +2636,12 @@ terminal; the second flag is used if the output should be sent to a pager.
 An example of a suitable tt(mailcap) entry for such a program is:
 
 example(text/html; /usr/bin/lynx '%s'; needsterminal)
+
+Running `tt(zsh-mime-handler -l) var(command line)' prints the command
+line that would be executed, simplified to remove the effect of any
+flags, and quoted so that the output can be run as a complete zsh
+command line.  This is used by the completion system to decide how to
+complete after a file handled by tt(zsh-mime-setup).
 )
 findex(pick-web-browser)
 item(tt(pick-web-browser))(
diff --git a/Functions/MIME/zsh-mime-handler b/Functions/MIME/zsh-mime-handler
index 4f7bc1eb5..9dd9cca4d 100644
--- a/Functions/MIME/zsh-mime-handler
+++ b/Functions/MIME/zsh-mime-handler
@@ -34,6 +34,28 @@ setopt extendedglob cbases nullglob $autocd
 # We need zformat from zsh/zutil for %s replacement.
 zmodload -i zsh/zutil
 
+# 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.
+local opt
+integer list
+while (( $# - $OPTIND > 0 )); do
+  if getopts "l" opt; then
+    case $opt in
+      (l)
+      list=1
+      ;;
+
+      (*)
+      return 1
+      ;;
+    esac
+  else
+    break
+  fi
+done
+shift $(( OPTIND - 1 ))
+
 # Always called with a filename argument first.
 # There might be other arguments; don't really know what to do
 # with these, but if they came from e.g. `*.ps' then we might
@@ -47,7 +69,8 @@ local -a match mbegin mend
 suffix=${(L)match[1]}
 context=":mime:.${suffix}:"
 
-local handler flags no_sh no_bg
+local handler flags no_sh no_bg arg
+integer i
 local -a exec_asis hand_nonex
 
 # Set to a list of patterns which are ignored and executed as they are,
@@ -94,7 +117,20 @@ fi
 for pattern in $exec_asis; do
   files=(${dirpref}${~pattern})
   if [[ -n ${files[(r)$1]} ]]; then
-    "$@"
+    if (( list )); then
+      for (( i = 1; i <= $#; i++ )); do
+	(( i == 1 )) || print -n " "
+	arg=${argv[i]}
+	if [[ -n $arg ]]; then
+	  print -rn -- ${(q)arg}
+	else
+	  print "''"
+	fi
+      done
+      print
+    else
+      "$@"
+    fi
     return
   fi
 done
@@ -152,12 +188,13 @@ if [[ $handler = *%s* ]]; then
       # Probably we ought not even to handle multiple
       # arguments, but at least the error message ought
       # to make it obvious what's going on.
-      zformat -f command $handler s:"$argv"
+      zformat -f command $handler s:"$argv[0]"
     else
-      files=(${(q)argv})
-      zformat -f command $handler s:"$files"
+      zformat -f command $handler s:"${(q)argv[0]}"
     fi
-    if [[ $no_sh = yes ]]; then
+    if (( list )); then
+      execargs=(${(Q)${(z)command}} ${argv[1,-1]})
+    elif [[ $no_sh = yes ]]; then
       execargs=(eval $command)
     else
       execargs=(sh -c $command)
@@ -174,13 +211,27 @@ if [[ $handler = *%s* ]]; then
 else
   # If there's no %s, the input is supposed to come from stdin.
   stdin=1
-  if [[ -n $hasmeta && $no_sh != yes ]]; then
+  if [[ -n $hasmeta && $no_sh != yes && list -eq 0 ]]; then
     execargs=(sh -c "$handler")
   else
     execargs=(${=handler})
   fi
 fi
 
+if (( list )); then
+  for (( i = 1; i <= ${#execargs}; i++ )); do
+    (( i == 1 )) || print -n " "
+    arg=${execargs[i]}
+    if [[ -n $arg ]]; then
+      print -rn -- ${(q)arg}
+    else
+      print -n "''"
+    fi
+  done
+  print
+  return 0
+fi
+
 # Now execute the command in the appropriate fashion.
 if [[ $flags = *copiousoutput* ]]; then
   # We need to page the output.