Re: [PATCH] emoji on TUI emacs

Eli Zaretskii <[email protected]>
Newsgroups gmane.emacs.devel
Message-ID <[email protected]>
> From: Kai Ma <[email protected]>
> Cc: [email protected]
> Date: Fri, 21 Aug 2026 02:51:29 +0200
> 
> Thanks for the review.  I've updated the patches according to the comments.

Thanks.  TL;DR: I installed these changes on the master branch.  Thank
you for all your work on this important improvement.

> >> -      cmp_it->width = 0;
> >> +      cmp_it->width = composition_gstring_width (gstring, cmp_it->from, cmp_it->to, NULL);
> >> +
> >>        for (i = cmp_it->nchars - 1; i >= 0; i--)
> >>  	{
> >>  	  c = XFIXNUM (LGSTRING_CHAR (gstring, from + i));
> >>  	  cmp_it->nbytes += CHAR_BYTES (c);
> >> -	  cmp_it->width += CHARACTER_WIDTH (c);
> >>  	}
> >>      }
> >>    return c;
> >
> >
> > Hmmm... is this guaranteed to produce correct results for both Emoji
> > and non-Emoji compositions?  Did you verify we are not breaking
> > anything here, for example with compositions like 'a' followed by an
> > accent?
> 
> Yes, they work for me.
> 
> > It would help if you could talk me through the code and
> > explain how what composition_gstring_width does is equivalent to
> > summing CHARACTER_WIDTH for TTY frames, in cases other than Emoji.  We
> > need to convince ourselves that we don't introduce regressions here.
> > If we are not sure, perhaps special-casing Emoji would be safer.
> 
> They should be equal for ordinary non-Emoji compositions (those in the
> form of {BASE} {MODIFIER}+):
> 
>   before the change: cmp_it->width = base-char-width + 0 + 0 ...
>                      (modifier-width = 0)
> 
>   after the change:  cmp_it->width = base-glyph-width + 0 + 0 ...
>                      (modifier-width = 0)
> 
> I think the reason why it works for TTY frames is that
> compose-gstring-terminal tries to extend the gstring as long as the next
> glyph has width 0.  Therefore, for the ordinary cases, it should usually
> be in the expected form.

Looking closer at the code, I think this indeed works correctly
because on TTY frames, the GLYPHs in the gstring object are actually
character codes, and LGLYPH_WIDTH accesses the values produced by
LGLYPH_SET_WIDTH, which were taken from char-width-table.  So we are
okay here, I think.

> Curiously, I found two exceptions during this testing,
> 
> U+061B ARABIC SEMICOLON
> U+06DE ARABIC START OF RUB EL HIZB
> 
>   (currently both (char-width ?\x061B) and (string-width "\x061B") are 0)
> 
> Both have visual appearance, their East_Asian_Width is Neutral and their
> canonical-combining-class is 0, so I think they should have width 1, so
> as to prevent them from being composed unexpectedly.  I updated Patch 1
> to correct them.  After this change, they work fine for me.  But I don't
> know Arabic, so I might be wrong here.

No, those were (unrelated) bugs in characters.el, so fixing them is
TRT.

> >> * admin/unidata/Makefile.in: Changed.
> >
> > This should describe the change.
> 
> Fixed.
> 
> >> * src/composite.c (composition_update_it): set the width of an automatic
> >> composition using composition_gstring_width.
> >
> > The description of the change should begin with a capital letter
> > ("Set", not "set").
> 
> Fixed.

The log messages are now okay, with a single nit: the first (heading)
line should NOT end in a period, except if it's the _only_ line in the
log message.  (I've removed them when I installed these patches, but
please remember this for the future.)

> > After fixing these two problems, I still see some incorrect
> > compositions in the various admin/unidata/emoji-*.txt files.  First,
> > cursor movement through Emoji sequences around line 3600 of
> > emoji-test.txt is wrong: it seems that the terminal thinks the "heart"
> > Emoji is two separate characters, or that its width is not 2.
> 
> Indeed.  This is due to emoji-zwj.awk only generating composition rules
> from emoji-zwj-sequences.txt, which only contains fully-qualified RGI
> sequences.  I've updated the patches to also generate composition rules
> for both minimally-qualified and unqualified RGI sequences from
> emoji-test.txt.  This should be correct according to the file header:
> 
>  • The listed minimally-qualified and unqualified cover all cases where
>    an element of the RGI set is missing one or more emoji presentation
>    selectors.
> 
> > The second problem is with the Keycap sequences around line 550 of
> > emoji-sequences: it seems Emacs is not composing these sequences for
> > some reason?  Do you see this on your terminal?
> 
> Should be fixed now.  It was because I added all codepoints in
> auto-composition-emoji-tty-eligible-codepoints to 'ch' in emoji-zwj.awk.
> The problem is that auto-composition-emoji-tty-eligible-codepoints
> contains initial codepoints of keycap sequences, and then 'ch' generated
> composition rules like 002A FE0F, which took priority over
> 002A FE0F 20E3.

These two issues are now fixed.

I should add that PuTTY has some problems with emoji-sequences.txt
around line 1140, and setting tty-display-emoji-force-wide to nil
doesn't help.  Also with emoji-zwj-sequences.txt.  I guess this is a
PuTTY problem (or maybe I need to upgrade to a newer version of
PuTTY?).

> > Apart of the above two issues, the display seems correct, which is a
> > nice improvement.
> 
> Thanks.  Hopefully the updated patches make it even nicer.

They are, thanks.  It would be interesting to hear feedback for the
various emulators out there.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.