Subject: Re: [PATCH] _describe and literal \n
From: Daniel Shahaf <[email-masked]>
To: Oliver Kiddle <[email-masked]>
Cc: [email-masked]
Date: Sun, 24 Jul 2016 21:30:46 +0000
List-Id: Zsh Workers List <zsh-workers.zsh.org>

Oliver Kiddle wrote on Sun, Jul 24, 2016 at 01:27:08 +0200:
> Daniel Shahaf wrote:
> > I haven't been able to get menu selection's highlighting to misbehave.
> >
> > However, consider this:
> >
> > Current master:
> >     % _f() { a=( $'foo:hello\nworld' $'bar:lorem\nipsum' $'baz:lorem\nipsum' ); _describe descr a }
> >     % f <TAB>
> >     baz  
> >     foo  -- lorem\nipsum
> >     bar  -- hello\nworld
> 
> Is your fix to the internals of _describe or the more general code.

The former: the patch is to cd_init(), which is guts of compdescribe,
which in turn is only used by the _describe function.

> Note that _describe truncates descriptions [...]

I see truncation with 
.
    a=( foo:"$(yes | head -150 | xargs)" bar:"$(yes n | head -150 | xargs)" )
    _describe descr a
.
but not if I remove the |xargs.  The only difference between the two
cases is whether the y's/n's are separated by spaces or newlines.

> I'm not especially fond of the \n escapes. Would prefer they were mapped
> to spaces. However, failing to group baz and foo is clearly wrong.
> 

While the patch adds one case where a newline is escaped as \n, the
incumbent code in master already uses that same escaping in another
situation.

> It could be worth experimenting with long strings that approach the
> right edge of the terminal to see if it is affecting the calculations.

I've found a problem, however, I'm not sure whether it's compdescribe's
fault.  Reproducer:

$ zsh -f
% autoload compinit
% compinit
% zstyle ':completion:*' completer _all_matches _match _expand _complete _ignored
% zstyle -e :completion:\* list-colors 'reply=( "=(#b)(${(b)PREFIX})(?)([^ ]#)*=0=33=34=33" )'
% zstyle ':completion:*' menu 'select=long-list' 'select=3'
% pad=${(r:3*COLUMNS::x :):-}
% _f() { a=( foo:$'fff\nfff'$pad bar:$'ggg\nggg'$pad ); _describe descr a }
% compdef _f f
% f <TAB><TAB><TAB><TAB><TAB>

This garbles the display, it shows a «ba» in reverse video and is offset
one line too far down.  Tabbing further keeps moving it down, eventually
I get lines as though by `repeat $N print -rP -- "%Sba%sf bar foo"`.

Or if you meant, to check whether the patch _break_ some width
calculation, I think that's unlikely: the patch escapes the description
value as soon as it's parsed out of the user-specified $foo:$bar value
into the ->desc struct member, in the (as far as I can tell) only
place that parsing is done.

Cheers,

Daniel
(let me know if I should push the patch I'd posted)