Skip to content

Commit fcd8296

Browse files
authored
Merge pull request #13 from mcpp-community/codex/fix-cdb-command-liveness
fix: keep IDE commands responsive after CDB removal
2 parents 0740431 + db80d42 commit fcd8296

12 files changed

Lines changed: 152 additions & 48 deletions

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# 更新日志
22

3+
## 0.3.1 - 2026-08-11
4+
5+
- 修复缺少 CDB 时 IDE 命令看似无响应的问题:配置 clangd、刷新编译数据库、检查模块支持和一键配置现在会立即显示进度并打开 `mcpp` 输出频道;clangd 重启与 `mcpp build --configure-only` 增加超时,避免异步操作永久占用 IDE 队列。
6+
- 增加删除 `compile_commands.json` 后刷新 CDB、配置 clangd、检查模块支持和一键配置的 Extension Host 回归测试。
7+
38
## 0.3.0 - 2026-08-11
49

510
- 将编译数据库刷新迁移到 `mcpp build --configure-only`:不解析 stdout 人类文本,以退出码

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
把 mcpp 工程、C++ 模块语法和官方 clangd 扩展接入 VS Code。
88

9-
当前版本为 `0.3.0`。扩展负责工程发现、clangd 配置、模块状态检查以及常用
9+
当前版本为 `0.3.1`。扩展负责工程发现、clangd 配置、模块状态检查以及常用
1010
mcpp CLI 操作;它不实现新的 C++ 语言服务器,也不替代 mcpp 的构建逻辑。
1111

1212
> 当前完整的模块语义能力只支持 LLVM/Clang 工具链。GCC 和 MSVC 工程仍可使用
@@ -37,7 +37,7 @@ mcpp CLI 操作;它不实现新的 C++ 语言服务器,也不替代 mcpp 的
3737
VSIX,然后在 VS Code 中执行 **Extensions: Install from VSIX...**,或者运行:
3838

3939
```sh
40-
code --install-extension /path/to/mcpp-vscode-0.3.0.vsix
40+
code --install-extension /path/to/mcpp-vscode-0.3.1.vsix
4141
```
4242

4343
安装后确认当前 VS Code profile 中同时存在 `mcpp-community.mcpp-vscode`
@@ -419,8 +419,8 @@ API、状态栏、任务和 clangd 集成。
419419
版本完全一致的 tag:
420420

421421
```sh
422-
git tag -a v0.3.0 -m "mcpp-vscode 0.3.0"
423-
git push origin v0.3.0
422+
git tag -a v0.3.1 -m "mcpp-vscode 0.3.1"
423+
git push origin v0.3.1
424424
```
425425

426426
`.github/workflows/release.yml` 会校验 tag,执行测试和打包,生成 VSIX 与 SHA-256 文件,

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "mcpp-vscode",
33
"displayName": "mcpp",
44
"description": "mcpp 与 C++ 模块的 VS Code 集成",
5-
"version": "0.3.0",
5+
"version": "0.3.1",
66
"publisher": "mcpp-community",
77
"license": "Apache-2.0",
88
"icon": "images/logo.png",

