Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Bug in zparseopts -G?




On 9/4/2025 9:46 AM, dana wrote:
On Thu 4 Sep 2025, at 08:20, Clinton Bunch wrote:
There seems to be a discrepancy in how zparseopts -G handles ~ paths.

--option ~/path and --option=~/path are not equivalent.  In the first
the tilde is expanded (probably as part of the shell's parsing before it
gets to zparseopts) in the second it isn't.
it's not an issue with zparseopts, it's just how tilde expansion works:
I get it's how tilde expansion works, once I saw it I knew what was happening, but it remains (at least IMHO) unexpected behavior when -G is supposed to make command line parsing  behave like other programs with long options.

**Each word is checked to see if it begins with an unquoted ‘~’.** If
it does, then the word up to a ‘/’, or the end of the word if there is
no ‘/’, is checked to see if it can be substituted in one of the ways
described here. If so, then the ‘~’ and the checked portion are
replaced with the appropriate substitute value.
the word --option=~/path does not begin with a ~

you can change this behaviour by enabling magic_equal_subst:

How many script users are going to expect that, though?  And know that what they need is magic_equal_subst?  Would setting the option just before zparseopts in the script fix it? (I'm not currently at a zsh prompt to try).  If not, perhaps -G should act as though magic_equal_subst were in force while processing options.

I contend end users are going to expect any script using --option=~/path to expand the tilde regardless if they have magic_equal_subst set in their shell or not.  So either the script writer is going to need to know to set a shell option (I worked on this for over an hour last night and never thought to check the manual for shell options, I was looking at parameter expansion and later filename generation.) or zparseopts needs to do it "out of the box".


All unquoted arguments of the form ‘anything=expression’ appearing
after the command name have filename expansion (that is, where
expression has a leading ‘~’ or ‘=’) performed on expression as if it
were a parameter assignment. The argument is not otherwise treated
specially; it is passed to the command as a single argument, and not
used as an actual parameter assignment. For example, in echo
foo=~/bar:~/rod, both occurrences of ~ would be replaced. Note that
this happens anyway with typeset and similar statements.
   % print -r - --option=~/path
   --option=~/path

   % setopt magic_equal_subst
   % print -r - --option=~/path
   --option=/Users/dana/path

dana





Messages sorted by: Reverse Date, Date, Thread, Author