Skip to content

mcpp-language-server 0.0.13: completion while modules build, one failed module leaves the others, build.mcpp edited safely, a log and an overview that say what runs and why - #54

Merged
Sunrisepeak merged 17 commits into
mainfrom
release/0.0.13
Oct 12, 2026
Merged

Sunrisepeak merged 17 commits into
mainfrom
release/0.0.13

Conversation

@Sunrisepeak

@Sunrisepeak Sunrisepeak commented Oct 11, 2026 •

Copy link
Copy Markdown
Owner

Implements .agents/docs/2026-10-12-0.0.13-design.md in one PR, one commit per checkpoint (C1–C9). The engine side is Sunrisepeak/mcppls-clangd#5 (mcppls-clangd 0.0.13, 23.1.0-mcppls.1); this PR's CI tested its build through packaging/engine-candidate.json, and the payload now pins the released v0.0.13 archives.

What changes for a person

  • Completion while modules are built (engine 0027): a module importer's first preamble is waited for at most 600 ms and a newly imported module at most 250 ms; the answer is marked incomplete and the editor asks again.
  • One module that does not compile leaves the others (clangd 23 module builder: one failed module (hello.test) blanks ALL completions — "Failed to compile src/test.cppm" while the project toolchain builds it fine #47; engine 0028, WA-CLANGD-014 for older engines): importers keep every other module, and the failed import says why.
  • build.mcpp: a build program that does not compile leaves the project its complete description (build-program-failed, mcpp's error on the file, no restart); a change is applied once saved, quiet and compiling (build-program-held, buildProgram.apply, C++ Modules: Apply build.mcpp); an include the build has not generated says so.
  • Opening again: a checkout that rewrites build files with their own bytes keeps the cached model; a stale one says which input changed.
  • mcppls 在Windows上运行缓慢 #53: a file typed into without a pause is not taken for a build clangd will not finish; non-file watched URIs no longer make clangd refuse the notification.
  • Seeing what runs (S3-4-31..33): about in the status and report (VS Code hub overview: versions, click to copy, running state; version-mismatch notice). A default log says what each start cost, why each module was rebuilt (engine 0026), a health line every ten minutes, with clangd's command echo at debug; docs/50-troubleshooting.md lists the lines.

Tests

Unit tests (server: SpinWatch per version, log reader, input stamps; VS Code: hub overview), new fixtures build-program-broken, build-program-gated, build-program-manual, mcpp-rules-generated G1b. Engine: unit tests, ci/module_resilience_canary.py. A temporary Windows probe (a large module project) compares the candidate with 0.0.12, digested inside Actions.

Not in this release

The design's §10 lists what was deferred and why (persisted validation memo, preamble reuse across sessions, commands re-read without a restart, Windows build concurrency, std shared across workspaces): each first needs the numbers the new log lines give.

…ays what builds cost, SpinWatch per version

- W7: the mcpp version is remembered with the producer's answer, so every describe reports it.
  The status, the report and the log's first lines carry `about` (server, extension, editor,
  engine and its restarts, kit, mcpp, platform; no paths). A server other than the one the editor
  package ships is a version-mismatch notice. The VS Code hub's overview opens with the versions
  (copied on click) and the running state.
- W6: the two lines clangd echoes after every AST build header go to debug; they were most of a
  default log, and the limiter left the rest out. What a build cost (a file's modules, a preamble,
  a module built or rebuilt) is said at info, limited apart from chatter, and so are clangd's
  errors.
- W4 (#53): SpinWatch times each version clangd's log says it began. A file typed into without a
  pause was rebuilt version after version under one 'parsing main file' status, and six 2-4 s
  builds were taken for one 21 s build that would never end.
…ritten with its own bytes stays fresh; the timers say what held the loop

- W5/W6: the model cache keeps each input's stamp and, for build description files, its content
  hash. A checkout or a branch switch that rewrites them with the bytes they had leaves the cache
  fresh (every warm start of the large Windows probe began 'older than its inputs' after one).
  Otherwise the log and the stale reason name the input that changed. A cache an older server
  wrote is judged by its fingerprint, as before.
- W6: the engine's new info lines (why a module is rebuilt, what a file's prerequisites cost, why
  a preamble is not reused, an answer before its modules) are told at info.
- W10 (#53): only file: URIs of a watched-files notification reach clangd, which refused the whole
  notification for one other. A turn of a root's timers over a second says which part took it.
…complete description; mcpp's error is on the file

W3: mcpp answers a describe whose build program did not compile or run with what it could
describe and MCPP_BUILD_DATABASE_PROGRAM_FAILED. That answer lacks what the build program gives the
targets (their flags, the units its rules generate); taken, it cost a Qt project its headers and
three clangd restarts in two minutes of typing build.mcpp, and a warm start on a large Windows
project ended degraded although nobody had edited anything.

The model in hand is now kept when it is complete. The state stays ready, with a
build-program-failed notice that says since when; mcpp's compile errors are diagnostics on the
build program at their lines (its first line when none names one); clangd is not restarted. The
next complete answer is taken. With no complete model yet (a cold start), the answer is used as
before, and the errors still reach the file.

Fixture build-program-broken (Linux, macOS).
…d compiles; buildProgram.apply, C++ Modules: Apply build.mcpp

W3(a): describing an mcpp project compiles and runs its build programs, and every autosave of
build.mcpp used to describe it again 1.5 s later. A change to a build program is now applied
once the file on disk is what the editor has, two seconds after its last change, and not while
clangd (which reads build.mcpp with its own set's arguments, mcpp 2026.10.11.1 and later) says
it does not compile -- the status says so (build-program-held) and the file's next diagnostics
check again. A file clangd is not given, or no verdict within ten seconds, leaves the decision
to mcpp; a failure keeps the model (C5).

New setting buildProgram.apply (auto | manual) and server command mcppls.applyBuildProgram
(VS Code: C++ Modules: Apply build.mcpp), which applies past the wait.

Fixtures build-program-gated (four saves in a row, one describe) and build-program-manual.
… importers itself; a start says what it cost in one line

- W2 (#47): WA-CLANGD-014 registers what the server does for clangd 23.1, which gives an importer of
  a module that does not compile no module at all: its importers are served by mcppls's own engine
  until the module changes. It retires for an engine that declares partial-prerequisite-modules
  (mcppls-clangd 0.0.13): clangd serves them with the modules that do compile, and its 'module not
  found' for the failed one (or a missing hint file) says which module did not compile and why,
  with the code and words of the diagnostic the workaround publishes.
- W6: when a root is first ready, one line says what its start cost (model and origin, engine,
  first diagnostics, first completion, modules built by why, restarts, ready); the report carries it
  and the last five starts of the workspace (<cache>/startups.json). The engine counts the modules
  it builds by why (mcppls-clangd says it: no BMI, another command, a changed input, an invalid
  BMI) and the report lists the latest. Every ten minutes of use, a health line: completion, hover
  and definition p50/p95 and the core engine's share, the engine's state, restarts and builds.
  A restart that is not counted against clangd says so instead of '(user)'.
…at to do

W3(d): where clangd reports a file not found that the build generates -- a generated file by its
name, or any include of a file of the project while a rule's output directory is still missing --
the diagnostic says the build has not generated it and to build once (C++ Modules: Build in
Terminal), with code generated-file-missing. mcpp-rules-generated checks it (G1b).
…e log's lines documented

- A start's own line and the startup banner read their JSON as an object (a one-element brace
  initializer made both an array: the first threw at the first ready, the second dropped the
  versions).
- S3-4-31..33 (s3-lsp-extensions.md, specs CHANGELOG, traceability): `about`, the version-mismatch
  notice, build-program-failed and build-program-held; mcppls.applyBuildProgram.
- docs/50-troubleshooting.md: what the default log says, line by line, and the new symptoms.
- CHANGELOG 0.0.13; every site at 0.0.13.
…ded is said, build.mcpp edge cases

- W4: clangd names a file D:\\src\\... on Windows where documents are D:/src/...; the AST build
  header now finds its document there too (the platform #53 came from).
- W6: the startup line is written when the root first settles, ready or degraded, and says which.
- W3(a): a build.mcpp with a UTF-8 BOM is compared with the editor's text without it; one saved and
  then edited without another save is applied after ten seconds as saved; Apply build.mcpp
  describes the project again even when no change is waiting.
- W3(b): mcpp's diagnostics on a build program that is not open use its path as the root spells it.
… base

The lock pins a maintained engine (23.1.0-mcppls.0) and the candidate is the next one
(23.1.0-mcppls.1): payload assembly refused it, since a maintained lock asks for its own fork
version exactly. payload --candidate, which only CI's candidate path passes with --clangd, takes
another fork version of the same base, its identity still checked; a release cannot set it.
… serves their importers itself

failure-at-base with the candidate engine: WA-CLANGD-014 retired, no file changes hands, and the
modules-doomed issue was never written (it was updated only with a hand-over). The modules still
cannot be prepared, and the status says which and why.
…ppls.1) on every platform; the candidate engine file goes
…when its file is closed: there is no editor left to wait on
@Sunrisepeak
Sunrisepeak marked this pull request as ready for review October 12, 2026 00:25
@Sunrisepeak
Sunrisepeak merged commit 6dee863 into main Oct 12, 2026
62 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant