Nerd Fonts 之 JetBrains Mono NoLigatures:无连字版补丁字体的选择、安装与原理
Nerd Fonts 之 JetBrains Mono NoLigatures:无连字版补丁字体的选择、安装与原理
导读
JetBrains Mono 是为开发者设计的等宽字体,而 Nerd Fonts 仓库在 patched-fonts/JetBrainsMono/ 下同时维护了保留连字(Ligatures)与移除连字(NoLigatures)两套补丁产物。本文以仓库中 patched-fonts/JetBrainsMono/NoLigatures/Regular/README.md 为骨架,系统讲解 NoLigatures 版本(版本号 2.304)的三种字体变体(Nerd Font / Nerd Font Mono / Nerd Font Propo)如何选择、如何获取、如何自行打补丁,并深入 font-patcher 的 --removeligatures 参数源码,说明"无连字"在补丁流水线中是如何被实现的。读完本文,你将能根据终端、编辑器与 GUI 场景正确选择字体文件,也能自己用仓库的补丁器复现无连字版本。
一、版本背景:NoLigatures 目录里的内容是什么
JetBrains Mono 是一款由 JetBrains 团队设计、面向开发者的等宽字体。Nerd Fonts 项目对其进行了图标补丁(patcher),并在 patched-fonts/JetBrainsMono/ 下提供了两套分支:
- patched-fonts/JetBrainsMono/Ligatures/:保留上游连字;
- patched-fonts/JetBrainsMono/NoLigatures/:本文主题,连字已被移除。
本目录对应的上游字体版本为 Version 2.304(见 NoLigatures/Regular/README.md 第 7 行)。在 NoLigatures 分支下,每个字重(Bold、BoldItalic、ExtraBold、ExtraBoldItalic、ExtraLight、ExtraLightItalic、Italic、Light、LightItalic、Medium、MediumItalic、Regular、SemiBold、SemiBoldItalic、Thin、ThinItalic)都带有各自的 OFL 许可证文本与说明 README。
以 NoLigatures/Regular/ 为例,实际产物为 48 个 TTF 文件,命名遵循 Nerd Fonts 的补丁命名规范:
JetBrainsMonoNLNerdFont-*.ttf:标准变体(NF),16 个文件;JetBrainsMonoNLNerdFontMono-*.ttf:等宽变体(NFM),16 个文件;JetBrainsMonoNLNerdFontPropo-*.ttf:比例变体(NFP),16 个文件。
文件名中的 NL 即 "No Ligatures" 的标记,用于与 Ligatures 分支下的 JetBrainsMonoNerdFont-* 系列区分。每个 TTF 都已在 src/unpatched-fonts/ 上游字体基础上合入了 Nerd Fonts 图标集。
二、TL;DR:三种字体变体怎么选
README 的 "Which font?" 一节给出了最直接的决策规则:
- 受限等宽场景(终端等):选择带
Nerd Font Mono(缩写NFM)的字体,例如JetBrainsMonoNLNerdFontMono-Regular.ttf; - 希望图标更大(通常约为普通字母的 1.5 倍宽):选择不带
Mono的Nerd Font(缩写NF),例如JetBrainsMonoNLNerdFont-Regular.ttf,大多数终端支持,但"结果可能因人而异(ymmv)"; - 比例上下文(GUI 元素、编辑演示文稿等):选择带
Nerd Font Propo(缩写NFP)的字体,例如JetBrainsMonoNLNerdFontPropo-Regular.ttf。
从命名规律可以推断,三者的核心区别在于数字与符号的步进宽度(advance width):NFM 保证所有字形严格等宽,图标被压缩为单字符宽度;NF 允许图标占更宽的空间;NFP 则将字体还原为比例宽度,更适合非等宽场景。仓库根目录的 readme.md 中对这三种变体有更完整的介绍,可作为横向参考。
三、连字(Ligatures)专题:NoLigatures 到底移除了什么
这是本 README 相对其他字型目录最有辨识度的一节,也是选择 NoLigatures 分支的核心动因。
3.1 补丁字体默认保留连字
README 明确指出:
Ligatures are generally preserved in the patched fonts.
即 Nerd Fonts 的补丁流水线默认保留上游字体的连字。历史上 Nerd Fonts v2.0.0 曾在 Nerd Font Mono 字体中关闭连字,但这一做法在 v2.1.0 起被放弃——从 patched-fonts/JetBrainsMono/NoLigatures/Regular/README.md 第 20-21 行可以看到这一版本演进的说明。因此,如果你使用支持连字的终端,通常会得到带连字的补丁字体。
3.2 NoLigatures 分支从构建层面移除连字
与"安装后在终端设置里关闭连字"不同,NoLigatures 分支是在补丁阶段直接删除连字查找表。仓库的 src/config.sample.cfg(src/config.sample.cfg)展示了实现方式:
[Config]
commandline: --removeligatures --makegroups 2
abort-mono-patch: True
[Subtables]
ligatures: [
"'dlig' Discretionary Ligatures lookup 12 contextual 0",
"'dlig' Discretionary Ligatures lookup 11 subtable",
"'dlig' Discretionary Ligatures lookup 9 subtable",
["!Italic", "'liga' Standard Ligatures in Latin lookup 6 subtable"] ]
其中 --removeligatures 与 --removeligs 是同一参数的两个别名,在 font-patcher 第 2276 行定义:
--removeligs, --removeligatures Removes ligatures specified in configuration file (needs --configfile)
该参数必须搭配 --configfile 使用,因为它依赖配置文件 [Subtables] 段中的 ligatures 列表来定位要删除的具体子表。列表中的每一项可以是一个简单字符串(要移除的子表名),也可以是 [正则, 子表名] 形式的二元组;正则若以 ! 开头则表示取反——例如上面示例中的 ["!Italic", "'liga' ... lookup 6 subtable"] 表示"只要字体全名不匹配 Italic,就移除该标准连字子表"。
3.3 源码级原理:remove_ligatures 的调用链
从 font-patcher 的源码结构看,补丁流程在写入 SFNT 名称阶段附近会调用 remove_ligatures()(第 381 行调用、第 832-857 行实现)。核心逻辑是:
- 检查
self.args.removeligatures是否为真; - 读取配置文件
[Subtables]段的ligatures列表(JSON 格式); - 对每条记录做正则匹配判断:复杂条目先解析正则与
!取反语义,只有匹配通过才进入下一步; - 对命中的子表调用 FontForge 的
removeLookupSubtable(subtable)删除对应连字查找子表。
因此,NoLigatures 分支产物中不再包含 liga、dlig 等连字查找表,即使终端或编辑器启用了连字渲染,也无法把这些字符组合成连字字形——这是它与"运行时关闭连字"在机制上的本质区别。仓库中如 src/unpatched-fonts/Noto/Sans-Mono/config.cfg、src/unpatched-fonts/Ubuntu/config.cfg 等大量字型的配置都采用了 --removeligatures 参数,说明这是一条被广泛使用的通用补丁路径。
3.4 如果你装了带连字版本怎么办
README 也给出了对 Ligatures 分支的补救建议:如果你的终端支持连字(ligature-aware terminal)但你不想要连字,通常可以在终端设置中关闭连字,无需更换字体文件。
四、获取方式:两种主流路径
选定字重与变体后,README 给出两条获取补丁字体的路径。
4.1 方式一:直接下载已补丁字体(推荐)
- 稳定版:从 Nerd Fonts 的 release 页面下载字体包,JetBrains Mono 的打包产物在仓库根 README 中提供了两种压缩格式:
JetBrainsMono.zip与体积更小的JetBrainsMono.tar.xz; - 开发版:直接使用本仓库
patched-fonts/JetBrainsMono/下的目录产物(即本文所讲解的 NoLigatures 各字重 TTF)。
4.2 方式二:用 font-patcher 自行打补丁
如果你需要"不包含全部图标"(例如为了缩小字体体积)等个性化组合,可以下载上游 JetBrains Mono 字体后自行运行补丁器。仓库根目录的 font-patcher 是可执行脚本,常用调用形式为:
# 示例:为上游 JetBrainsMono-Regular.ttf 打补丁(具体参数以 --help 输出为准)
font-patcher --removeligatures --configfile src/config.sample.cfg JetBrainsMono-Regular.ttf
也可以先用 font-patcher --help 查看全部选项。--removeligatures 需要与 --configfile 配合;配置文件写法可参考 src/config.sample.cfg,其中 commandline 字段还示范了 --makegroups 2(对符号按组聚合,可显著缩小字体文件体积)与 abort-mono-patch: True 的组合用法。
五、安装与使用
补丁字体与普通 TTF 的安装方式完全一致。仓库提供了跨平台安装脚本:
- Linux/macOS:执行根目录 install.sh;
- Windows:执行根目录 install.ps1(PowerShell)。
也可以在系统字体目录中手动放置 TTF 文件。此外,仓库根目录的 10-nerd-font-symbols.conf 是 fontconfig 配置示例,可在 Linux 下将 Nerd Fonts 符号字体作为回退字体,确保终端在缺字时能正确回退到图标字形。
安装后在终端、编辑器中按名称选择字体即可:
- 使用
JetBrainsMonoNL Nerd Font Mono作为等宽终端字体; - 使用
JetBrainsMonoNL Nerd Font获得更宽的图标; - 使用
JetBrainsMonoNL Nerd Font Propo处理 GUI 比例排版场景。
需要强调的是,本分支已移除连字,若你希望保留 ->、=> 等编程连字体验,请改用 patched-fonts/JetBrainsMono/Ligatures/ 分支,并在支持连字的终端中开启该特性。
六、许可证与保留字体名说明
JetBrains Mono 采用 SIL Open Font License 1.1(每个字重目录均附带 OFL.txt),可自由使用、修改与再分发,但需遵循 OFL 的保留字体名(Reserved Font Name,RFN)机制:修改版不得使用保留的原始字体名称,除非获得版权所有者的书面许可。仓库在 src/readme-rfn-addendum.md 中摘录了这一条款,其目的是避免混淆、保护作者、减少支持负担并鼓励衍生作品。Nerd Fonts 补丁产物采用独立命名(JetBrainsMonoNLNerdFont*)正是对这一机制的实际遵循。
小结
- 选变体:终端选
NFM、想图标更大选NF、GUI 比例场景选NFP; - 选分支:不要连字用 NoLigatures(本主题),要连字用 Ligatures;
- 获取:稳定版下载 release 压缩包,个性化需求用 font-patcher 加
--removeligatures自打补丁; - 原理:NoLigatures 是在补丁阶段通过配置文件与
removeLookupSubtable删除连字查找表,与运行时关闭连字是两种不同机制。