On Wed, 19 May 2010 13:37:04 +0000 Clint Adams <sch...@debian.org> wrote: > On Wed, May 19, 2010 at 05:18:59PM +0400, Nikolay A. Panov wrote: > > Using zsh-mime-setup I have no completions for, say, django: > > > > $ zsh -f > > laptop% autoload -U compinit;compinit > > laptop% ./manage.py > > tags in context :completion::complete:manage.py:: > > argument-1 options (_arguments _django (eval)) > > subcommands (_describe _django (eval)) > > You could do `unalias -s py' to get your manage.py completion back.
"alias -s py=python" would also work around the problem without creating any new symptoms---this makes python execute the file directly, instead of via zsh-mime-handler, and the python completion function is smart enough to know about looking for completion for scripts. However, it ought to be able to work without you doing that. The problem is that the alias gets expanded to zsh-mime-handler ./manage.py <completing here> (I'm guessing---you don't say specifically but this is the obvious thing the MIME system would do that would confuse completion without screwing up execution) and there's no special zsh-mime-handler completion function. There should be one that translates the command line into what would be executed by the handler and then completes based on that. I think the following does the basics. I'm sure you'll let me know politely if it doesn't. Index: Completion/Zsh/Function/.distfiles =================================================================== RCS file: Completion/Zsh/Function/.distfiles diff -N Completion/Zsh/Function/.distfiles --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ Completion/Zsh/Function/.distfiles 23 May 2010 19:23:31 -0000 @@ -0,0 +1,4 @@ +DISTFILES_SRC=' +.distfiles +zsh-mime-handler +' Index: Completion/Zsh/Function/_zsh-mime-handler =================================================================== RCS file: Completion/Zsh/Function/_zsh-mime-handler diff -N Completion/Zsh/Function/_zsh-mime-handler --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ Completion/Zsh/Function/_zsh-mime-handler 23 May 2010 19:23:31 -0000 @@ -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 Index: Doc/Zsh/contrib.yo =================================================================== RCS file: /cvsroot/zsh/zsh/Doc/Zsh/contrib.yo,v retrieving revision 1.114 diff -p -u -r1.114 contrib.yo --- Doc/Zsh/contrib.yo 14 May 2010 07:58:37 -0000 1.114 +++ Doc/Zsh/contrib.yo 23 May 2010 19:23:32 -0000 @@ -2411,7 +2411,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 @@ -2635,6 +2635,12 @@ terminal; the second flag is used if the 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))( Index: Functions/MIME/zsh-mime-handler =================================================================== RCS file: /cvsroot/zsh/zsh/Functions/MIME/zsh-mime-handler,v retrieving revision 1.11 diff -p -u -r1.11 zsh-mime-handler --- Functions/MIME/zsh-mime-handler 20 Nov 2008 18:12:32 -0000 1.11 +++ Functions/MIME/zsh-mime-handler 23 May 2010 19:23:32 -0000 @@ -34,6 +34,28 @@ setopt extendedglob cbases nullglob $aut # 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. -- Peter Stephenson <p.w.stephen...@ntlworld.com> Web page now at http://homepage.ntlworld.com/p.w.stephenson/ -- To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org