直接修改 editor.tokenColorCustomizations 即可生效,但常见问题在于 scope 不准确、语义高亮覆盖或第三方主题静默覆盖;需用 Developer: Inspect Editor Tokens and Scopes 实时获取带语言后缀的精确 scope,并确保配置在 settings.json 的 textMateRules 中。

直接改 editor.tokenColorCustomizations 就能生效,但 90% 的人配完没反应,问题不在 JSON 写法,而在 scope 没抓准、规则被语义高亮绕过、或第三方主题静默覆盖。
怎么拿到准确的 scope 名称
别猜 keyword 或 comment——VSCode 实际打给代码片段的 scope 往往带语言后缀,比如 keyword.control.js、comment.line.double-slash、string.quoted.double.ts。必须用内置工具实时确认:
- 把光标停在目标位置(比如一个
if、一段// 注释、一对[]) - 按
Ctrl+Shift+P(Win/Linux)或Cmd+Shift+P(macOS),输入并执行Developer: Inspect Editor Tokens and Scopes - 看弹窗中 “Scope” 列表最靠前、带语言后缀的那一项(如
support.function.dom.js),优先选它 - 如果看到的是
source或text.plain,说明文件没被识别为对应语言——先检查右下角语言模式是否正确
配置必须写对位置和格式
editor.tokenColorCustomizations 只在 settings.json 中生效,UI 设置界面、workbench.colorCustomizations、主题文件里写都无效。
- 打开命令面板 → 输入
Preferences: Open Settings (JSON) - 在顶层 JSON 对象内添加字段:
"editor.tokenColorCustomizations",值是一个对象,不是数组 - 必须用
textMateRules字段,每条规则含scope(字符串或字符串数组)和settings(只支持foreground、background、fontStyle) - 示例有效写法:
{
"editor.tokenColorCustomizations": {
"textMateRules": [
{
"scope": "keyword.control.js",
"settings": {
"foreground": "#e06c75",
"fontStyle": "bold"
}
}
]
}
}
- 引号必须是英文双引号;末尾不能多逗号;
scope大小写敏感;settings不支持rgb()或颜色名,只认十六进制(如#6a9955)
为什么改了 keyword 却不影响 class 名
因为 class MyClass 中的 MyClass 不归语法高亮管,它由语言服务器识别为语义 token,类型是 class 或 support.class,走的是另一套机制。
- 想单独调类名颜色,得用
editor.semanticTokenColorCustomizations,且确保"editor.semanticHighlighting": true - 语义规则优先级高于
textMateRules,所以即使你在textMateRules里写了"scope": "support.class",也可能被覆盖 - 验证方式:运行
Developer: Inspect Editor Tokens and Scopes,把光标停在类名上,看 “Semantic token type” 是否为class;如果不是,说明语义分析未就绪(可能因语法错误、语言模式不对或 LSP 未加载) - 函数名同理:
function和method是两个独立语义类型,需分开配
第三方主题正在偷偷覆盖你
One Dark Pro、Nord、Material Theme 等主流主题自带完整的 tokenColors 规则,它们的优先级低于用户设置,但高于默认值——也就是说,你的规则没失效,只是被主题的更细粒度规则压住了。
- 查证方式:在
Developer: Inspect Editor Tokens and Scopes面板右侧点当前生效颜色旁的齿轮图标,会跳转到定义来源——大概率指向某个主题的package.json - 临时验证:切换到 VSCode 自带的
Default Dark+主题,如果颜色变了,就确认是主题冲突 - 部分主题提供开关(如
"nord.enforceSyntaxHighlighting": false),可禁用其语法层;否则只能用更具体的 scope(如comment.line.double-slash而非comment)来穿透覆盖
真正卡住人的从来不是 JSON 语法,而是 scope 和语义层的错位——光标停在哪,VSCode 就告诉你它真正在意什么;其余全是干扰项。











