Skip to content

Commit d5b953a

Browse files
committed
fix: PR #9 review 打磨——补 [build-dependencies] 段头、[[...]] 数组表不出建议、README 文档化
- SECTION_HEADERS 增加 [build-dependencies](mcpp 真实依赖表,契约测试已覆盖) - [[...]] 数组表段头不提供建议,避免把数组表意图悄悄替换成普通段 [x] - 补行为测试(数组表 / build-dependencies 模板)与段头注册表关键组断言 - README:能力矩阵、已实现功能、设置三处补充结构补全说明
1 parent be14ad9 commit d5b953a

4 files changed

Lines changed: 38 additions & 2 deletions

File tree

README.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ mcpp CLI 操作;它不实现新的 C++ 语言服务器,也不替代 mcpp 的
1818
| --- | --- | --- | --- |
1919
| 识别 mcpp 工程 | 支持 | 支持 | 支持 |
2020
| `mcpp.toml` TOML 语法高亮 | 支持 | 支持 | 支持 |
21+
| `mcpp.toml` 结构补全(段头 + 写法模板) | 支持 | 支持 | 支持 |
2122
| `build.mcpp``.cppm``.ixx``.mpp``.ccm` 文件关联 | 支持 | 支持 | 支持 |
2223
| `module``export module``import` 语法高亮 | 支持 | 支持 | 支持 |
2324
| 构建、运行、测试、清理命令 | 支持 | 支持 | 支持 |
@@ -97,6 +98,19 @@ TextMate 语法规则提供。
9798
`import mcpp;` 不会再被误报为缺少 C++ 模块。真正的 mcpp API 补全需要 mcpp 核心
9899
未来生成宿主 helper 的 CDB 和 PCM 映射。
99100

101+
### mcpp.toml 结构补全
102+
103+
- 段头补全:26 个段(`[package]``[targets.<name>]``[dependencies]``[build-dependencies]`
104+
`[features]``[indices]``[pack]` 等),参数化段带可跳转占位符。
105+
- 写法模板:依赖段的依赖写法(版本 / 路径 / git / features / tools)、`[features]` 表形式、
106+
capabilities / xlings / tools.overrides / generated_files 等开放段的条目形态。
107+
- 每条建议携带显式替换范围,部分输入(`[dep``na`)不会残留无效文本;所有语义规则有真实
108+
mcpp 契约测试(44 例,无 mcpp 环境自动跳过)。
109+
- 范围边界:不提供静态字段键/枚举(等上游版本化 manifest schema),不提供依赖包名/版本候选
110+
(等上游批量 catalog 接口);未知自定义段与 `[[...]]` 数组表不提供建议。
111+
-`mcpp.tomlCompletion` 设置控制(默认开启);未受信任工作区仅做纯文本分析,不执行任何
112+
外部程序。
113+
100114
### LLVM 与 clangd 集成
101115

