
1. 为什么我要把 VSCode 和 Cursor 的 C 代码配色改成 Keil 风格如果你平时写 STM32、GD32 或者 51 单片机大概率绕不开 Keil。Keil 的编辑器配色有个很鲜明的特点关键字是深蓝、注释是暗绿、字符串是偏暗的绿、数字也是绿整体饱和度低、明度低看久了眼睛不累。而 VSCode 和 Cursor 默认的 Dark 或者各种花哨主题颜色种类太多一个函数名、变量名、类型名、宏名能给你整出五六种颜色写嵌入式代码的时候注意力很容易被这些颜色带跑。我自己的场景是这样的白天在 Keil 里调寄存器、看汇编晚上切到 VSCode 或者 Cursor 写上层逻辑、跑 CMake 工程。两边配色差异太大眼睛每次都要重新适应。后来我干脆把 VSCode 和 Cursor 的settings.json手动改了一套 Keil 风格的浅色配色搭配 Visual Studio Light 主题使用关键字、注释、字符串、数字、宏定义的颜色全部对齐 Keil 的观感饱和度压下来明度提上去长时间盯着屏幕写 C 代码舒服很多。这篇文章要解决的就是在 VSCode 和 Cursor 里通过settings.json里的editor.tokenColorCustomizations把 C 语言语法高亮复刻成 Keil 经典配色并适配 Visual Studio Light 浅色主题。适合谁适合嵌入式开发、C 语言为主、用 Keil 习惯了的同学也适合觉得 VSCode 默认配色太花、想让代码颜色收敛一点的人。核心检索词就是VSCode settings.json Keil 配色、Cursor C 语言语法高亮、Visual Studio Light 主题、editor.tokenColorCustomizations。下面我会给出可以直接粘贴的配置片段并逐项说明怎么验证关键字、注释、字符串这些颜色有没有生效。先说清楚一个前提VSCode 和 Cursor 的配置体系是同一套settings.json的字段基本通用所以下面所有配置两边都能用。区别只在于打开设置文件的方式略有不同Cursor 是 VSCode 的 fork快捷键和菜单几乎一致。2. 前置准备Visual Studio Light 主题与 settings.json 打开方式在动手改配色之前先把基础环境搭好。这一步不做后面 token 颜色可能被主题覆盖你会以为配置没生效。2.1 安装并切换到 Visual Studio Light 主题VSCode 和 Cursor 都内置了Visual Studio Light这个主题不需要额外装扩展。打开命令面板CtrlShiftP输入Color Theme回车在列表里找到Visual Studio Light选中即可。如果你在列表里没看到可以在扩展市场搜Visual Studio Light或者直接装微软官方的C/C扩展它会带一些配套主题。切好之后整个编辑区背景是浅灰白侧边栏是浅色这是后面 Keil 配色能看清的前提。Keil 本身就是浅色背景如果你用深色主题去套 Keil 的暗绿注释对比度会很难看。2.2 打开 settings.json 的两种方式第一种命令面板输入Preferences: Open User Settings (JSON)直接打开用户级settings.json。这个文件对所有项目生效路径大概是Windows%APPDATA%\Code\User\settings.jsonCursor 是%APPDATA%\Cursor\User\settings.jsonmacOS~/Library/Application Support/Code/User/settings.jsonLinux~/.config/Code/User/settings.json第二种如果你只想对当前项目生效在项目根目录建.vscode/settings.json写进去的配置只作用于这个工程。嵌入式项目我建议用项目级配置因为不同项目可能用不同主题。2.3 确认 C/C 扩展已安装语法高亮的 scope 名称依赖语言支持。写 C 代码建议装微软官方的C/C扩展ms-vscode.cpptools它会提供source.c、source.cpp这些 scope。如果你用的是 clangdscope 体系略有差异但大部分textMateRules还是通用的。装好之后随便打开一个.c文件右下角语言模式确认是C而不是Plain Text。如果是 Plain Text点一下切成 C否则 token 规则不会命中。2.4 关于字体和编码的顺带设置Keil 默认字体偏小中文注释容易乱码。我一般会在settings.json里加上{ files.encoding: gb2312, files.autoGuessEncoding: true, editor.fontFamily: Consolas, Courier New, monospace, editor.fontSize: 13, editor.fontLigatures: false }files.encoding设成gb2312是为了兼容 Keil 工程里常见的中文注释编码。autoGuessEncoding打开后VSCode 会自动猜编码减少乱码。字体用 Consolas等宽、清晰接近 Keil 的观感。fontLigatures关掉因为连字在 C 代码里容易把!、-显示成奇怪符号反而影响阅读。这些基础项配好再进入配色部分。下面这段是核心直接决定关键字、注释、字符串的颜色。3. 可复制配置editor.tokenColorCustomizations 复刻 Keil 配色这一节是全文重点。我把配置拆成几块讲你可以整段粘贴也可以按需取用。核心思路是降低饱和度、统一色系、让关键字和类型用深蓝灰、注释用暗绿、字符串和数字用中绿、宏定义用深绿整体贴近 Keil 在浅色背景下的观感。3.1 完整配置片段可直接粘贴把下面这段合并进你的settings.json。注意 JSON 不能有注释我这里的注释只用于讲解实际粘贴时删掉。{ workbench.colorTheme: Visual Studio Light, editor.tokenColorCustomizations: { textMateRules: [ { scope: comment, settings: { foreground: #3f7f5f, fontStyle: italic } }, { scope: source, settings: { foreground: #1e1e1e } }, { scope: [ storage.type, support.type, entity.name.type, meta.type ], settings: { foreground: #0000c0 } }, { scope: [ keyword, keyword.control, storage.modifier ], settings: { foreground: #0000c0 } }, { scope: entity.name.function, settings: { foreground: #6a3ab2 } }, { scope: variable.parameter, settings: { foreground: #1e1e1e } }, { scope: constant.numeric, settings: { foreground: #3f853f } }, { scope: [ string.quoted.double, string.quoted.single ], settings: { foreground: #3f853f } }, { scope: meta.preprocessor, settings: { foreground: #2a6a2a } }, { scope: entity.name.function.preprocessor, settings: { foreground: #3f853f } }, { scope: string.quoted.double.preprocessor, settings: { foreground: #2a6a2a } } ] }, workbench.colorCustomizations: { editorBracketMatch.background: #ffd9a0, editorBracketMatch.border: #c08000, editorIndentGuide.background1: #e8ebe8 } }3.2 逐项说明每个 scope 对应什么comment控制注释包括//和/* */。我给了#3f7f5f一个偏暗的绿加斜体。Keil 的注释就是暗绿斜体这个颜色在浅色背景上不刺眼。source是默认文本颜色设成#1e1e1e接近纯黑但柔和一点。变量名、普通标识符都会用这个色。storage.type、support.type、entity.name.type、meta.type这几个合起来管类型比如int、uint8_t、struct名。Keil 里类型是深蓝我用#0000c0。keyword、keyword.control、storage.modifier管关键字比如if、for、return、static、const。同样深蓝和类型保持一致这样代码里结构性的东西都是蓝色视觉上统一。entity.name.function是函数名我用#6a3ab2紫色。Keil 里函数名偏紫蓝这个色在浅色背景上辨识度够又不会太跳。variable.parameter是函数参数设成和默认文本一样的#1e1e1e避免参数名颜色太花。constant.numeric是数字常量#3f853f中绿。Keil 里数字就是绿色。string.quoted.double和string.quoted.single是字符串同样#3f853f。meta.preprocessor管预处理指令整体比如#include、#define那一行用#2a6a2a深绿。entity.name.function.preprocessor是宏名用#3f853f。string.quoted.double.preprocessor是#include xxx.h里的字符串用#2a6a2a。3.3 括号匹配和缩进线的微调workbench.colorCustomizations里我调了括号匹配的背景和边框用暖橙色#ffd9a0这样光标停在某个括号上时配对括号一眼可见。缩进线用很浅的灰绿#e8ebe8不抢眼但能看清层级。3.4 关于 Cursor 的差异Cursor 的settings.json结构和 VSCode 完全一致上面这段直接粘进 Cursor 的用户设置或项目设置即可。Cursor 有些 AI 相关的内联提示颜色可能会覆盖部分 token如果你发现某处颜色不对可以在textMateRules里追加更具体的 scope 来覆盖。整体上这套配置在 Cursor 里表现和 VSCode 一样。配置写完保存VSCode 和 Cursor 会立即生效不需要重启。如果没变化检查 JSON 有没有语法错误比如多了逗号、少了引号。4. 验证请求逐项确认关键字、注释、字符串颜色是否生效配置粘进去只是第一步关键是确认每一项都真的生效了。我一般会写一个测试用的 C 文件把各种语法元素都覆盖到然后逐项对照。4.1 准备一个覆盖全语法的测试文件新建color_test.c内容如下#include stdio.h #include test.h #define MAX_COUNT 100 #define LED_PIN GPIO_PIN_5 typedef struct { uint8_t id; uint16_t value; } Sensor_t; static int g_counter 0; int calculate_sum(int a, int b) { // 这是单行注释 /* 这是块注释 跨行测试 */ int result a b; const char *msg hello keil; if (result MAX_COUNT) { result MAX_COUNT; } return result; }这个文件里包含了预处理指令、宏定义、类型定义、函数名、参数、数字、字符串、单行和块注释基本覆盖了我们要验证的所有 scope。4.2 逐项对照检查打开这个文件按下面的清单看关键字int、if、return、static、const应该是深蓝#0000c0。如果它们还是默认的紫色或者别的颜色说明keyword规则没命中检查 scope 拼写。类型uint8_t、uint16_t、Sensor_t也应该是深蓝。如果uint8_t没变色可能是 C/C 扩展把它识别成了别的 scope可以追加support.type.stdint试试。函数名calculate_sum应该是紫色#6a3ab2。如果没变确认语言模式是 C。注释应该是暗绿斜体。如果注释没变绿检查comment规则有没有被主题覆盖可以把textMateRules里的comment规则放到数组最前面。字符串hello keil和test.h应该是绿色。数字100、5、0也应该是绿色。宏MAX_COUNT、LED_PIN应该是绿色#define那一行整体偏深绿。4.3 用开发者工具查看 token scope如果某项颜色死活不对最靠谱的办法是用 VSCode 的开发者工具看它实际命中的 scope。命令面板输入Developer: Inspect Editor Tokens and Scopes然后把光标放到那个词上会弹出一个面板显示当前 token 的 scope 列表和最终生效的颜色。比如你把光标放到uint8_t上面板可能显示support.type.stdint.c那你就知道该在textMateRules里针对这个 scope 加规则。这个方法比瞎猜高效得多我调配色基本都靠它。4.4 确认主题没有被覆盖有时候你改了 token 颜色但看起来没变是因为主题本身对某些 scope 有更强的定义。editor.tokenColorCustomizations的优先级高于主题正常情况下会覆盖。但如果主题用了semanticHighlighting可能会绕过 textMate 规则。可以在settings.json里加{ editor.semanticHighlighting.enabled: false }关掉语义高亮让所有颜色都走 textMate 规则这样你的配置就完全可控了。C/C 扩展默认可能开启语义高亮关掉之后颜色更接近 Keil 那种纯语法着色。4.5 在 Cursor 里验证Cursor 的验证方式和 VSCode 一样Developer: Inspect Editor Tokens and Scopes命令同样可用。如果 Cursor 的 AI 补全提示灰色幽灵文本颜色和你的配色冲突可以在设置里搜editorGhostText调整但那不属于语法高亮范畴不影响主体配色。逐项确认完之后你的 C 代码应该已经是 Keil 那种低饱和、浅色背景、蓝绿为主的观感了。5. 本篇常见错排查401、local proxy failed、reading choices 等报错对照这一节说几个我在配置过程中真实踩到的坑以及一些和 AI 编码工具相关的报错。虽然主题配置本身不涉及网络请求但如果你在 Cursor 里同时用 AI 功能可能会遇到下面这些错误顺便一起讲清楚。5.1 settings.json 语法错误导致配置不生效最常见的不是颜色不对而是 JSON 写错了。比如最后一个属性后面多了逗号或者用了单引号。VSCode 会在编辑器底部提示Problems点开能看到具体行号。Cursor 同理。遇到配置完全不生效先看这里。5.2 401 报错API Key 无效或未配置如果你在 Cursor 或 VSCode 里接了 AI 编码插件比如 Cline、Continue调用模型时返回401 Unauthorized通常是 API Key 没填、填错或者 Base URL 和 Key 不匹配。这时候要检查三件套Base URL、API Key、Model ID 是否一致。以 TaoToken 为例Base URL 是https://taotoken.net/apiKey 在控制台生成Model ID 要和你实际调用的模型对应。三者任何一个不对都会 401。你可以在 API Keys 页面 重新生成一个 Key 试试。5.3 local proxy failed本地代理配置问题local proxy failed一般出现在插件尝试走本地代理转发请求时。检查插件的代理设置确认没有填一个不存在的本地端口。如果你用的是公司网络可能需要确认网络策略允许访问目标 API 地址。这个报错和主题配色无关但很多人会在同一个settings.json里同时配 AI 插件所以容易混在一起排查。5.4 reading choices 报错响应格式解析失败reading choices这类报错通常是插件在解析模型返回的 JSON 时发现choices字段读不到。原因可能是返回的不是标准 OpenAI 格式或者请求被中间层改写了。排查方法是看插件的日志确认请求的 endpoint 和返回体。如果用的是兼容 OpenAI 协议的服务确认 Base URL 结尾有没有多余的斜杠。5.5 OAuth 相关报错有些插件用 OAuth 登录报OAuth token expired或者OAuth callback failed一般是授权过期或者回调地址被占用。重新走一遍授权流程即可。这类报错和settings.json里的 token 颜色配置没有关系分开处理。5.6 颜色改了但只有部分生效如果关键字变了但注释没变或者反过来说明部分 scope 没命中。回到第 4 节用Inspect Editor Tokens and Scopes看实际 scope针对性补规则。C 和 C 的 scope 命名有细微差别.c文件和.cpp文件可能命中不同规则必要时两份都配。5.7 中文注释乱码Keil 工程常用 GB2312VSCode 默认 UTF-8打开就乱码。在settings.json里设files.encoding: gb2312和files.autoGuessEncoding: true基本能解决。如果个别文件还是乱码点右下角编码选Reopen with Encoding手动选 GB2312。6. 长期编码与 Agent 场景把配色和工具链一起固定下来配色调好只是第一步。如果你像我一样长期用 VSCode 和 Cursor 写嵌入式 C 代码还会涉及 AI 辅助编码、Agent 自动改代码这些场景。这时候建议把配置和工具链一起固定减少每次换环境的折腾。6.1 把 settings.json 纳入版本管理我习惯把用户级settings.json里的通用部分主题、字体、token 颜色抽出来放到一个 dotfiles 仓库换电脑时直接同步。项目级的.vscode/settings.json则跟着工程走里面放和这个项目相关的编码、格式化配置。这样配色和工程配置分离互不干扰。6.2 AI 编码插件的三件套配置如果你用 Cline、Continue 或者 Cursor 自带的 AI 功能配置里一定要写全三件套Base URL、API Key、Model ID。以 TaoToken 为例{ baseUrl: https://taotoken.net/api, apiKey: 你的Key, model: claude-sonnet-4-5 }Base URL 用https://taotoken.net/api不要加多余路径。Key 在 控制台 生成。Model ID 要和你实际想用的模型一致。三件套对齐401 和 reading choices 这类报错基本不会出现。6.3 长期编码场景建议用 Coding Plan如果你每天都要用 AI 辅助写代码、跑 Agent 任务按量付费可能不如包月划算。TaoToken 的 Coding Plan 适合长期编码和 Agent 场景配置方式和上面一样只是计费模式不同。我自己的体感是写嵌入式项目时AI 帮忙生成寄存器配置、解析数据手册片段效率提升明显配色舒服了之后盯着屏幕的时间也更长。6.4 验证模型是否连通配置完 AI 插件后想快速确认模型能不能通可以用 模型对话 页面发一条测试消息。能正常返回说明 Base URL 和 Key 没问题。如果报错对照第 5 节排查。6.5 接入文档和 Claude Code 场景如果你用的是 Claude Code 这类命令行 Agent接入方式略有不同需要配置环境变量或者配置文件。具体步骤可以看 接入文档。Claude Code 的配置里同样要写全 Base URL、Key、Model ID缺一不可。相关配置可以参考 ClaudeCodeAnthropic 接入说明。6.6 最后的实用建议配色这东西没有绝对标准。上面这套 Keil 风格配置是我自己用着舒服的版本你可以在此基础上微调。比如觉得函数名紫色太跳可以换成深蓝觉得注释斜体不习惯把fontStyle去掉。关键是先用Inspect Editor Tokens and Scopes搞清楚每个 scope 对应什么然后大胆改改完保存立即生效试错成本很低。另外浅色主题下长时间编码记得把屏幕亮度调低一点配合低饱和配色眼睛负担会小很多。这套配置我在 VSCode 和 Cursor 上用了大半年切回 Keil 的时候几乎无感算是把两边的视觉体验统一了。