Skip to content

mcpp-language-server 0.0.14: Windows -- opening a project again and completion as you type - #56

Merged
Sunrisepeak merged 16 commits into
mainfrom
release/0.0.14
Oct 12, 2026
Merged

Sunrisepeak merged 16 commits into
mainfrom
release/0.0.14

Conversation

@Sunrisepeak

@Sunrisepeak Sunrisepeak commented Oct 12, 2026 •

Copy link
Copy Markdown
Owner

Implements .agents/docs/2026-10-12-windows-performance-plan.md in one PR, one commit per checkpoint. The engine side is Sunrisepeak/mcppls-clangd#7, released as mcppls-clangd 0.0.15 (23.1.0-mcppls.3, 32 patches, three new); this PR's CI tested its build through packaging/engine-candidate.json and now pins the released archives.

What changes

  • A module that includes <windows.h> no longer carries all of it (engine 0032): a reduced BMI left in every declaration of an extern "C" block its global module fragment includes; nearly all of <windows.h> and of a C library's headers is in such blocks. Found from the cost lines below once the input checks were down to 10 ms.
  • Completion lists come whole (A2): clangd gives up to 1000 items, so the editor filters a list as you type instead of asking again per key; a client asking at every key is answered from the word's complete list (A1).
  • Module checks by where inputs come from (engine 0030): an mcpp/xlings package version is checked by its install markers, system headers (the Windows SDK's and Visual Studio's included) once per session, the project's files every time.
  • Memos kept across sessions (engine 0030): BMI verdicts and dependency scans are read back by the next session and checked again before use.
  • The last session's files are ready first (G1), and adopted by the editor without reopening -- built, or still being built with the same text, without sending it again.
  • Windows: preambles in memory with 16 GiB or more (mcppls.engine.preambleStorage); a cache off a Dev Drive is said once (about.cacheDevDrive, S3-4-34); six retained ASTs with 16 GiB or more.
  • Seeing it: a slow module completion's cost line, the memos kept, the package stores used.
  • Fixes found on the way: four nlohmann Json x { y } sites that built a one-element array (the sweep by category ran nothing; C-2 let go of a late completion under the wrong id); two test programs that never reported failures.

Measured (Windows CI)

before after
ux-modules-windows-large (30 module units including <windows.h>): idle completion p95 1.01 s, half past the budget 0.45 s, all from clangd
same, completion while typing (U17) p95 1.02 s 0.57 s
same, clangd's time per completion 430 / 2000 ms 280-475 ms
ux-modules-windows U17: completions asked for 24 words 59 (all at the deadline) 35, p95 0.93 s
module input checks per completion (large fixture) most of it 10 ms

Tests

Engine: unit tests for the source classes, package markers, system inputs, validation verdicts and the memo round trip; ci/module_inputs_canary.py on the package; clang/test/Modules/reduced-bmi-linkage-spec-in-gmf.cppm. Product: argument assembly and thresholds, word answers, warm open and adoption (built, changed, still building; the diagnostics handed over as a list), the telling log lines; conformance reask typing (U17 on Qt and <windows.h>, bounding the completions asked per word) and ux-modules-windows-large run cold and warm in the release checks, each run's checks, costs and log in files of their own.

…pletion as typed, with the task split and the engine contract
…ered from them; preambles in memory on Windows; the engine's input stores, memos and retained ASTs by feature

A2: clangd gives up to 1000 completions (--limit-results), so a list whose matches fit is complete and the editor
filters it as the person types instead of asking again per key. A1: a request typed on in the word of a complete core
answer, with the document outside the word as it was, is given that answer at once (MCPPLS_COMPLETION_REFILTER=off
turns it off); the report counts them (completionCosts.fromWord). C1: mcppls.engine.preambleStorage, auto keeping
preambles in memory on Windows with 16 GiB or more. The machine's memory is read on Windows too (platform.system).
For an engine declaring them: --managed-input-root for the mcpp and xlings package stores, --module-memo-dir under
the workspace cache, --max-retained-asts=6 with 16 GiB or more. Two test programs that never returned report() --
test_workarounds and test_engineidentity -- now fail when an expectation does; the bundled engine is the one the
traits call tested, whatever its version.
…r opens them again; a cache off a Dev Drive is said on Windows

