VS Code 的 editor.tokenColorCustomizations 无法高亮自定义关键字,因其仅能覆盖已有 token 类型,不能创建新 scope;必须通过 TextMate 语法注入或完整语法扩展先生成对应 scope(如 keyword.custom.constant),再用 textMateRules 配色。

VS Code 无法通过 editor.tokenColorCustomizations 直接高亮自定义关键字,必须用 TextMate 语法注入(injectionSelector)或扩展语法文件 + textMateRules 配合生效。
为什么 tokenColorCustomizations 对自定义关键字无效
VS Code 的 editor.tokenColorCustomizations 只能覆盖已有 token 类型(如 keyword、support.function),不能凭空创建新 token。你写的 myKeyword 如果没被语法解析器识别为某个 scope,再怎么配 textMateRules 都不会命中。
- 常见错误现象:
"scope": "myKeyword"完全不生效,关键词颜色毫无变化 - 根本原因:TextMate 规则靠 scope 字符串匹配,而默认的 JavaScript/Python 等语法不产出
myKeyword这类 scope - 验证方法:打开命令面板 →
Developer: Inspect Editor Tokens and Scopes,把光标停在目标词上,看右下角显示的实际 scope 列表
正确做法:用 injectionSelector 注入自定义 scope
适用于想在特定语言(如 JavaScript)中高亮一组固定单词(如 TODO、FIXME、API_V1),且不想写完整语法扩展的情况。
- 新建
~/.vscode/extensions/custom-keywords-0.0.1/syntaxes/inject-custom-keywords.json - 内容需包含
injectionSelector(例如"L:source.js"表示注入到 JS 文件)和patterns匹配规则 - 关键点:每个
match必须输出一个明确 scope,如keyword.custom.api,后续才能被textMateRules捕获 - 示例片段(匹配大写蛇形常量):
{ "injectionSelector": "L:source.js", "patterns": [ { "match": "\b[A-Z][A-Z_0-9]*\b", "name": "keyword.custom.constant" } ] }
如何用 textMateRules 绑定颜色
只有当上面的 injection 成功产出 scope 后,这条配置才起作用。它不是独立生效的开关,而是“染色器”。
- 在
settings.json中添加:"editor.tokenColorCustomizations": { "textMateRules": [ { "scope": "keyword.custom.constant", "settings": { "foreground": "#ff6b6b", "fontStyle": "bold" } } ] } -
scope值必须与 injection 中的name完全一致(包括大小写和点号) - 多个规则按数组顺序匹配,靠前的规则优先级更高;避免 scope 冲突(比如同时匹配
keyword和keyword.custom.constant) - 不支持正则 scope,不支持通配符(
keyword.custom.*无效)
更稳定但重一点的方案:写完整语法扩展
如果需要跨语言支持、复杂上下文判断(比如只在注释里高亮 TODO),或者 injectionSelector 不稳定(某些语言不支持注入),就得走标准语法扩展路径。
- 创建
package.json声明contributes.grammars,指向自定义.tmLanguage.json - 在
.tmLanguage.json中用repository和include复用原语言语法,再叠加自己的patterns - 好处是 scope 控制精准、可调试性强;坏处是每次更新都要 reload window,且发布为扩展才方便复用
- 本地测试时,直接把
.tmLanguage.json放进~/.vscode/extensions/xxx/syntaxes/并重启即可
真正卡住人的地方从来不是配色本身,而是 scope 没生成出来就急着写 textMateRules —— 先用 Inspect Editor Tokens and Scopes 确认 scope 存在,再动笔配色,省掉 90% 的无意义尝试。


















