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

Re: issues when coloring only descriptions in menu list

On Apr 17,  1:12pm, Bart Schaefer wrote:
} This demonstrates what is going on:

Apparently I should have explained a bit more thoroughly.

The tl;dr of this is that the list-colors patterns have to be able to
properly color completions (alone), descriptions (alone but with lots
of trailing whitespace), or single lines consisting of a completion
followed by a description.  This can be done either by using more than
one pattern or by clever use of backreferences.

Read on for too much detail.

}     _a () {
}       _arguments \
} 	{--first,-f}'[first should be red]' \
} 	'--barXXfoo[watch what happens here]' \
} 	'--second[second should be red]'
}     }

The list-colors style is documented as using a pattern that is matched
against the "display strings" in the completion listing.  However, what
exactly constitutes a "display string" is not well-described.

Given the above call to _arguments, when TAB is pressed after a single
hyphen ("a -") the following display elements (I'm carefully not yet
naming them "display strings") are generated:

    --first                     (potential completion)
    first should be red         (description of --first)
    -f                          (potential completion)
    first should be red         (description of -f)
    --barXXfoo			(etc.)
    watch what happens here
    second should be red

The descriptions are then examined to see if there are any completions
that share the same description.  If there are, those elements are to be
grouped together.  So we end up with

    --first                     (potential completion, group 1)
    -f                          (potential completion, group 1)
    first should be red         (description of group 1)
    --barXXfoo			(group 2)
    watch what happens here     (description of group 2)
    --second                    (etc.)
    second should be red

These are next examined to determine how to put them in columns.  The
result is that we need three columns, two for completions (--first and
-f appearing together) and one for descriptions.  Some lines will not
have all three columns, so the first column in those lines must be
padded to the width of the two columns in the other line to keep the
third column visually stacked.

Next it's determined how to lay these out on the screen, with the
requirement that the third column must have the list-seprator added
at the beginning.  Because of the alignment requirement for the
third column, the preceding columns in each of the other lines must
be handled separately.

Here's where we get into "display strings":  In order to solve the
alignment problem, the display is broken into seven "display strings"
corresponding to the seven elements in my second list above, and
then those are arranged in their sorted order and with appropriate
padding so that the the correct number of lines with the correct
alignment of columns is produced when the seven elements are printed,
in that order, left-to-right (wrap) left-to-right (etc.)

The third column (description) is padded on the right with spaces in
order to force wrapping to occur at the correct position.  This can be
see when colors are added (next step) by setting the background color
of the last character.

Finally the list-colors pattern is matched against each of those seven
strings.  *(XX*)(?) matches "--barXXfoo" and "XX watch what happens here"
but does not match "--first" and does not match "-f".  Then it matches
"XX first should be red", and so on.

So you get no color on the things not matched, and colors on those that
are matched.

If instead TAB is pressed after "a --", we get

    first should be red
    watch what happens here
    second should be red

There's no duplication here, so there's no need to break this up into
multiple columns.  Everything needed can be done in one line per
potential completion, just by inserting proper padding before the
list-separator.  So this is minimized to use only one "display string"
per line, "--barXXfoo  XX watch ...", "--first    XX first ..." etc.
The pattern *(XX*)(?) is then matched against those three strings and
matches all of them, with the leading * greedily consuming the first
"XX" in the "--barXXfoo" line so it's not part of the (XX*) reference
and therefore is not colored.

The latter is what I thought would be happening in both cases, when I
made my first reply.

There's an additional complication mentioned in a previous thread (I
forget whether on -workers or -users) that the complist module assumes
the default list-colors foreground+background will always be the same
as the default terminal foreground+background and so does not assert
color changes in all necessary cases when list-colors has been told to
use something else for one of those defaults.  Fortunately you're not
also tickling that one or things would be even harder to explain.

Barton E. Schaefer

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