* Advanced option parsing across zsh commands @ 2016-01-26 9:20 Sebastian Gniazdowski 2016-01-26 18:28 ` Bart Schaefer 0 siblings, 1 reply; 6+ messages in thread From: Sebastian Gniazdowski @ 2016-01-26 9:20 UTC (permalink / raw) To: Zsh hackers list Hello, This will bind to current keymap, not to "a": % bindkey -N a main % bindkey -s '^[t' 'echo test' -M a I like zparseopts because of -E option, which allows to mix options with strings and handles --. Is it expected that one day zsh will do the same? It's a matter of providing one well written options parsing function, isn't it. That said, following zparseopts apparently fails: % set -- a -b something -- -c % typeset -A opts % zparseopts -A opts -DE b: c % echo "${(kv)opts}" % # $1, $2, ... $5 are still the same I once (12 years ago) used zparseopts this way and it worked great. The call had to be different then. Best regards, Sebastian Gniazdowski ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Advanced option parsing across zsh commands 2016-01-26 9:20 Advanced option parsing across zsh commands Sebastian Gniazdowski @ 2016-01-26 18:28 ` Bart Schaefer 2016-01-26 18:59 ` Sebastian Gniazdowski 0 siblings, 1 reply; 6+ messages in thread From: Bart Schaefer @ 2016-01-26 18:28 UTC (permalink / raw) To: Zsh hackers list On Jan 26, 10:20am, Sebastian Gniazdowski wrote: } Subject: Advanced option parsing across zsh commands } } I like zparseopts because of -E option, which allows to mix options } with strings and handles --. Is it expected that one day zsh will do } the same? No, this is not expected. } % set -- a -b something -- -c } % typeset -A opts } % zparseopts -A opts -DE b: c } % echo "${(kv)opts}" } } % # $1, $2, ... $5 are still the same You can't stack the options of zparseopts itself, i.e, you can't use -DE, you have to use -D -E. zparseopts also doesn't handle "negated options" in the +X format, only those introduced with "-". There's a fairly convoluted issue with making "+" work for the associative array case because of the way zparseopts gathers up the arguments of each option before assigning to the array. ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Advanced option parsing across zsh commands 2016-01-26 18:28 ` Bart Schaefer @ 2016-01-26 18:59 ` Sebastian Gniazdowski 2016-01-26 19:09 ` Sebastian Gniazdowski 2016-01-27 6:56 ` Bart Schaefer 0 siblings, 2 replies; 6+ messages in thread From: Sebastian Gniazdowski @ 2016-01-26 18:59 UTC (permalink / raw) To: Bart Schaefer; +Cc: Zsh hackers list On 26 January 2016 at 19:28, Bart Schaefer <schaefer@brasslantern.com> wrote: > } % set -- a -b something -- -c > } % typeset -A opts > } % zparseopts -A opts -DE b: c > } % echo "${(kv)opts}" > } > } % # $1, $2, ... $5 are still the same > > You can't stack the options of zparseopts itself, i.e, you can't use -DE, > you have to use -D -E. Thanks, this works > zparseopts also doesn't handle "negated options" in the +X format, only > those introduced with "-". There's a fairly convoluted issue with making > "+" work for the associative array case because of the way zparseopts > gathers up the arguments of each option before assigning to the array. This sounded like if there would a workaround for +X. I tried the following: define option "+", which takes argument. Then replace "+X" with "-+X" in the command line. However: % unset opts % typeset -A opts % set -- a -b something -+X -- -c % zparseopts -A opts -D -E b: c +: % echo "${(k)opts}" % echo "${(v)opts}" b+X Weird, isn't it? With also a regular array: % unset opts % unset optsa % typeset -A opts % typeset -a optsa % set -- a -b something -+X -- -c % zparseopts -a optsa -A opts -D -E b: c +: % echo ${(k)opts} % echo ${(v)opts} b+X % echo $optsa b - +X With only regular array it's the same Best regards, Sebastian Gniazdowski ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Advanced option parsing across zsh commands 2016-01-26 18:59 ` Sebastian Gniazdowski @ 2016-01-26 19:09 ` Sebastian Gniazdowski 2016-01-27 7:07 ` Bart Schaefer 2016-01-27 6:56 ` Bart Schaefer 1 sibling, 1 reply; 6+ messages in thread From: Sebastian Gniazdowski @ 2016-01-26 19:09 UTC (permalink / raw) To: Bart Schaefer; +Cc: Zsh hackers list Here is how it works if order of option specification is changed: % unset opts % unset optsa % typeset -A opts % typeset -a optsa % set -- a -b something -+X -- -c % zparseopts -a optsa -A opts -D -E +: b: c % echo "${(k)opts}" -b - % echo "${(v)opts}" something +X % echo "${opts[-]}" +X % echo $optsa -b something - +X That's quite a work around, but I wonder what's going on internally? Tested (the previous runs too) on 5.2 Best regards, Sebastian Gniazdowski ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Advanced option parsing across zsh commands 2016-01-26 19:09 ` Sebastian Gniazdowski @ 2016-01-27 7:07 ` Bart Schaefer 0 siblings, 0 replies; 6+ messages in thread From: Bart Schaefer @ 2016-01-27 7:07 UTC (permalink / raw) To: Zsh hackers list On Jan 26, 8:09pm, Sebastian Gniazdowski wrote: } } Here is how it works if order of option specification is changed: } } % zparseopts -a optsa -A opts -D -E +: b: c All you've done there is manage to get the empty-string option to be tested after any of the others (the specs are tested against $argv in reverse of the order they appear as zparseopts arguments). It's almost certainly coincidental that this created options that seem to be named "-" and assigned "+X" as the value; this effect no longer occurs with my patch from 37810, and is probably not reliable with any zsh prior to that patch. ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Advanced option parsing across zsh commands 2016-01-26 18:59 ` Sebastian Gniazdowski 2016-01-26 19:09 ` Sebastian Gniazdowski @ 2016-01-27 6:56 ` Bart Schaefer 1 sibling, 0 replies; 6+ messages in thread From: Bart Schaefer @ 2016-01-27 6:56 UTC (permalink / raw) To: Zsh hackers list On Jan 26, 7:59pm, Sebastian Gniazdowski wrote: } Subject: Re: Advanced option parsing across zsh commands } } > zparseopts also doesn't handle "negated options" in the +X format } } This sounded like if there would a workaround for +X. I tried the } following: define option "+", which takes argument. Then replace "+X" } with "-+X" in the command line. However: } } % zparseopts -A opts -D -E b: c +: That does not define an option "+" which takes an argument. That in fact defines an option (empty string) which may be repeated multiple times and takes an argument, because the "+" invokes the NAME+ form of option description. There's not a lot of internal consistency checking in zparseopts. Old code that has not been reviewed since it was written. To define an option named "+" instead of an option named "", you are intended to use: zparseopts -A opts -D -E b: c '\+:' However, because of a bug, you can't actually do that. The backslash causes everything after it to shift one character to the left, but the NUL-terminator is not also shifted, so the above accidentally defines the option "++" instead of the option "+". torch% typeset -A opts torch% set -- a -b something -++X -- -c torch% zparseopts -A opts -D -E b: c \\+: torch% print -lr -- $@ a -- -c torch% print -r -- ${(kv)opts} -b something -++ X torch% With the patch below, the very first character of the option spec is always taken to be part of the option name (unless that first char is is a backslash, in which case it is shifted off as usual). So you no longer need to escape a "+" (though it doesn't hurt to do so): torch% typeset -A opts torch% set -- a -b something -+X -- -c torch% zparseopts -A opts -D -E b: c +: torch% print -r -- ${(kv)opts} -b something -+ X And using "++" does the expected thing: torch% typeset -A opts=() torch% set -- a -b something -+X -+Y -+Z -- -c torch% zparseopts -A opts -D -E b: c ++: torch% print -r -- ${(kv)opts} -b something -+ XYZ torch% For pre-5.3 zsh I suggest you use a different character than "+" for your proposed workaround, e.g. set -- a -b something -\*X -\*Y -\*Z -- -c zparseopts -A opts -D -E b: c '*+:' should work. diff --git a/Src/Modules/zutil.c b/Src/Modules/zutil.c index d98028a..12a4c03 100644 --- a/Src/Modules/zutil.c +++ b/Src/Modules/zutil.c @@ -1745,13 +1745,15 @@ bin_zparseopts(char *nam, char **args, UNUSED(Options ops), UNUSED(int func)) for (p = o; *p; p++) { if (*p == '\\' && p[1]) p++; - else if (*p == '+') { - f |= ZOF_MULT; - *p = '\0'; - p++; - break; - } else if (*p == ':' || *p == '=') - break; + else if (p > o) { /* At least one character of option name */ + if (*p == '+') { + f |= ZOF_MULT; + *p = '\0'; + p++; + break; + } else if (*p == ':' || *p == '=') + break; + } } if (*p == ':') { f |= ZOF_ARG; @@ -1789,6 +1791,7 @@ bin_zparseopts(char *nam, char **args, UNUSED(Options ops), UNUSED(int func)) p++; *n++ = *p; } + *n = '\0'; if (get_opt_desc(o)) { zwarnnam(nam, "option defined more than once: %s", o); return 1; ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2016-01-27 7:06 UTC | newest] Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2016-01-26 9:20 Advanced option parsing across zsh commands Sebastian Gniazdowski 2016-01-26 18:28 ` Bart Schaefer 2016-01-26 18:59 ` Sebastian Gniazdowski 2016-01-26 19:09 ` Sebastian Gniazdowski 2016-01-27 7:07 ` Bart Schaefer 2016-01-27 6:56 ` Bart Schaefer
Code repositories for project(s) associated with this public inbox https://git.vuxu.org/mirror/zsh/ This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).