Visual Studio Code 中 Operator Mono 的可行替代方案

2025-06-07

Visual Studio Code 中 Operator Mono 的可行替代方案

在看到Sarah Drasner为 VSCode 设计的 Night Owl 颜色主题后,开始犹豫是购买 Dank Mono(虽然不太成熟,但已经是相当不错的 Operator Mono 替代品),还是开始寻找免费的替代品。考虑到我的兴趣爱好每两秒就会切换一次,我决定不花钱买炒作,而是去寻找那些肯定存在的 hack。

起初,我在寻找 Operator Mono 的免费替代品时,发现了Ken Krocken 开发的FiraCodeiScript。它的作用是将两种字体合并成一种,这样你就可以使用 Fira Code 作为常规字体,使用 Script12 作为斜体字体。它们是使用FontForge(一款用于创建或修改字体的工具)编辑的。我的第一印象是“这很酷”,但过了一段时间后,我还是忍不住对 Script12 不太感冒了。

我觉得我必须创建一个自己的版本。因为我是一名程序员,不想费力地使用 GUI 工具,所以决定用FontTools编写一个 Python 脚本来编辑字体文件,让它们显示为一个字体系列。关于如何操作,请参阅GitHub 上 Open Soure Idea 代码库的下一期

FontTools 对我来说是不利的,而不是有利的,因为不知何故,我总是找不到需要调整的字段。于是,我开始寻找更好的模块。我的终端字体一直来自Nerd Fonts库,而且由于许可问题,他们也需要重命名字体,所以 Nerd Fonts 成了我深入研究的最佳起点。

他们用Python 脚本编辑字体文件,并附加大量酷炫的内容,你猜怎么着,他们用的是 FontForge 自带的 Python 模块。酷!很简单,对吧?不,不是。我选择用 Windows 10,这次我彻底被坑了。你不能用 来安装这个模块pip install FontForge,它包含在 FontForge 的安装包里。在 Linux 上,你可以安装绑定来暴露这个模块并在脚本中使用它,但 Windows 上没有这个选项。

回到思考舱!看看 FontForge 的工作原理,它嵌入了 Python 2.7 (🤦‍),让你可以开箱即用 FontForge 模块。出于务实的考虑,我决定使用这个 Python 可执行文件来创建脚本。使用 VSCode,你可以调整调试设置(位于projectroot\.vscode\launch.json)来实现这一点。

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Python Experimental: Current File (Integrated Terminal)",
            "type": "pythonExperimental",
            "request": "launch",
            "program": "${file}",
            "console": "integratedTerminal",
            "pythonPath": "C:\\Program Files (x86)\\FontForgeBuilds\\bin\\ffpython.exe"
        }
    ]
}
Enter fullscreen mode Exit fullscreen mode

这样,你就可以轻松导入 FontForge 模块,并创建一个脚本,将两个字体文件转换为一个新创建的字体系列。我非常喜欢 Fira Code,所以我从 Nerd Fonts 下载了Fura Code来保存所有有趣的内容,并且爱上了用Yellowtail作为斜体变体。

import fontforge
import uuid


def change_font_data_and_save(font_location, familyname,
                              sub_family, output_dir, uid):
    source_font = fontforge.open(font_location)
    source_font.familyname = familyname
    source_font.fullname = '{} {}'.format(familyname, sub_family)
    source_font.fontname = '{}-{}'.format(familyname, sub_family)
    source_font.appendSFNTName(str('English (US)'), str('Family'),
                               source_font.familyname)
    source_font.appendSFNTName(str('English (US)'), str('SubFamily'),
                               sub_family)
    source_font.appendSFNTName(str('English (US)'), str('UniqueID'),
                               uid)
    source_font.appendSFNTName(str('English (US)'), str('Preferred Family'),
                               source_font.familyname)
    source_font.appendSFNTName(str('English (US)'), str('Compatible Full'),
                               source_font.fullname)
    source_font.generate(output_dir + '/' + source_font.fullname + '.ttf',
                         flags=(str('opentype'), str('PfEd-comments')))


