Subject: Re: Parameter + prompt expansion %D{%T.%.} parser issue
From: Bart Schaefer <[email-masked]>
To: Roland Eggner <[email-masked]>, zsh workers <[email-masked]>
Date: Mon, 18 Jul 2016 20:48:15 -0700
List-Id: Zsh Workers List <zsh-workers.zsh.org>

On Jul 19,  2:21am, Mikael Magnusson wrote:
} Subject: Re: Parameter + prompt expansion %D{%T.%.} parser issue
}
} On Mon, Jul 18, 2016 at 10:31 PM, Roland Eggner
} <[email-masked]> wrote:
} > emulate -R zsh -c 'print -l ${(%):-%D{%T.%.} %~} "${(%):-%D{%T.%.} %~}" ${(%):-"%D{%T.%.} %~"}'
} >
} > Observed:
} > 22:03:02.324 ~
} > 22:03:02.324 %~}
} > 22:03:02.324 ~
} >
} > Usage error?  Bug?  Feature?
} 
} Usage error, but it's kind of hard to understand what's going on there
} admittedly. When ${} is unquoted, then the parser "knows" which {}
} belong together

That's not quite right either.

You can get a better idea what's happening this way:

torch% setopt ignorebraces
torch% print -l ${(%):-%D{%T.%.} %~} "${(%):-%D{%T.%.} %~}" ${(%):-"%D{%T.%.} %~"}
20:33:34.148
%~}
20:33:34.148 %~}
20:33:34.148 ~

In the first (unquoted) case, with the default setopts (no_ignorebraces),
the substring {%T.%.} is parsed like a brace expansion, but then does not
expand because there are no commas.  So it's accidental that it works the
way expected.  With ignorebraces you see parameter expansion end at the
first close brace, leaving %~} to split into another argument to print.

The third form with the part after :- in quotes is really the only right
way, particularly given the space before %~.  Note that with parameter
expansions in all but the most antiquated versions of the shell you can
actually nest double quotes:

    print "${(%):-"%D{%T.%.} %~"}"