src/cliController.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -632,7 +632,7 @@ export class McppCliController {
632632
} catch {
633633
// 输出频道可能已经在窗口重载时释放。
634634
}
635-
await vscode.window.showErrorMessage(`mcpp:${message}`);
635+
void vscode.window.showErrorMessage(`mcpp:${message}`);
636636
}
637637
};
638638
}
@@ -679,15 +679,15 @@ export class McppCliController {
679679
const result = await runProcess(executable, args, workingDirectory(project));
680680
this.appendShortCommand("查看工具链", executable, args, result);
681681
if (result.exitCode !== 0) {
682-
await vscode.window.showErrorMessage(
682+
void vscode.window.showErrorMessage(
683683
`mcpp toolchain list 失败(退出码 ${result.exitCode})。请查看 mcpp 输出频道。`,
684684
);
685685
return undefined;
686686
}
687687

688688
const inventory = parseToolchainList(`${result.stdout}${result.stderr.length > 0 ? `\n${result.stderr}` : ""}`);
689689
if (!inventory.recognized) {
690-
await vscode.window.showErrorMessage(
690+
void vscode.window.showErrorMessage(
691691
"无法识别当前 mcpp toolchain list 输出;原始输出已保留在 mcpp 输出频道,请检查 mcpp 版本。",
692692
);
693693
return undefined;

src/configureOnly.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,18 @@
11
import { runProcess, type ProcessResult, type ProcessRunner } from "./process";
22

33
export const configureOnlyArguments = ["build", "--configure-only"] as const;
4+
// 配置阶段可能解析工具链和依赖,但不能无限期占住 IDE 操作队列。
5+
export const configureOnlyTimeoutMs = 5 * 60_000;
46

57
export function runConfigureOnly(
68
projectRoot: string,
79
executable = "mcpp",
810
runner: ProcessRunner = runProcess,
911
): Promise<ProcessResult> {
10-
return runner(executable, [...configureOnlyArguments], projectRoot);
12+
return runner(
13+
executable,
14+
[...configureOnlyArguments],
15+
projectRoot,
16+
{ timeoutMs: configureOnlyTimeoutMs },
17+
);
1118
}

src/extension.ts

Lines changed: 51 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ import {
4747
shouldRenderProjectStatus,
4848
shouldUseWorkspaceClangd,
4949
statusCommandForCapability,
50+
withTimeout,
5051
workspaceAllowsToolExecution,
5152
type ModuleSupportState,
5253
} from "./workflow";
@@ -306,12 +307,23 @@ async function maybeDisableCppTools(project: McppProjectDiscovery): Promise<void
306307
}
307308
}
308309

309-
async function restartClangd(): Promise<boolean> {
310+
const CLANGD_RESTART_TIMEOUT_MS = 15_000;
311+
312+
async function restartClangd(output: vscode.OutputChannel): Promise<boolean> {
310313
if (vscode.extensions.getExtension("llvm-vs-code-extensions.vscode-clangd") === undefined) {
311314
return false;
312315
}
313316
try {
314-
await vscode.commands.executeCommand("clangd.restart");
317+
const timedOut = {};
318+
const result = await withTimeout(
319+
vscode.commands.executeCommand("clangd.restart"),
320+
CLANGD_RESTART_TIMEOUT_MS,
321+
timedOut,
322+
);
323+
if (result === timedOut) {
324+
appendOutputLine(output, `[clangd] 重启命令超过 ${CLANGD_RESTART_TIMEOUT_MS / 1000} 秒未完成,已释放 IDE 操作队列。`);
325+
return false;
326+
}
315327
return true;
316328
} catch {
317329
// clangd 扩展可能尚未激活,但配置仍然已经写入。
@@ -329,7 +341,7 @@ async function configureClangd(
329341
const interactive = mode === "interactive";
330342
if (context.analysis.capability === "syntax-only") {
331343
if (interactive) {
332-
await vscode.window.showWarningMessage(
344+
void vscode.window.showWarningMessage(
333345
`${context.analysis.kind.toUpperCase()} 模块产物无法由 clangd 读取。语法高亮仍然可用,但模块语义诊断需要 LLVM mcpp 工具链。`,
334346
);
335347
}
@@ -338,7 +350,7 @@ async function configureClangd(
338350
}
339351
if (context.analysis.capability !== "full" || context.analysis.compilerPath === undefined) {
340352
if (interactive) {
341-
await vscode.window.showWarningMessage(
353+
void vscode.window.showWarningMessage(
342354
`${context.analysis.reason} 请先运行“mcpp: 刷新编译数据库”。`,
343355
);
344356
}
@@ -347,7 +359,7 @@ async function configureClangd(
347359
if (!workspaceAllowsToolExecution(vscode.workspace.isTrusted)) {
348360
const message = "当前工作区未受信任,mcpp 不会执行 CDB 中的编译器或 clangd,也不会接管 clangd 配置。";
349361
if (interactive) {
350-
await vscode.window.showWarningMessage(message);
362+
void vscode.window.showWarningMessage(message);
351363
} else {
352364
appendOutputLine(output, `[自动配置] ${message}`);
353365
}
@@ -358,7 +370,7 @@ async function configureClangd(
358370
if (clangd === undefined) {
359371
const message = "没有找到可用的 clangd。请安装与 mcpp LLVM 编译器来自同一 revision 的 clangd,或设置 mcpp.clangd.path;clangd 可以来自 xlings llvm-tools,也可以独立安装。";
360372
if (interactive) {
361-
await vscode.window.showErrorMessage(message);
373+
void vscode.window.showErrorMessage(message);
362374
} else {
363375
appendOutputLine(output, `[自动配置] ${message}`);
364376
}
@@ -399,11 +411,11 @@ async function configureClangd(
399411
await maybeDisableCppTools(context.project);
400412
}
401413
const restartRequired = shouldRestartClangd(plan.changed, interactive, forceRestart);
402-
const restartSucceeded = restartRequired ? await restartClangd() : false;
414+
const restartSucceeded = restartRequired ? await restartClangd(output) : false;
403415
if (!configurationReadyAfterRestart(restartRequired, restartSucceeded)) {
404416
const message = "clangd 配置已写入,但无法重启语言服务器。请查看 mcpp 输出频道,或手动执行 clangd 重启命令。";
405417
if (interactive) {
406-
await vscode.window.showErrorMessage(message);
418+
void vscode.window.showErrorMessage(message);
407419
} else {
408420
appendOutputLine(output, `[自动配置] ${message}`);
409421
}
@@ -412,11 +424,11 @@ async function configureClangd(
412424
updateStatusBar(status, context);
413425

414426
if (!clangd.comparison.compatible) {
415-
await vscode.window.showWarningMessage(
427+
void vscode.window.showWarningMessage(
416428
`clangd 已配置,但 LLVM 身份与 mcpp 编译器不匹配:${clangd.comparison.reason}。`,
417429
);
418430
} else if (interactive) {
419-
await vscode.window.showInformationMessage("mcpp 已为当前工作区配置匹配的 clangd。");
431+
void vscode.window.showInformationMessage("mcpp 已为当前工作区配置匹配的 clangd。");
420432
} else if (plan.changed) {
421433
appendOutputLine(output, `[自动配置] clangd.path = ${plan.path}`);
422434
}
@@ -546,7 +558,7 @@ async function runModuleSupportCheck(
546558
storeModuleStatus(status, context, { state: "unavailable", message });
547559
}
548560
if (interactive) {
549-
await vscode.window.showWarningMessage(message);
561+
void vscode.window.showWarningMessage(message);
550562
}
551563
return context.analysis.capability === "full"
552564
? { state: "unavailable", message }
@@ -559,7 +571,7 @@ async function runModuleSupportCheck(
559571
const moduleStatus = { state: "unavailable", message } as const;
560572
storeModuleStatus(status, context, moduleStatus);
561573
if (interactive) {
562-
await vscode.window.showWarningMessage(message);
574+
void vscode.window.showWarningMessage(message);
563575
} else {
564576
appendOutputLine(output, `[自动检查] ${message}`);
565577
}
@@ -583,7 +595,7 @@ async function runModuleSupportCheck(
583595
return undefined;
584596
}
585597
if (interactive) {
586-
await vscode.window.showErrorMessage(message);
598+
void vscode.window.showErrorMessage(message);
587599
} else {
588600
appendOutputLine(output, `[自动检查] ${message}`);
589601
}
@@ -630,9 +642,9 @@ async function runModuleSupportCheck(
630642
}
631643
if (interactive) {
632644
if (moduleStatus.state === "available") {
633-
await vscode.window.showInformationMessage(message);
645+
void vscode.window.showInformationMessage(message);
634646
} else {
635-
await vscode.window.showErrorMessage(message);
647+
void vscode.window.showErrorMessage(message);
636648
}
637649
} else {
638650
appendOutputLine(output, `[自动检查] ${message}`);
@@ -751,7 +763,7 @@ async function autoConfigureModulesWizard(
751763
appendOutputLine(output, "[一键配置] 开始一键配置模块代码提示...");
752764

753765
if (!vscode.workspace.isTrusted) {
754-
await vscode.window.showWarningMessage(moduleSetupBlockedMessage("untrusted"));
766+
void vscode.window.showWarningMessage(moduleSetupBlockedMessage("untrusted"));
755767
return;
756768
}
757769
const inventory = await cliController.readToolchainInventory(context.project);
@@ -765,7 +777,7 @@ async function autoConfigureModulesWizard(
765777
cliController.isBusy(),
766778
);
767779
if (decision.kind === "blocked") {
768-
await vscode.window.showWarningMessage(moduleSetupBlockedMessage(decision.reason));
780+
void vscode.window.showWarningMessage(moduleSetupBlockedMessage(decision.reason));
769781
return;
770782
}
771783

@@ -861,14 +873,14 @@ async function autoConfigureModulesWizard(
861873

862874
if (outcome.state === "succeeded") {
863875
if (outcome.degraded) {
864-
await vscode.window.showWarningMessage("构建失败,语言服务已刷新。请查看任务终端获取构建错误。");
876+
void vscode.window.showWarningMessage("构建失败,语言服务已刷新。请查看任务终端获取构建错误。");
865877
} else {
866-
await vscode.window.showInformationMessage("mcpp 模块代码提示一键配置完成。");
878+
void vscode.window.showInformationMessage("mcpp 模块代码提示一键配置完成。");
867879
}
868880
} else if (outcome.state === "cancelled") {
869-
await vscode.window.showWarningMessage(`一键配置已取消(${outcome.stage})。`);
881+
void vscode.window.showWarningMessage(`一键配置已取消(${outcome.stage})。`);
870882
} else {
871-
await vscode.window.showErrorMessage(`一键配置失败(${outcome.stage})。${outcome.steps.at(-1)?.detail ?? "请查看 mcpp 输出频道。"}`);
883+
void vscode.window.showErrorMessage(`一键配置失败(${outcome.stage})。${outcome.steps.at(-1)?.detail ?? "请查看 mcpp 输出频道。"}`);
872884
}
873885
}
874886

@@ -931,6 +943,10 @@ export async function activate(extensionContext: vscode.ExtensionContext): Promi
931943
void vscode.window.showErrorMessage(`mcpp:${message}`);
932944
}
933945
};
946+
const showInteractiveIdeStart = (title: string): void => {
947+
appendOutputLine(output, `\n[IDE] ${title}:已接收,正在等待 IDE 操作队列。`);
948+
output.show(true);
949+
};
934950
let cliController: McppCliController;
935951
const runConfigureOnlyForProject = async (
936952
project: McppProjectDiscovery,
@@ -939,7 +955,7 @@ export async function activate(extensionContext: vscode.ExtensionContext): Promi
939955
if (!workspaceAllowsToolExecution(vscode.workspace.isTrusted)) {
940956
appendOutputLine(output, "[CDB 配置] 工作区未受信任,跳过 mcpp build --configure-only。");
941957
if (interactive) {
942-
await vscode.window.showWarningMessage(
958+
void vscode.window.showWarningMessage(
943959
"当前工作区未受信任,不会刷新编译数据库。请先信任工作区。",
944960
);
945961
}
@@ -949,7 +965,7 @@ export async function activate(extensionContext: vscode.ExtensionContext): Promi
949965
if (result === undefined) {
950966
appendOutputLine(output, "[CDB 配置] 已有 mcpp 操作正在运行,本次刷新已跳过。");
951967
if (interactive) {
952-
await vscode.window.showWarningMessage(
968+
void vscode.window.showWarningMessage(
953969
"已有 mcpp 操作正在运行,暂不能刷新编译数据库。请等待当前操作完成后重试。",
954970
);
955971
}
@@ -1204,7 +1220,7 @@ export async function activate(extensionContext: vscode.ExtensionContext): Promi
12041220
if (kind === "build") {
12051221
if (reconciled.context?.analysis.capability === "syntax-only") {
12061222
const buildMessage = completion.state === "succeeded" ? "mcpp 构建完成" : "mcpp 构建失败";
1207-
await vscode.window.showWarningMessage(
1223+
void vscode.window.showWarningMessage(
12081224
`${buildMessage}${reconciled.context.analysis.reason}。模块语法高亮仍然可用。`,
12091225
);
12101226
return;
@@ -1215,18 +1231,18 @@ export async function activate(extensionContext: vscode.ExtensionContext): Promi
12151231
reconciled.configured,
12161232
);
12171233
if (outcome.level === "information") {
1218-
await vscode.window.showInformationMessage(outcome.message);
1234+
void vscode.window.showInformationMessage(outcome.message);
12191235
} else if (outcome.level === "warning") {
1220-
await vscode.window.showWarningMessage(outcome.message);
1236+
void vscode.window.showWarningMessage(outcome.message);
12211237
} else {
1222-
await vscode.window.showErrorMessage(outcome.message);
1238+
void vscode.window.showErrorMessage(outcome.message);
12231239
}
12241240
return;
12251241
}
12261242

12271243
if (completion.state === "succeeded") {
12281244
const label = kind === "run" ? "运行" : kind === "test" ? "测试" : "清理";
1229-
await vscode.window.showInformationMessage(`mcpp ${label}完成;clangd/CDB 状态已重新检查。`);
1245+
void vscode.window.showInformationMessage(`mcpp ${label}完成;clangd/CDB 状态已重新检查。`);
12301246
}
12311247
};
12321248
cliController = new McppCliController({
@@ -1251,6 +1267,7 @@ export async function activate(extensionContext: vscode.ExtensionContext): Promi
12511267
await vscode.window.showWarningMessage("当前工作区没有找到 mcpp.toml。");
12521268
return;
12531269
}
1270+
showInteractiveIdeStart("配置 clangd");
12541271
await executeWithWorkspaceClangd(async () => {
12551272
if (!shouldUseWorkspaceClangd(findCurrentProject()?.root, project.root)) {
12561273
return;
@@ -1269,6 +1286,7 @@ export async function activate(extensionContext: vscode.ExtensionContext): Promi
12691286
await vscode.window.showWarningMessage("当前工作区没有找到 mcpp.toml。");
12701287
return;
12711288
}
1289+
showInteractiveIdeStart("刷新编译数据库");
12721290
await executeWithWorkspaceClangd(async () => {
12731291
const hadUsableDatabase = hasUsableCompilationDatabase(project);
12741292
const result = await runConfigureOnlyForProject(project, true);
@@ -1284,11 +1302,11 @@ export async function activate(extensionContext: vscode.ExtensionContext): Promi
12841302
reconciled.configured,
12851303
);
12861304
if (outcome.level === "information") {
1287-
await vscode.window.showInformationMessage(outcome.message);
1305+
void vscode.window.showInformationMessage(outcome.message);
12881306
} else if (outcome.level === "warning") {
1289-
await vscode.window.showWarningMessage(outcome.message);
1307+
void vscode.window.showWarningMessage(outcome.message);
12901308
} else {
1291-
await vscode.window.showErrorMessage(outcome.message);
1309+
void vscode.window.showErrorMessage(outcome.message);
12921310
}
12931311
});
12941312
})),
@@ -1298,6 +1316,7 @@ export async function activate(extensionContext: vscode.ExtensionContext): Promi
12981316
await vscode.window.showWarningMessage("当前工作区没有找到 mcpp.toml。");
12991317
return;
13001318
}
1319+
showInteractiveIdeStart("检查模块支持");
13011320
await executeWithWorkspaceClangd(async () => {
13021321
if (!shouldUseWorkspaceClangd(findCurrentProject()?.root, project.root)) {
13031322
return;
@@ -1401,6 +1420,7 @@ export async function activate(extensionContext: vscode.ExtensionContext): Promi
14011420
await vscode.window.showWarningMessage("当前工作区没有找到 mcpp.toml。");
14021421
return;
14031422
}
1423+
showInteractiveIdeStart("一键配置模块代码提示");
14041424
await executeWithWorkspaceClangd(async () => {
14051425
if (!shouldUseWorkspaceClangd(findCurrentProject()?.root, project.root)) {
14061426
return;

0 commit comments

Comments
 (0)