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

Re: append to history entry?



Ray Andrews wrote on Tue, Dec 27, 2016 at 16:57:48 -0800:
> On 27/12/16 03:55 PM, Bart Schaefer wrote:
> >That's what $'...' does, but you can't ask for a C string and for
> >variable interpolation at the same time.  Well, you can, but it
> >doesn't really help. ;-)
> Indeed.  Be careful what you ask for ... I am expecting the variables
> to expand.  It's all  this backslash and 'is it one string or several
> strings' stuff.  Dunno ...  is that really different?  It just seems
> that the expansion of the variables is 'visible' for lack of a better
> word -- you expect it, it's not a gotcha the way the rest is.  For me,
> the task is to see the 'naturalness' for lack of a better word of the
> way that zsh does this:
> 
>     print -rS -- "rap ${${(q+)@}}; : ${(q-)HOST}"
> 
> ... it seems that the backslashes need protecting and reprotecting and
> yet more protecting and each stage of the protection is different from
> the last.  Couldn't we just:

Actually, there's just one escaping: instead of using «${foo}»,
use «${(q)foo}» if $foo is a scalar and «${${(q)foo}}» if it is an
array.  The - and + are cosmetic.

>     setopt protect-backslashes-thanks
>     print -S "rap $@; : $HOST"
> 
> ... it's not that the backslashes are presumed special, it's that I'd
> say we should only have to press one button once to literalise them.

Most programming languages don't work this way.

When zsh parses the line «print -S -r -- "rap $@; : $HOST"», it does not
yet know that 'print' denotes the shell builtin and that 'print -S'
re-parses its argument according to shell syntax; and even if it did, it
_still_ wouldn't necessarily be correct for zsh to automatically escape
every variable that's interpolated into the string argument at the end,
because people sometimes use variable interpolations that _must not_ be
${(q)}-escaped.

The selling point of this strategy is that the parsing of string
literals is consistent: the string literal «"rap $@; : $HOST"» always
means the same thing, regardless of what command it is an argument to;
the string literal «"foo $*"» always means '"foo" followed by the
positional arguments joined by spaces without any escaping'.  Then, if
a particular command needs quoting, it is up to the programmer to supply
the appropriate quoting.

The strategy you're describing amounts to a macro expansion language;
such languages are generally a lot more hairy than zsh.

> Is it impossible that this could be simple and intuitive?  No ordinary
> mortal would know to do what you guys showed me, one must be shown and
> even Bart and Daniel didn't get it exactly right the first time.  What
> hope do I have?

I didn't get it right, but Bart was right all along.  Anyway, the rules
are simple:

1) When using the 'print' builtin, always pass '-r --'.

2) When interpolating a variable into a string that will be parsed as
zsh code, escape that variable using ${${(q)}}.

But yes, you have to do (2) yourself.

I hope this helped...

Cheers,

Daniel

> 
> 



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