Lately a bunch of programming-oriented fonts have added ligatures, especially for operators. For example, take a look at Fira Code and JetBrains Mono. To be honest, I’m not sure what I think of the ligatures, but I’d still like to be able to use the fonts. The problem is that GNOME Terminal makes a mess of the ligatures, for example here’s JetBrains Mono:
One option is to use a terminal emulator that supports ligatures. Another option is to find a forked font that disables ligatures. For Fira Code, that’s especially easy because it was forked from Fira Mono specifically to add ligatures!
A third option is to disable the ligatures in GNOME Terminal, instead of disabling them in the font. This is good for JetBrains Mono, which comes with ligatures in the upstream build, and it would be nice to avoid forking the font.
GNOME Terminal uses
fontconfig under the
hood, so the file we need to change is
is a configuration that recognizes GNOME Terminal, then disables the OpenType
related to ligatures:
<?xml version='1.0'?> <!DOCTYPE fontconfig SYSTEM 'fonts.dtd'> <fontconfig> <match> <test name="prgname" compare="contains"> <string>gnome-terminal</string> </test> <edit name="fontfeatures" mode="append"> <string>calt off</string> <string>clig off</string> <string>dlig off</string> <string>liga off</string> </edit> </match> </fontconfig>
Here’s JetBrains Mono with ligatures disabled:
Matching GNOME Terminal in fonts.conf
You might have noticed the config snippet uses
<test name="prgname" compare="contains"> <string>gnome-terminal</string> </test>
It took me a little while to figure out the right test to use here. I had worked
out how to disable the ligatures with OpenType feature flags, but I wanted to
constrain that to GNOME Terminal instead of affecting other programs. Originally
compare="eq" but it wasn’t recognizing.
$ FC_DEBUG=5 /usr/libexec/gnome-terminal-server \ --app-id=my.foo.Terminal &> out &
Next, I ran the client. The interesting stuff happens in the server, but it doesn’t happen until the client connects:
$ gnome-terminal --app-id=my.foo.Terminal
Finally, I found lots of this in the captured output:
The program name is “gnome-terminal-server,” so “contains gnome-terminal” does the trick.
If you’re curious, here’s my full fonts.conf.