102116
扩展读取 mcpp 生成的 `compile_commands.json`,然后:
@@ -172,7 +186,8 @@ xlings 补齐匹配版本的 llvm-tools(含 clangd),最后重新读取 CDB
172186
"mcpp.path": "/path/to/mcpp",
173187
"mcpp.clangd.path": "/path/to/matching/clangd",
174188
"mcpp.modulesSupport": "auto",
175-
"mcpp.configureCppTools": true
189+
"mcpp.configureCppTools": true,
190+
"mcpp.tomlCompletion": true
176191
}
177192
```
178193

@@ -182,6 +197,7 @@ xlings 补齐匹配版本的 llvm-tools(含 clangd),最后重新读取 CDB
182197
| `mcpp.clangd.path` || 与 CDB 中 LLVM 编译器匹配的 clangd;空值表示自动发现 |
183198
| `mcpp.modulesSupport` | `auto` | `auto``on``off`,控制 clangd 实验模块参数 |
184199
| `mcpp.configureCppTools` | `true` | 手动配置 clangd 时,是否询问关闭当前工作区的 cpptools IntelliSense |
200+
| `mcpp.tomlCompletion` | `true` |`mcpp.toml` 提供结构补全:段头与写法模板(snippet);所有建议带显式替换范围,并经真实 mcpp 契约测试验证 |
185201

186202
`mcpp.path` 只影响插件执行 mcpp CLI 命令。工程实际编译器来自
187203
`compile_commands.json``mcpp.clangd.path` 只指定语言服务器,三者相互独立。

src/mcppTomlCompletion.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ export const SECTION_HEADERS: readonly SectionHeaderSpec[] = [
4343
{ group: "generated_files", label: "[generated_files]", header: "[generated_files]", detail: "生成文件(路径 → 内容)" },
4444
{ group: "dependencies", label: "[dependencies]", header: "[dependencies]", detail: "运行时依赖" },
4545
{ group: "dev-dependencies", label: "[dev-dependencies]", header: "[dev-dependencies]", detail: "开发/测试依赖" },
46+
{ group: "build-dependencies", label: "[build-dependencies]", header: "[build-dependencies]", detail: "构建期依赖(仅构建期拉取,运行时不可见)" },
4647
{ group: "workspace", label: "[workspace]", header: "[workspace]", detail: "工作空间成员声明" },
4748
{ group: "workspace.dependencies", label: "[workspace.dependencies]", header: "[workspace.dependencies]", detail: "集中声明依赖版本,成员用 workspace = true 继承" },
4849
{ group: "features", label: "[features]", header: "[features]", detail: "feature 定义" },
@@ -189,6 +190,11 @@ export function computeMcppTomlCompletions(
189190
const context = contextAt(lines, line, character);
190191

191192
if (context.kind === "section-header") {
193+
// mcpp manifest 不使用 TOML 数组表([[...]]);[[ 内不提供建议,
194+
// 避免把用户意图的数组表悄悄替换成普通段 [x](未知段会被 mcpp 静默忽略)。
195+
if (context.isArray) {
196+
return [];
197+
}
192198
// parser 的替换范围从段名 token 开始;段头建议插入的是完整 "[xxx]",
193199
// 需要把范围扩展到本行的 "[",避免留下 "[["。仅当 "[" 是行内首个
194200
// 非空白字符时才扩展(section-header 上下文正常都满足,防御奇怪输入)。

test/mcppTomlCompletion.test.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ test("suggests section headers on a partial bracket line", () => {
1515
assert.ok(suggestions.length > 0);
1616
assert.ok(suggestions.every((suggestion) => suggestion.kind === "section"));
1717
assert.ok(labels(suggestions).includes("[dependencies]"));
18+
assert.ok(labels(suggestions).includes("[build-dependencies]"));
1819
assert.ok(labels(suggestions).includes("[workspace]"));
1920
assert.ok(labels(suggestions).includes("[indices]"));
2021
// 每条建议都带显式替换范围(覆盖已输入的 "[dep")。
@@ -26,6 +27,13 @@ test("suggests section headers on a partial bracket line", () => {
2627
assert.equal(targets?.insertSnippet, "[targets.${1:name}]");
2728
});
2829

30+
test("offers nothing inside [[...]] array-table headers", () => {
31+
// mcpp manifest 不使用 TOML 数组表([[...]]):[[ 内不出建议,
32+
// 避免把用户意图的数组表悄悄替换成普通段 [x]。
33+
assert.deepEqual(computeMcppTomlCompletions(["[[dep"], 0, 5), []);
34+
assert.deepEqual(computeMcppTomlCompletions(["[[dependencies]"], 0, 3), []);
35+
});
36+
2937
test("suggests section headers at the top of the document", () => {
3038
const suggestions = computeMcppTomlCompletions([""], 0, 0);
3139
assert.ok(suggestions.length > 0);
@@ -61,6 +69,12 @@ test("suggests dependency templates in conditional dependency sections", () => {
6169
assert.ok(labels(suggestions).includes('name = "version"'));
6270
});
6371

72+
test("suggests dependency templates in build-dependencies", () => {
73+
const suggestions = computeMcppTomlCompletions(["[build-dependencies]", ""], 1, 0);
74+
assert.ok(labels(suggestions).includes('name = "version"'));
75+
assert.ok(suggestions.every((suggestion) => suggestion.kind === "template"));
76+
});
77+
6478
test("suggests templates in free-key sections", () => {
6579
const features = computeMcppTomlCompletions(["[features]", ""], 1, 0);
6680
assert.ok(features.every((suggestion) => suggestion.kind === "template"));

test/mcppTomlContract.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ function fixtureFor(entry: SectionHeaderSpec): { manifest: string; files: Record
121121
test("段头注册表形态:数量与关键段齐全(防止测试与实现脱节)", { skip: skipReason }, () => {
122122
assert.ok(SECTION_HEADERS.length >= 20, `段头注册表只有 ${SECTION_HEADERS.length} 条(期望 ≥ 20)`);
123123
const groups = new Set(SECTION_HEADERS.map((entry) => entry.group));
124-
for (const key of ["package", "dependencies", "workspace", "pack"]) {
124+
for (const key of ["package", "dependencies", "build-dependencies", "workspace", "pack"]) {
125125
assert.ok(groups.has(key), `段头注册表缺少关键段 ${key}`);
126126
}
127127
const labels = SECTION_HEADERS.map((entry) => entry.label);

0 commit comments

Comments
 (0)