G1: the workspace keeps the five files last opened or edited in its cache directory (recent-files.json). The next
session gives them to the core engine, which opens them in clangd as soon as it takes files and its database has them;
the editor's open adopts such a file instead of closing and reopening it -- the same text keeps clangd's build and
hands its diagnostics to the editor, other text (a restored edit) goes as a change on the preamble clangd built. Those
the editor does not open within two minutes are closed. E1: on Windows the cache directory's volume is asked whether
it is a Dev Drive; when not, the log says so once, about.cacheDevDrive is false and the VS Code overview says it, with
nothing changed for the person.
…- four places relied on it being a copy

With the compiler this builds with (clang 22, CWG 2137), `Json x { y }` takes nlohmann's initializer-list constructor:
- the warm adoption (G1) handed the editor [[diagnostics]] and the server ended on a type_error; the G1 test now holds
  the list it hands over to the one clangd published;
- C-2 detached and cancelled a late completion under [id], which matched no request;
- mcppls.sweepCache with categories looked for each category inside [[categories]] and ran none of them -- an explicit
  staleCommands sweep never ran;
- the cache report's instance 'at' was [seconds].
Each is copy-initialized now, as the comments elsewhere already ask.
…ped (reask), U17 on Qt and <windows.h>, and a large Windows module project run cold and warm

The typing check's reask mode asks at a word's first character and again only while the last answer is incomplete or
not yet in (VS Code), or at every key (always); it counts both causes apart and the answers the server gave from a
word's complete list, with budgets on the asks per word an incomplete answer caused. ux-modules-windows-large is
generated (thirty module units with <windows.h>, chains four deep, main.cpp importing twenty-five) and built by MSVC;
the release checks' performance job opens it cold and then warm with the same cache, each run's checks, costs and log
in files of their own and the two runs in the step summary. clangd's 'Module memos' and 'Module inputs' lines reach the
default log.
…e log lines and a Windows section in the troubleshooting guide (en, zh-CN), and the plan's implementation status
…kage's own import library; the large Windows fixture is committed as generated, with no script

The Windows targets link openkal-windows' kernel32 import library, which lists only what openkal calls, so system.cpp's
two names were undefined there; port/winprocess.def carries them beside the process identity's. The repository keeps
scripts to what no mcpp-built program can do (tools/devtools/scripts.allow): the thirty module units of
ux-modules-windows-large are files of the fixture now.
… Code does, and asks again only for an incomplete one; U17 holds at most two asks a word

VS Code filters an answer that comes while keys were typed by what was typed; it asks again only when the answer said it
was incomplete. The first runs asked at every key while an answer was out, a client heavier than any editor, and on
Windows that load alone pushed p95 to 2.5 s. U17's budget is what the first measurements said: about 1.6 asks a word on
a cold start (answers before the modules are built are incomplete), 1.0 once built.
… a URI spelled as the engine spells it (Windows: a drive letter's case, an escaped ':')
…15 engine: module inputs checked by where they come from, memos kept across sessions
…ahead is taken as it is, not sent again; the log says which case it was; the changelog and the plan carry the engine's reduced BMI fix (UP-37)
…sked again for an incomplete answer are reported, not bounded on their own -- a faster engine leaves fewer keys waiting and so more of them ask again
…ppls.3) on every platform; the candidate engine file goes
…side a project checked one by one, and the module context reloaded per completion
@Sunrisepeak
Sunrisepeak marked this pull request as ready for review October 12, 2026 22:49
@Sunrisepeak
Sunrisepeak merged commit 6c907be 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