字体最终修复方案(Arch)

适用场景:Arch Linux + Niri + DMS 环境下,VSCode、Kitty、opencode 等终端出现黑块、断字、中文异常。你会学到"四层字体架构"的最终方案:系统层安装、fontconfig 全局 fallback、VSCode 与 Kitty 对齐配置,并掌握最终验证方法。

下面给你一套"字体最终修复方案(Arch + Niri + DMS + VSCode + Kitty + opencode 全一致无黑块版)"。

这套方案的目标只有一个:所有终端 / GUI / TUI / 编辑器字体完全统一,不再出现黑块、断字、中文异常。

最终架构

字体不再是"一个字体解决全部",而是 4 层:

1. 英文/代码 -> JetBrainsMono Nerd Font Mono
2. 图标 -> Nerd Fonts Symbols Mono
3. 中文 -> Noto Sans CJK SC
4. Emoji -> Noto Color Emoji

系统级安装(必须)

sudo pacman -S \
ttf-jetbrains-mono-nerd \
noto-fonts \
noto-fonts-cjk \
noto-fonts-emoji \
ttf-nerd-fonts-symbols-mono

fontconfig 全局统一(核心修复点)

编辑 ~/.config/fontconfig/fonts.conf,写入以下内容:

<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>

<!-- ========== monospace 主字体链 ========== -->
<match target="pattern">
  <test name="family">
    <string>monospace</string>
  </test>

  <edit name="family" mode="prepend">
    <string>JetBrainsMono Nerd Font Mono</string>
    <string>Noto Sans Mono CJK SC</string>
  </edit>
</match>

<!-- ========== sans 中文 fallback ========== -->
<match target="pattern">
  <test name="lang" compare="contains">
    <string>zh</string>
  </test>

  <edit name="family" mode="prepend">
    <string>Noto Sans CJK SC</string>
  </edit>
</match>

<!-- ========== emoji ========== -->
<alias>
  <family>emoji</family>
  <prefer>
    <family>Noto Color Emoji</family>
  </prefer>
</alias>

</fontconfig>

VSCode(最容易出问题的地方)

打开 settings.json

"terminal.integrated.fontFamily":
"JetBrainsMono Nerd Font Mono, Symbols Nerd Font Mono, Noto Sans CJK SC, Noto Color Emoji"

关键额外设置(必须)

"terminal.integrated.gpuAcceleration": "off",
"terminal.integrated.fontLigatures": true

Kitty(对齐 VSCode)

font_family JetBrainsMono Nerd Font Mono
bold_font auto
italic_font auto

symbol_map U+4E00-U+9FFF Noto Sans CJK SC
emoji_font Noto Color Emoji

opencode / TUI 环境(避免断字符)

确保 locale 设置:

export LANG=zh_CN.UTF-8
export LC_ALL=zh_CN.UTF-8
export TERM=xterm-256color

已在 DMS environment.d 中配置,这里只做确认。

DMS / Niri(你已经做对了)

~/.config/environment.d/90-dms.conf 内容:

LANG=zh_CN.UTF-8
LC_ALL=zh_CN.UTF-8
TERM=xterm-256color

这一步已经 OK,非常关键。

最终验证方法

在所有环境运行:

echo "中文 test ABC    🌏 ▓▒░"

正常结果

  • 中文:正常不方块
  • 英文:等宽
  • 图标:正常(无黑块)
  • emoji:彩色
  • 排版:对齐

如果仍然有黑块(最后兜底)

fc-match monospace
fc-cache -fv

并检查:

fc-list | grep "JetBrainsMono"
fc-list | grep "Noto Sans CJK"

最终总结

这套系统最终正确状态:

DMS / systemd env -> 控制 LANG / TERM
fontconfig -> 控制中文 fallback
VSCode -> 控制 terminal glyph
Kitty -> 对齐渲染
Noto CJK -> 中文兜底
Nerd Font -> 图标核心

一句话终极结论

字体问题的本质不是"缺字体",而是 fontconfig + terminal + Nerd Font 没有统一 fallback 链。

参考