Hi Eli,

Thanks for the thorough report :-)

I raised the issue on the FiraCode repository and here's the answer:

Considering that it works literally everywhere else, it probably has something to do with Emacs

https://fonts.google.com/specimen/Fira+Code?preview.text=%3E%3E%3D

Image

On 22/03/2025 9:16 AM, Eli Zaretskii wrote:
Date: Fri, 21 Mar 2025 18:46:30 +0100
Cc: 77151@debbugs.gnu.org
From: Mattias Roux <mattias@kojin.tech>

As Mickey says when creating an issue:

 > If you're experiencing one of the following problems:
 >
 > - Emacs crashes when you use `ligature.el`;
 > - Some ligations are visually garbled, cut off, or not rendering at all;
 > - No ligations are showing at all;
 > - Weird interactions with non-ligated characters around a ligated 
character;
 >
 > Then it's very likely the issue is with **Emacs core**, and not 
`ligature.el`. This package merely interacts
 > with the Emacs text shaping engine to configure your ligature 
settings. It does not, on its own, do any sort
 > of ligation.

That's why I created this bug report but since you asked I also created 
an issue on the ligature repo: 
https://github.com/mickeynp/ligature.el/issues/59
Thanks.

Looking at what happens, I'm not sure I see a bug in Emacs here.  For
the ">>=" case (where you see no ligation), find-composition produces
the following:

  (267 270 [[#<font-object "-outline-Fira Code-regular-normal-normal-*-16-*-*-*-c-*-iso8859-1"> 62 62 61]
	    1
	    [0 0 62 1650 10 0 0 15 5 nil]
	    [1 1 62 1390 10 -8 8 15 5 nil]
	    [2 2 61 1578 10 2 8 15 5 nil]])

Whereas for the ">>==" case, where you see ligation, it produces the
following:

  (467 471 [[#<font-object "-outline-Fira Code-regular-normal-normal-*-16-*-*-*-c-*-iso8859-1"> 62 62 61 61]
	    3
	    [0 0 62 1650 10 0 0 15 5 nil]
	    [1 1 62 1469 10 -7 10 15 5 nil]
	    [2 2 61 1456 10 0 10 15 5 nil]
	    [3 3 61 1455 10 0 8 15 5 nil]])

(If you want to understand what these values mean, see the doc string
of composition-get-gstring.)

My conclusions from this are:

  . Emacs does recognize both cases as composable sequences
  . Emacs passes both sequences of characters to the shaping engine
  . The differences on display are because the shaping engine returned
    different sequences of font glyphs (the 4th element of the glyph
    vector) in each case

So the reason for this is probably in the font itself?  Maybe this
should be taken up with the developers of the fonts?  I see a very
similar behavior with Cascadia Code, so maybe these fonts assume or
require something which the particular ligatures you used violate?