必须将主题文件置于./themes/midnight-sage.json路径,package.json中contributes.themes[].uitheme严格设为vs-dark或vs,并在theme文件中同时定义colors(用官方color id)和tokencolors(含正确textmate scope)两个字段。

直接创建一个能被 VSCode 识别并启用的个人颜色主题,必须同时满足三个硬性条件:主题文件路径正确、package.json 正确声明、colors 和 tokenColors 两个字段缺一不可。只改 settings.json 里的 workbench.colorCustomizations 不算“创建主题”,它只是用户级覆盖,无法导出、复用或分享。
主题文件放哪?路径错就根本看不到你的主题
VSCode 不会自动扫描任意 JSON 文件作为主题——它只认固定路径下的文件。你必须手动创建 themes/ 子目录,并把主题文件放在里面:
- 项目根目录下新建文件夹:
themes(不能叫theme、Themes或嵌套在src/里) - 文件名必须全小写、用连字符分隔、以
.json结尾,例如:midnight-sage.json(MidnightSage.json或midnight sage.json都会失败) - 完整路径必须是:
./themes/midnight-sage.json - 如果路径不对,VSCode 启动后执行
Developer: Inspect Editor Tokens and Scopes都不会报错,但你的主题压根不会出现在「颜色主题」列表里
package.json 里 uiTheme 必须填 vs-dark 或 vs
VSCode 主题不是靠文件名或内容自动判断明暗模式的,而是靠 package.json 中 contributes.themes[].uiTheme 字段强制指定。填错或留空会导致主题加载失败:
-
"uiTheme": "vs-dark"→ 对应深色 UI(比如你设了"editor.background": "#1a1a1a") -
"uiTheme": "vs"→ 对应浅色 UI(不能写vs-light或light,官方不认) - 即使你主题里
colors全是浅色值,只要uiTheme是vs-dark,VSCode 就按深色模式加载;反之亦然 - 常见错误:
"uiTheme": "dark"或"uiTheme": "my-dark"—— 这两种写法都会让主题静默失效
tokenColors 不配,语法高亮永远是默认色
很多人以为改了 "editor.background" 和 "sideBar.background" 就算主题完成了,结果打开代码一看:注释还是灰色、关键字还是蓝色——因为没配 tokenColors。VSCode 的语法着色逻辑优先级是:具体 scope > editor.foreground > 默认 fallback。
-
tokenColors是数组,每一项必须含scope(TextMate 作用域)和settings(含foreground等) - 别猜 scope 名字,把光标停在目标代码上(比如一个
function关键字),按Cmd+Shift+P→ 运行Developer: Inspect Editor Tokens and Scopes,取顶部第一个 scope(如keyword.control.js) - 支持透明度:用
#RRGGBBAA格式,比如"#e53e3e80"(半透红),写成"#e53e3e"就没 alpha 效果 - 如果想全局微调所有文字颜色,加一条 fallback:
{"scope": ["*"], "settings": {"foreground": "#e2e8f0"}},但它不能替代具体规则
colors 字段只能用官方 color ID,不能自创
colors 控制的是界面控件,不是代码。它不接受任意字符串作 key,必须严格使用 VSCode 官方定义的 color ID(比如 activityBar.background),否则整个 colors 块会被忽略。
- 查完整 ID 列表:命令面板 →
Developer: Generate Color Theme From Current Settings,它会输出当前所有可用 ID - 常见误写:
"sidebarBg"、"tab-active-bg"、"editorFontColor"—— 全部无效 - 有效示例:
"editorLineNumber.foreground"、"tab.inactiveBackground"、"statusBar.noFolderBackground" - 注意大小写和点号,
editorLineNumbers.foreground(少个n)也会失效
最常被跳过的环节是验证 scope:哪怕 tokenColors 语法完全正确,如果 scope 写错了语言插件不认的值(比如给 Python 代码配了 keyword.control.js),那条规则就等于不存在。动手前先用 Inspect Editor Tokens and Scopes 点一下真实代码,比查文档快十倍。











