pkgsrc-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: pkg/58875: python: terminal colours broke in some applications
The following reply was made to PR pkg/58875; it has been noted by GNATS.
From: Taylor R Campbell <riastradh%NetBSD.org@localhost>
To: Christos Zoulas <christos%zoulas.com@localhost>
Cc: gnats-bugs%NetBSD.org@localhost, pkgsrc-bugs%NetBSD.org@localhost,
Aleksey Cheusov <cheusov%NetBSD.org@localhost>,
Christos Zoulas <christos%NetBSD.org@localhost>, Jonathan Perkin <jperkin%mnx.io@localhost>
Subject: Re: pkg/58875: python: terminal colours broke in some applications
Date: Thu, 5 Dec 2024 17:44:37 +0000
> Date: Thu, 05 Dec 2024 11:36:23 -0500
> From: Christos Zoulas <christos%zoulas.com@localhost>
>=20
> On 2024-12-05 10:29 am, Taylor R Campbell wrote:
> > The attached patch resolves the problem by using libreadline
> > unconditionally. Maybe in the future if libedit is changed to support
> > colours (which christos tells me it does not right now) we can put the
> > option back, but until then I think we should have applications work
> > out of the box.
>=20
> I think it does support colors in the same way readline does according=20
> to this:
> https://wiki.hackzine.org/development/misc/readline-color-prompt.html
Interesting. If I patch Mercurial to surround the prompt by \001 and
\002, the prompt comes out just fine with libedit and libreadline:
diff -r 47eacd67ce16 mercurial/ui.py
--- a/mercurial/ui.py Thu Dec 05 13:48:22 2024 +0000
+++ b/mercurial/ui.py Thu Dec 05 17:18:57 2024 +0000
@@ -1745,7 +1745,7 @@
self.flush()
prompt =3D b' '
else:
- prompt =3D self.label(prompt, b'ui.prompt') + b' '
+ prompt =3D b'\001' + self.label(prompt, b'ui.prompt') + b'\002=
' + b' '
=20
# prompt ' ' must exist; otherwise readline may delete entire line
# - http://bugs.python.org/issue12833
But these are not required by libreadline.
It looks like the difference is that libedit simply discards wide
characters with wcwidth <=3D 0, like ESC:
85 w =3D wcwidth(end[1]); /* column width of the visible char */
86 *wp =3D (int)w;
87=20
88 if (w <=3D 0) /* we require something to be printed */
89 return 0;
...
100 for (n =3D 0, i =3D 0; i < len; i++)
101 n +=3D ct_encode_char(b + n, (size_t)(w - n), buf[i]);
102 n +=3D ct_encode_char(b + n, (size_t)(w - n), end[1]);
103 b[n] =3D '\0';
https://nxr.netbsd.org/xref/src/lib/libedit/literal.c?r=3D1.5#85
In contrast, I think libreadline preserves them, and just calculates
the column widths differently. (The logic in
https://git.savannah.gnu.org/cgit/readline.git/tree/display.c?h=3Dreadline-=
8.2&id=3Df7a382fd09319b20ef4435b9b554183b605468c1
is a lot more complicated, though, and I haven't stepped through it
carefully.)
On the one hand, it might be appropriate for Mercurial to use \001 and
\002 around any terminal-specific escape sequences it uses that take
up zero width -- particularly since, without that, readline might
compute the column widths wrong for strings like "\033[0;33m", where
it will treat the "\033" part as zero-width but the "[0;33m" as
nonzero-width.
On the other hand, I don't think Python really exposes this reasonably
as part of the documented and reliable builtin input() or readline
semantics. (There are macros RL_PROMPT_START/END_IGNORE in readline.h
but Python doesn't expose them. It's hard to search for applications
that handle this because what am I going to search for, the text
`\001' or `\x01' or something?) And what libedit is doing here isn't
quite the same as libreadline, so there is a compatibility issue.
So my inclination is still to switch back to unconditional libreadline
until we've had more time to digest this -- after the branch.
Home |
Main Index |
Thread Index |
Old Index