regular_font = 'path_to_fura_code.tff'
italic_font = 'path_to_yellowtail.ttf'
output_dir = './output'
familyname = 'VSCode Font'
uid = str(uuid.uuid4())
change_font_data_and_save(regular_font, familyname, 'Regular', output_dir, uid)
change_font_data_and_save(italic_font, familyname, 'Italic', output_dir, uid)
Enter fullscreen mode Exit fullscreen mode

这非常有效,你会在输出文件夹中得到两种字体,然后将它们安装为一个字体系列,调整 VSCode 以使用该字体即可。但有一个恼人的副作用。根据两种字体之间的差异,你可能需要缩放其中一种。我对 Yellowtail 就是这样做的,结果当一个句子以斜体单词开头时,一些字母会被截断。在上面的示例中,每当def位于一行的 0 位置时, 的d开头都会被稍微截断。我不需要解释这不是我想要的效果。

我查看了其他自定义字体,它们都存在同样的问题,具体取决于所使用的字体。一个效果更好的替代解决方案是使用自定义 CSS 和 JS 插件来调整斜体字(可以通过类名区分)的字体大小mkti。但是,重要的是,如果我们这样做,那么我们就失去了自定义字体的用例。

因此,在花了几个小时才搞定之后,我选择了自定义 CSS 方案。我安装了 Fura Code 和 Yellowtail 字体的所有变体,并使用自定义 CSS 和 JS 插件为该类创建了覆盖。为此,请创建一个包含以下内容的文件。您可以根据自己的喜好修改字体系列,在尝试了几种手写字体后,我最终mkti选择了Flottflott 。

.mtki {
    font-size: 1.6em;
    font-family: Flottflott;
}
Enter fullscreen mode Exit fullscreen mode

这会使文本变大,但仍会遵循窗口边界。因此,字体效果相同,但效果更好。如果您使用的是 Windows,请确保在应用样式时以提升的权限运行 VSCode(并在更新 VSCode 时重新应用)。

开始主题设置吧。我们每个人都使用不同的主题,而且并非每个主题都支持斜体关键字。现在,我不想创建自定义主题,而是想教你如何覆盖主题设置,这样无论你使用什么主题,这些设置都会生效。我切换主题就像换衣服一样(你可以定义是否频繁应用主题😲),所以我不想每次都费劲地摆弄这个。

事实证明,VSCode 遵循 TextMate 语法来定义其渲染代码的方式。我从另一个未公开的编辑器中找到了一份不错的指南,结合查看现有主题及其实现方式,我得以上手。目前我的配置如下。

"editor.fontFamily": "FuraCode NF",
"editor.fontLigatures": true,
"vscode_custom_css.imports": [
    "file://C:/Users/jan/.vscode_css_settings.css"
],
"vscode_custom_css.policy": true,
"editor.tokenColorCustomizations": {
    "textMateRules": [
        {
            "scope": [
                "storage.modifier",
                "variable.language",
                "markup.italic",
                "punctuation.definition.keyword",
                "keyword.control.import",
                "storage.type.class",
                "storage.type.function",
                "storage.modifier"
            ],
            "settings": {
                "fontStyle": "italic"
            }
        },
        {
            "scope": [
                //following will be excluded from italics
                "comment",
                "invalid",
                "keyword.operator",
                "keyword.control.conditional",
                "storage.type.function.arrow.js"
            ],
            "settings": {
                "fontStyle": ""
            }
        }
    ]
},
Enter fullscreen mode Exit fullscreen mode

有两个覆盖选项,一个明确指定要渲染斜体的内容(并因此添加mkti类),另一个用于排除要渲染斜体的关键字。这样我可以使用任何我喜欢的主题,我的设置将使正确的单词以美观的斜体显示。此列表并不完整,还有很多可以添加的选项。最终,它需要根据主题、语言和个人喜好来定义所需的外观。

我希望您在自定义编辑器时能获得和我尝试寻找灵丹妙药时一样多的乐趣😄。

斜体

原文发布于:https://blog.itdepends.be/operator-mono-alternative/

文章来源:https://dev.to/jandedobbeleer/a-viable-alternative-to-operator-mono-in-visual-studio-code-ge8
PREV
如何克服冒名顶替综合症?
NEXT
顶级 WebStorm 插件助您提升工作效率