From eb647248df912d96e004b9e16c3d413e3c740f93 Mon Sep 17 00:00:00 2001 From: wellwei Date: Tue, 4 Aug 2026 16:14:11 +0800 Subject: [PATCH 1/2] feat: add build.mcpp syntax highlighting --- CHANGELOG.md | 4 ++++ README.md | 12 ++++++------ package-lock.json | 4 ++-- package.json | 3 ++- test/artifacts.test.ts | 13 ++++++++++++- 5 files changed, 26 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 603a475..8cc4ac1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # 更新日志 +## 0.2.3 + +- 为精确文件名 `build.mcpp` 增加 C++ 语言关联,复用 VS Code 内置 C++ 高亮和现有模块语法注入;不扩大到所有 `*.mcpp` 文件。 + ## 0.2.2 - 新增 **mcpp: 一键配置模块代码提示**:自动检测匹配的 clangd,缺失时通过 xlings 下载 diff --git a/README.md b/README.md index c29732a..45b99b1 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ 把 mcpp 工程、C++ 模块语法和官方 clangd 扩展接入 VS Code。 -当前版本为 `0.2.2`。扩展负责工程发现、clangd 配置、模块状态检查以及常用 +当前版本为 `0.2.3`。扩展负责工程发现、clangd 配置、模块状态检查以及常用 mcpp CLI 操作;它不实现新的 C++ 语言服务器,也不替代 mcpp 的构建逻辑。 > 当前完整的模块语义能力只支持 LLVM/Clang 工具链。GCC 和 MSVC 工程仍可使用 @@ -17,7 +17,7 @@ mcpp CLI 操作;它不实现新的 C++ 语言服务器,也不替代 mcpp 的 | 能力 | LLVM/Clang | GCC | MSVC | | --- | --- | --- | --- | | 识别 mcpp 工程 | 支持 | 支持 | 支持 | -| `.cppm`、`.ixx`、`.mpp`、`.ccm` 文件关联 | 支持 | 支持 | 支持 | +| `build.mcpp`、`.cppm`、`.ixx`、`.mpp`、`.ccm` 文件关联 | 支持 | 支持 | 支持 | | `module`、`export module`、`import` 语法高亮 | 支持 | 支持 | 支持 | | 构建、运行、测试、清理命令 | 支持 | 支持 | 支持 | | 查看、安装或选择 mcpp 工具链 | 支持 | 支持 | 系统检测与选择 | @@ -35,7 +35,7 @@ mcpp CLI 操作;它不实现新的 C++ 语言服务器,也不替代 mcpp 的 VSIX,然后在 VS Code 中执行 **Extensions: Install from VSIX...**,或者运行: ```sh -code --install-extension /path/to/mcpp-vscode-0.2.2.vsix +code --install-extension /path/to/mcpp-vscode-0.2.3.vsix ``` 安装后确认当前 VS Code profile 中同时存在 `mcpp-community.mcpp-vscode` 和 @@ -80,7 +80,7 @@ xlings 安装。 ### C++ 模块语法高亮 -- 将 `.cppm`、`.ixx`、`.mpp` 和 `.ccm` 关联到 VS Code 内置 `cpp` 语言。 +- 将 `build.mcpp`、`.cppm`、`.ixx`、`.mpp` 和 `.ccm` 关联到 VS Code 内置 `cpp` 语言。 - 向 `source.cpp` 注入模块语法规则。 - 覆盖 `module`、`export module`、`import`、`export import`、模块名和模块分区。 - 支持尚未输入分号的编辑中间态。 @@ -371,8 +371,8 @@ API、状态栏、任务和 clangd 集成。 版本完全一致的 tag: ```sh -git tag -a v0.2.2 -m "mcpp-vscode 0.2.2" -git push origin v0.2.2 +git tag -a v0.2.3 -m "mcpp-vscode 0.2.3" +git push origin v0.2.3 ``` `.github/workflows/release.yml` 会校验 tag,执行测试和打包,生成 VSIX 与 SHA-256 文件, diff --git a/package-lock.json b/package-lock.json index b4291bd..36029a7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "mcpp-vscode", - "version": "0.2.1", + "version": "0.2.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "mcpp-vscode", - "version": "0.2.1", + "version": "0.2.3", "license": "Apache-2.0", "devDependencies": { "@types/node": "^24.0.0", diff --git a/package.json b/package.json index 73c50e4..4a29e69 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "mcpp-vscode", "displayName": "mcpp", "description": "mcpp 与 C++ 模块的 VS Code 集成", - "version": "0.2.2", + "version": "0.2.3", "publisher": "mcpp-community", "license": "Apache-2.0", "icon": "images/logo.png", @@ -134,6 +134,7 @@ }, "configurationDefaults": { "files.associations": { + "build.mcpp": "cpp", "*.ccm": "cpp", "*.cppm": "cpp", "*.ixx": "cpp", diff --git a/test/artifacts.test.ts b/test/artifacts.test.ts index dfc0f80..91db1af 100644 --- a/test/artifacts.test.ts +++ b/test/artifacts.test.ts @@ -24,7 +24,7 @@ const root = path.resolve(process.cwd()); test("declares the official clangd dependency and mcpp commands", () => { const manifest = JSON.parse(readFileSync(path.join(root, "package.json"), "utf8")) as PackageManifest; - assert.equal(manifest.version, "0.2.2"); + assert.equal(manifest.version, "0.2.3"); assert.ok(manifest.extensionDependencies?.includes("llvm-vs-code-extensions.vscode-clangd")); assert.ok(manifest.activationEvents?.includes("workspaceContains:mcpp.toml")); assert.equal(manifest.capabilities?.untrustedWorkspaces?.supported, "limited"); @@ -52,6 +52,7 @@ test("declares the official clangd dependency and mcpp commands", () => { assert.ok(manifest.contributes?.configuration?.properties?.["mcpp.path"]); assert.ok(manifest.contributes?.configuration?.properties?.["mcpp.modulesSupport"]); assert.deepEqual(manifest.contributes?.configurationDefaults?.["files.associations"], { + "build.mcpp": "cpp", "*.ccm": "cpp", "*.cppm": "cpp", "*.ixx": "cpp", @@ -59,6 +60,16 @@ test("declares the official clangd dependency and mcpp commands", () => { }); }); +test("associates the build.mcpp file with the C++ language", () => { + const manifest = JSON.parse(readFileSync(path.join(root, "package.json"), "utf8")) as PackageManifest; + const associations = manifest.contributes?.configurationDefaults?.["files.associations"] as + | Record + | undefined; + + assert.equal(associations?.["build.mcpp"], "cpp"); + assert.equal(associations?.["*.mcpp"], undefined); +}); + test("ships an injection grammar with module-specific scopes", () => { const manifest = JSON.parse(readFileSync(path.join(root, "package.json"), "utf8")) as PackageManifest; const grammar = manifest.contributes?.grammars?.find((item) => item.scopeName === "source.cpp.mcpp-modules"); From 15c5c1cc24ff1992f636f55db38f5e480a6c5676 Mon Sep 17 00:00:00 2001 From: wellwei Date: Tue, 4 Aug 2026 16:55:39 +0800 Subject: [PATCH 2/2] feat: add mcpp.toml syntax highlighting --- CHANGELOG.md | 5 +- README.md | 5 +- package.json | 17 +++++ syntaxes/mcpp-toml.tmLanguage.json | 116 +++++++++++++++++++++++++++++ test/artifacts.test.ts | 47 +++++++++++- 5 files changed, 187 insertions(+), 3 deletions(-) create mode 100644 syntaxes/mcpp-toml.tmLanguage.json diff --git a/CHANGELOG.md b/CHANGELOG.md index 8cc4ac1..ece9c0b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,10 @@ ## 0.2.3 -- 为精确文件名 `build.mcpp` 增加 C++ 语言关联,复用 VS Code 内置 C++ 高亮和现有模块语法注入;不扩大到所有 `*.mcpp` 文件。 +- 为精确文件名 `build.mcpp` 增加 C++ 语言关联,复用 VS Code 内置 C++ 高亮和现有模块 + 语法注入;不扩大到所有 `*.mcpp` 文件。 +- 为精确文件名 `mcpp.toml` 内置独立 TOML 语法高亮,不依赖额外扩展,也不接管普通 + `*.toml` 文件。 ## 0.2.2 diff --git a/README.md b/README.md index 45b99b1..d4402f7 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,7 @@ mcpp CLI 操作;它不实现新的 C++ 语言服务器,也不替代 mcpp 的 | 能力 | LLVM/Clang | GCC | MSVC | | --- | --- | --- | --- | | 识别 mcpp 工程 | 支持 | 支持 | 支持 | +| `mcpp.toml` TOML 语法高亮 | 支持 | 支持 | 支持 | | `build.mcpp`、`.cppm`、`.ixx`、`.mpp`、`.ccm` 文件关联 | 支持 | 支持 | 支持 | | `module`、`export module`、`import` 语法高亮 | 支持 | 支持 | 支持 | | 构建、运行、测试、清理命令 | 支持 | 支持 | 支持 | @@ -78,8 +79,10 @@ xlings 安装。 扩展激活本身不会静默运行 `mcpp build`,也不会自动下载、安装或切换工具链。 -### C++ 模块语法高亮 +### 语法高亮 +- 将精确文件名 `mcpp.toml` 识别为独立的 mcpp TOML 语言,内置表、键、字符串、数字、 + 布尔、日期时间和注释高亮。 - 将 `build.mcpp`、`.cppm`、`.ixx`、`.mpp` 和 `.ccm` 关联到 VS Code 内置 `cpp` 语言。 - 向 `source.cpp` 注入模块语法规则。 - 覆盖 `module`、`export module`、`import`、`export import`、模块名和模块分区。 diff --git a/package.json b/package.json index 4a29e69..650abfc 100644 --- a/package.json +++ b/package.json @@ -132,6 +132,18 @@ } } }, + "languages": [ + { + "id": "mcpp-toml", + "aliases": [ + "mcpp TOML", + "mcpp.toml" + ], + "filenames": [ + "mcpp.toml" + ] + } + ], "configurationDefaults": { "files.associations": { "build.mcpp": "cpp", @@ -142,6 +154,11 @@ } }, "grammars": [ + { + "language": "mcpp-toml", + "scopeName": "source.toml.mcpp", + "path": "./syntaxes/mcpp-toml.tmLanguage.json" + }, { "scopeName": "source.cpp.mcpp-modules", "injectTo": [ diff --git a/syntaxes/mcpp-toml.tmLanguage.json b/syntaxes/mcpp-toml.tmLanguage.json new file mode 100644 index 0000000..e0df854 --- /dev/null +++ b/syntaxes/mcpp-toml.tmLanguage.json @@ -0,0 +1,116 @@ +{ + "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json", + "name": "mcpp TOML", + "scopeName": "source.toml.mcpp", + "patterns": [ + { + "include": "#comment" + }, + { + "include": "#table" + }, + { + "include": "#key" + }, + { + "include": "#string" + }, + { + "include": "#datetime" + }, + { + "include": "#number" + }, + { + "include": "#boolean" + }, + { + "include": "#punctuation" + } + ], + "repository": { + "comment": { + "match": "#.*$", + "name": "comment.line.number-sign.toml" + }, + "table": { + "match": "^\\s*(\\[\\[?)([^\\]\\r\\n]+?)(\\]\\]?)\\s*(?=#|$)", + "captures": { + "1": { + "name": "punctuation.definition.table.begin.toml" + }, + "2": { + "name": "entity.name.section.toml" + }, + "3": { + "name": "punctuation.definition.table.end.toml" + } + } + }, + "key": { + "match": "^\\s*((?:[A-Za-z0-9_-]+|\"[^\"]+\"|'[^']+')(?:\\s*\\.\\s*(?:[A-Za-z0-9_-]+|\"[^\"]+\"|'[^']+'))*)\\s*(=)", + "captures": { + "1": { + "name": "variable.other.key.toml" + }, + "2": { + "name": "keyword.operator.assignment.toml" + } + } + }, + "string": { + "patterns": [ + { + "begin": "\"\"\"", + "end": "\"\"\"", + "name": "string.quoted.triple.basic.toml", + "patterns": [ + { + "include": "#escape" + } + ] + }, + { + "begin": "'''", + "end": "'''", + "name": "string.quoted.triple.literal.toml" + }, + { + "begin": "\"", + "end": "\"", + "name": "string.quoted.double.toml", + "patterns": [ + { + "include": "#escape" + } + ] + }, + { + "begin": "'", + "end": "'", + "name": "string.quoted.single.toml" + } + ] + }, + "escape": { + "match": "\\\\(?:[btnfr\"\\\\]|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})", + "name": "constant.character.escape.toml" + }, + "datetime": { + "match": "(?; configuration?: { properties?: Record }; configurationDefaults?: Record; - grammars?: Array<{ scopeName: string; injectTo?: string[]; path: string }>; + languages?: Array<{ id: string; aliases?: string[]; filenames?: string[] }>; + grammars?: Array<{ language?: string; scopeName: string; injectTo?: string[]; path: string }>; }; } @@ -70,6 +71,50 @@ test("associates the build.mcpp file with the C++ language", () => { assert.equal(associations?.["*.mcpp"], undefined); }); +test("ships TOML highlighting for the exact mcpp.toml filename", () => { + const manifest = JSON.parse(readFileSync(path.join(root, "package.json"), "utf8")) as PackageManifest; + const language = manifest.contributes?.languages?.find((item) => item.id === "mcpp-toml"); + assert.deepEqual(language, { + id: "mcpp-toml", + aliases: ["mcpp TOML", "mcpp.toml"], + filenames: ["mcpp.toml"], + }); + + const grammar = manifest.contributes?.grammars?.find((item) => item.language === "mcpp-toml"); + assert.deepEqual(grammar, { + language: "mcpp-toml", + scopeName: "source.toml.mcpp", + path: "./syntaxes/mcpp-toml.tmLanguage.json", + }); + + const grammarText = readFileSync(path.join(root, "syntaxes/mcpp-toml.tmLanguage.json"), "utf8"); + const grammarDocument = JSON.parse(grammarText) as { + repository?: Record; + }; + for (const key of ["comment", "table", "key", "string", "datetime", "number", "boolean", "punctuation"]) { + assert.ok(grammarDocument.repository?.[key], `missing TOML grammar rule: ${key}`); + } + + const tablePattern = new RegExp(grammarDocument.repository?.table.match ?? ""); + assert.match("[package]", tablePattern); + assert.match("[[target.generated]]", tablePattern); + + const keyPattern = new RegExp(grammarDocument.repository?.key.match ?? ""); + assert.match('standard = "c++23"', keyPattern); + assert.match('"quoted.key" = true', keyPattern); + + for (const scope of [ + "comment.line.number-sign.toml", + "entity.name.section.toml", + "variable.other.key.toml", + "string.quoted.double.toml", + "constant.numeric.toml", + "constant.language.boolean.toml", + ]) { + assert.match(grammarText, new RegExp(scope.replaceAll(".", "\\."))); + } +}); + test("ships an injection grammar with module-specific scopes", () => { const manifest = JSON.parse(readFileSync(path.join(root, "package.json"), "utf8")) as PackageManifest; const grammar = manifest.contributes?.grammars?.find((item) => item.scopeName === "source.cpp.mcpp-modules");