help-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Help-bash] Expand a prompt string to calculate its length?


From: Andy Chu
Subject: Re: [Help-bash] Expand a prompt string to calculate its length?
Date: Wed, 19 Jun 2019 12:40:41 -0700

On Wed, Jun 19, 2019 at 12:29 PM Greg Wooledge <address@hidden> wrote:
>
> On Wed, Jun 19, 2019 at 11:57:28AM -0700, Andy Chu wrote:
> > 1. colors and ANSI (compensated for by \[ and \] as mentioned)
> >
> > 2. Unicode characters.  All shells appear use wcwidth() or some
> > variant to compute this.
> >
> >  http://man7.org/linux/man-pages/man3/wcwidth.3.html
> >
> > So depending on the complexity of the prompt, there are 2 issues to 
> > overcome.
> >
> > AFAIK there's not an easy pure-bash solution for either problem, short
> > of reimplementing PS1, which is probably technically possible in bash
> > but something you don't want to do.  I did this when implementing
> > bash-compatible prompts for Oil [1].
>
> The @P operator in bash 4.4 overcomes the first, and bash itself already
> handles the second.
>
> wooledg:~$ shopt -s extglob
> wooledg:~$ glob=$'\x01*([!\x02])\x02'
> wooledg:~$ NOTPS1='foo\[xyz\]сд'
> wooledg:~$ tmp=${NOTPS1@P}; tmp2=${tmp//$glob/}
> wooledg:~$ echo "<$tmp> <${#tmp}> <$tmp2> <${#tmp2}>"
> <fooxyzсд> <10> <fooсд> <5>
>
> I didn't test with characters outside the Unicode BMP, but this case
> seems to work.  Note that the <$tmp> piece actually contains two
> invisible characters (01 and 02), hence the length of 10.  <$tmp2>
> contains 3 ASCII characters and 2 UTF-8 characters, and is counted with
> a length of 5.
>
> Is it pretty?  No.  But it's not totally ridiculous.

IIRC, bash counts Unicode code points with ${#s} (e.g. it will decode
UTF-8).  But that is different than the display width.  I think you
need the concept of "graphemes" for that.

That is, there are 2 problems in Unicode:

# bytes != # code points
# code points != display width.

i.e. every code point doesn't take the same number of pixels to draw.

If I spent the time I could probably come with an example to
illustrate this ... however most likely I will wait for someone to
complain about it in Oil before investigating further.  (Oil doesn't
use wcwidth() yet)

Of course, this may or may not matter for a particular use case....
just being pedantic as is the custom here :)

Andy



reply via email to

[Prev in Thread] Current Thread [Next in Thread]