vscode中格式化与颜色显示机制独立,格式化不改变颜色;颜色失效主因是语言模式错误、语义高亮覆盖textmaterules或第三方主题吞掉自定义规则,须用developer: inspect editor tokens and scopes实抓准确scope并严格按languageid配置。

VSCode 里“格式化”和“颜色显示”是两套独立机制,格式化(如 Prettier、Volar)只管代码结构(缩进、换行、空格),不碰颜色;颜色显示完全由 editor.tokenColorCustomizations 控制,依赖语法作用域(scope),跟格式化器无关。想让格式化后的代码颜色依然准确,关键不是配格式器,而是确保高亮规则本身没被覆盖或写错。
为什么格式化后某些词颜色变淡或消失
这不是格式化导致的,而是高亮规则失效的典型症状。常见原因有三个:
- 当前文件语言模式不对——比如
.vue文件右下角显示的是HTML而非Vue,editor.tokenColorCustomizations就不会生效 - 启用了语义高亮(
"editor.semanticHighlighting": true),而你的textMateRules规则粒度太粗(比如只写了variable),被更精确的语义规则(如variable.other.readwrite.ts)覆盖了 - 第三方主题(如 One Dark Pro、Nord)自带完整的
tokenColors,直接吞掉了你自定义的textMateRules,哪怕配置语法完全正确也看不到效果
怎么查准 format 后仍有效的 scope
别信网上搜来的“string”或“keyword”,必须用 VSCode 自带工具实抓。打开一个刚被格式化过的文件,把光标停在目标词上(比如 Prettier 格式化后的一段 const name = "Alice" 中的 "Alice"),然后:
- 按
Ctrl+Shift+P(Win/Linux)或Cmd+Shift+P(macOS) - 输入并执行
Developer: Inspect Editor Tokens and Scopes - 看面板顶部第一个带语言后缀的 scope,例如
string.quoted.double.tsx或string.quoted.single.python—— 这才是你该填进textMateRules的值
注意:如果格式化改变了结构(比如把多行模板字符串压成一行),scope 可能也会变,务必在格式化后抓取。
如何避免格式化插件干扰高亮配置
格式化插件本身不改颜色,但它们可能间接破坏高亮前提:
- Volar / Vetur 如果未正确激活,
.vue文件会被当成HTML处理,你的[vue]语言专属规则就根本不会加载 - Prettier 若被设为默认 formatter,但没配合
volar.format.defaultFormatter.js等桥接配置,可能导致<script setup></script>块内语法识别失败,进而影响 scope 判定 - 多个格式器共存(比如同时启用 Prettier 和 ESLint 的 auto-fix-on-save)可能造成编辑器卡顿或语言服务器重启,临时中断语义高亮,让 scope 暂时回退到词法层
最稳做法:关掉所有非必要格式器,确认高亮正常后再逐个开回来,观察哪一步触发异常。
language-specific override 写法必须严格
想只对 TypeScript 或 Vue 单独调色,不能只写 "[typescript]": { "editor.tokenColorCustomizations": { ... } } 就完事。VSCode 对语言标识符大小写和拼写极其敏感:
-
typescriptreact是 TSX 文件的正确标识,不是tsx或ts-react -
vue是 Volar 激活后的标准标识,不是vue-html或vue-sfc - 整个配置必须是顶级 JSON 字段,不能嵌在别的对象里,否则整个块被忽略
错误示例:"files.associations": { "*.vue": "vue" } 下面紧跟着 "[vue]": {...} 是无效的——这两个字段平级,不是父子关系。
真正容易被忽略的点是:语义高亮开启时,textMateRules 只作为兜底,优先级最低。如果你看到某个变量颜色始终不变,大概率不是 scope 写错了,而是语言服务器已经给出了更细粒度的语义标记,这时候得去查 entity.name.variable 这类更具体的 scope,而不是反复修改 variable。











