VSCode自定义主题必须同时包含colors和tokenColors两个顶层字段,缺一不可;colors用预定义color ID控制UI控件色,tokenColors用TextMate scope控制语法高亮,并通过Developer: Inspect Editor Tokens and Scopes精准获取scope。

VSCode 自定义皮肤(主题)不是写个插件就能生效的——它本质是 JSON 配置文件,不是运行时逻辑代码;真要发成插件,必须严格满足 package.json 声明 + tokenColors + colors 三要素,缺一就白忙。
为什么只改 workbench.colorCustomizations 不算“自定义皮肤”
这个设置只是用户级临时覆盖,不打包、不复用、不跨机器,且只影响 UI 控件色(比如侧边栏、状态栏),完全不碰语法高亮。你改了 editor.background,但 string 还是默认橙色,keyword 还是蓝色——这根本不是一套皮肤,只是“贴了层膜”。真正皮肤必须同时控制两层:UI 元素颜色 + 代码 token 着色规则。
-
colors字段只能用 VSCode 官方预定义 color ID(如editorLineNumber.foreground),不能自造 key -
tokenColors是数组,每项必须含scope(如support.function.console.js)和settings(含foreground、fontStyle) - 想改某个语法元素?别猜 scope —— 光标停在目标代码上,按
Cmd+Shift+P→ 运行Developer: Inspect Editor Tokens and Scopes,取顶部第一个 scope
package.json 里 uiTheme 必须设为 vs-dark 或 vs
VSCode 主题系统硬性限制:package.json 的 contributes.themes 下每个 theme 条目,uiTheme 字段只能填 "vs-dark" 或 "vs"。填 "hc-black" 或留空都会导致主题加载失败,且无任何错误提示——它就静默忽略整个条目。
- 填
"vs-dark"表示适配深色 UI(绝大多数自定义皮肤选这个) - 填
"vs"表示适配浅色 UI,但实际中极少有人做纯浅色皮肤,因为语法高亮常依赖深底反差 - 路径字段
path必须指向你的.json主题文件,且该文件必须与package.json同目录或子目录下
调试时 Developer: Inspect Editor Tokens and Scopes 显示多个 scope 怎么选
Inspect 工具列出的 scope 是从具体到宽泛的链式结构,比如 support.function.console.js → support.function.js → support.function。匹配规则是“最长前缀优先”,所以你配 support.function.console.js,就不会被更宽泛的 support.function 覆盖。
- 永远优先用顶部第一个(最具体)的 scope,避免误改其他语言或上下文的同类元素
- JavaScript 的
console.log和 Python 的print()scope 完全不同,不能复用 - 如果 scope 带语言后缀(如
.js),说明它由对应语言插件注册,换语言就得换 scope - 配完保存主题文件后,不用重启 VSCode,直接按
Cmd+K Cmd+T切换一次当前主题即可刷新
发布前必须验证 tokenColors 和 colors 是否共存
新建一个 my-theme.json 文件时,最容易犯的错就是只写 colors 对象,漏掉 tokenColors 数组——VSCode 会完全无视这个文件,连 warning 都不抛。主题文件必须是合法 JSON,且顶层必须同时存在这两个字段。
-
colors是对象,键名固定,值为十六进制色值(支持 alpha,格式为#RRGGBBAA) -
tokenColors是数组,哪怕只配一条规则也得是数组形式:[{"scope": "comment", "settings": {"foreground": "#6272a4"}}] - 字体样式
fontStyle只接受"italic"、"bold"、"underline"或空字符串,不能写"bold italic" - 发布前用
vsce package打包,若报错Invalid theme file,90% 是这两个字段没对齐
真正难的不是写 JSON,而是搞清 scope 边界和 color ID 的映射关系——同一个视觉元素,在不同语言、不同插件、不同上下文中,scope 名可能完全不同;而 UI 控件色 ID 又不能拼错一个字母。这些细节不靠 inspect 工具和官方文档交叉验证,光靠试错会卡很久。


















