JetBrains Mono NoLigatures 无连字字体变体:Nerd Fonts 下的选择与打补丁实战指南
JetBrains Mono NoLigatures 无连字字体变体:Nerd Fonts 下的选择与打补丁实战指南
JetBrains Mono 是 JetBrains 为开发者打造的编程字体,Nerd Fonts 仓库为其提供三种(普通 / Mono / Propo)形态的预打补丁版本,其中 NoLigatures 系列(文件名以 JetBrainsMonoNL 开头)默认移除了连字。本文以 patched-fonts/JetBrainsMono/NoLigatures/BoldItalic/README.md 为核心,讲解该字体变体的完整脉络:如何按终端与场景选择 Nerd Font / Nerd Font Mono / Nerd Font Propo,连字被保留或去除的底层逻辑,以及"下载现成字体"与"用 font-patcher 自行打补丁"两条获取路径,并对照 font-patcher 源码与 changelog.md 中的实现证据。
目录中的这份 README 是什么
patched-fonts/JetBrainsMono/NoLigatures/BoldItalic/README.md 是 Nerd Fonts 为每个补丁字体目录生成的说明文件,它由仓库维护脚本基于模板 src/readme-per-directory-addendum.md 填充生成(模板中保留了 %DOWNLOADFROM% 占位符,生成时替换为具体下载路径)。
它承担两项职责:
- 元信息声明:确认该目录中字体为 JetBrains Mono 上游版本 2.304 打补丁所得,并指向上游官网;
- 选字体决策指南:提供
Which font?一节,帮助用户在众多 Nerd Fonts 补丁变体中快速做出选择。
因此,该文档的核心技术内容是"Nerd Fonts 三种命名形态的选择逻辑 + 连字处理说明 + 两条获取路径",下面逐一展开,并结合仓库源码印证实现细节。
三种形态怎么选:NF / NFM / NFP
原文档的 TL;DR 部分给出了最简决策路径,这也是整个 Nerd Fonts 使用体系中最关键的概念,完整继承如下:
- Nerd Font Mono(缩写 NFM):适合被强制使用等宽字体的场景(如多数终端)。所有字符(包括新增图标)都被强制为单倍宽度;
- Nerd Font(缩写 NF):适合希望图标更大(通常约为普通字符的 1.5 倍宽)的场景。大多数终端都支持,但效果因终端而异(文档原文为 ymmv);
- Nerd Font Propo(缩写 NFP):适合比例(非等宽)上下文,例如 GUI 元素、演示文稿编辑等。
在 NoLigatures/BoldItalic 目录中,这三种形态正好对应三类文件:BoldItalic 目录 下的 JetBrainsMonoNLNerdFont-BoldItalic.ttf(NF)、JetBrainsMonoNLNerdFontMono-BoldItalic.ttf(NFM)、JetBrainsMonoNLNerdFontPropo-BoldItalic.ttf(NFP),三个文件共用一个 OFL.txt 许可证与一份 README.md。
源码层面:三种形态如何被生成
这三种形态并非人工维护的多份文件,而是 font-patcher 通过命令行参数从同一份上游字体生成的,相关参数定义见 font-patcher:
| 参数 | 简写 | 作用 | 对应形态 |
|---|---|---|---|
--mono |
-s |
生成等宽字体,已有与新增字形均为单宽度(隐含 --single-width-glyphs);可重复传递以强制覆盖非等宽字体 |
NFM |
--single-width-glyphs |
— | 仅控制新增图标字形为单宽度(默认是双宽度) | NFM |
--variable-width-glyphs |
— | 不调整字符宽度(无 "overhang"),保持原有比例宽度 | NFP |
| (默认) | — | 图标按双宽度叠加,宽度约为 1.5 个普通字符 | NF |
参数之间的冲突也在源码中有显式处理:font-patcher 第 2383 行会检测 --variable-width-glyphs 与 --mono/--single-width-glyphs 同时出现的情况,并输出警告 "Specified contradicting --variable-width-glyphs together with --mono or --single-width-glyphs. Ignoring --variable-width-glyphs."。
此外,--mono 并非只影响新增图标:从源码结构看(font-patcher),当指定 --mono 时,patcher 会调用 set_sourcefont_glyph_widths() 强制统一所有字符宽度,注释明确说明这是为了保证字体在 Windows 上被视为等宽字体,且需要对全部字符执行,因为原始字体文件中部分宽度信息可能已丢失。
连字(Ligatures):保留、去除与自行控制
这是理解 NoLigatures 目录命名的关键。原文档明确指出:
- 补丁字体通常保留上游连字;
- Nerd Fonts
v2.0.0曾让Nerd Font Mono字体不含连字,这一设计在v2.1.0被撤销; - 若终端支持连字而你不想使用,通常可在终端设置中关闭。
这一点与仓库历史高度吻合。在 changelog.md 中可以找到连字处理的演进证据:
- 相关条目修复了 JetBrains Mono
!=连字(Fix JetBrains Mono != ligature); - 较早版本支持通过
--removeligatures选项去除连字; - 维护记录中有 "Revive some ligature removal (only of problematic ligs)"(恢复部分有问题的连字的移除)与 "Sunset ligature removal"(移除连字功能下线)等调整。
NoLigatures 变体的含义
本仓库为 JetBrains Mono 提供 Ligatures 与 NoLigatures 两套目录(patched-fonts/JetBrainsMono/NoLigatures)。NoLigatures 下的字体文件名带 NL 标记(如 JetBrainsMonoNLNerdFont-BoldItalic.ttf),即上游无连字(No Ligatures)版本的补丁产物,适合不想在等宽终端中看到 ->、!= 等编程连字的开发者。
源码层面:连字移除机制
font-patcher 提供了 --removeligs / --removeligatures 参数(需配合 --configfile 使用),其实现位于 remove_ligatures() 方法(font-patcher):
- 从配置文件
Subtables段读取ligaturesJSON 列表; - 列表项可以是字符串(直接作为 lookup subtable 名称移除),也可以是
[regex, table]形式的复杂条目——若 regex 以!开头则表示"该字体名不匹配时才执行移除"; - 通过 fontforge 的
removeLookupSubtable()实际删除连字查找表,失败时记录 error 但不会中断打补丁流程。
从源码注释可以看出,该机制主要用于等宽字体:let's deal with ligatures (mostly for monospaced fonts),且通常只移除会破坏单格宽度的 fi 类连字。这说明"连字保留与否"在 Nerd Fonts 中是一套可配置的工程机制,而非简单的静态结果。
获取方式一:直接下载已打补丁的字体
原文档给出两条下载路径,完整继承:
- 稳定版:从官方 release 页面下载发布包(这是 Nerd Fonts 最推荐的方式,release 包会包含全部字族与文档);
- 开发版:直接从当前仓库对应目录下载,例如 patched-fonts/JetBrainsMono/NoLigatures/BoldItalic 下的
JetBrainsMonoNLNerdFont-BoldItalic.ttf、JetBrainsMonoNLNerdFontMono-BoldItalic.ttf、JetBrainsMonoNLNerdFontPropo-BoldItalic.ttf。
安装到系统
仓库同时提供了跨平台安装脚本,可作为"下载后怎么做"的落点:
- Linux/macOS:执行 install.sh;
- Windows:以管理员身份运行 install.ps1。
Linux 下还可借助仓库自带的 10-nerd-font-symbols.conf 将 Symbol 字形(NerdFontsSymbolsOnly)接入 fontconfig,让终端在字体缺少个别图标时回退到符号字体渲染,避免出现缺字形方框。
获取方式二:用 font-patcher 自行打补丁
如果下载好的字体不满足需求(例如想精简符号集以减小体积、或想要特定风格组合),可以自行打补丁,这正是原文档 Option 2 的内容:使用 font-patcher 提供的各种选项,例如"不包含全部符号以减小字体体积"。
最小可复现命令
以本仓库源码为基准,典型用法如下:
./font-patcher JetBrainsMono.ttf --complete
--complete(简写 -c)表示添加所有可用 Glyphs(参数定义见 font-patcher)。若要生成本文主题对应的三种形态,可分别执行:
./font-patcher JetBrainsMono.ttf --complete # 生成 Nerd Font(NF)
./font-patcher JetBrainsMono.ttf --complete --mono # 生成 Nerd Font Mono(NFM)
./font-patcher JetBrainsMono.ttf --complete --variable-width-glyphs # 生成 Nerd Font Propo(NFP)
常用参数速查
| 参数 | 简写 | 说明 |
|---|---|---|
--complete |
-c |
加入全部可用图标 |
--mono |
-s |
等宽输出(隐含单宽度字形) |
--variable-width-glyphs |
— | 保持比例宽度(Propo) |
--single-width-glyphs |
— | 新增字形单宽度 |
--careful |
— | 检测到已有字形时不要覆盖 |
--removeligs / --removeligatures |
— | 按配置文件移除指定连字查找表(需 --configfile) |
--configfile |
— | 指定自定义配置文件 |
配置文件默认模板见 src/config.sample.cfg,其中 Subtables 段的 ligatures 列表即为 remove_ligatures() 读取的数据源。
从源码结构可以推断,打补丁的完整流程还包括:将字体编码切换为 UnicodeFull 以释放全部 Unicode 字形(font-patcher)、为非常宽且矮的字体禁用双单元格 Powerline 字形(font-patcher)、在版本号 SFNT name 中追加 Nerd Fonts 标识(font-patcher)等。这些细节解释了为什么"打补丁"不只是简单叠加图标。
许可证与保留字体名(RFN)说明
NoLigatures/BoldItalic 目录与仓库中其他补丁字体一样附带了 OFL.txt(SIL Open Font License)。需要特别注意的是,JetBrains Mono 属于启用了 Reserved Font Name(RFN)机制的字体:根据 SIL OFL 的 RFN 条款,修改版字体不得使用被保留的主字体名,除非获得版权持有者的书面许可。
这正是补丁字体命名带 NL、NerdFont 等后缀的原因——例如 JetBrainsMonoNLNerdFont-BoldItalic.ttf 就是对原"JetBrains Mono"名称的合法改写。仓库用 src/readme-rfn-addendum.md 统一说明了 RFN 的机制与目标(避免冲突、保护作者、最小化维护负担、鼓励衍生)。
结语
patched-fonts/JetBrainsMono/NoLigatures/BoldItalic/README.md 虽篇幅不长,却浓缩了 Nerd Fonts 使用体系的三块基石:NF / NFM / NFP 三形态的选择逻辑(对应 font-patcher 的 --mono、--variable-width-glyphs 等参数)、连字的保留与去除机制(对应 remove_ligatures() 实现与 NoLigatures 目录命名),以及下载现成补丁字体 / 自行打补丁两条获取路径。结合 font-patcher 源码、changelog.md 与配置文件模板 src/config.sample.cfg,开发者不仅能在终端、IDE 与 GUI 场景中选对字型,还能理解并复现 Nerd Fonts 的补丁工程细节。