Skip to content

Prototype: lazily activate language server projects that have no open files - #1935

Draft
chrisdp wants to merge 1 commit into
v1from
proto/lazy-project-activation
Draft

chrisdp wants to merge 1 commit into
v1from
proto/lazy-project-activation

Conversation

@chrisdp

@chrisdp chrisdp commented Oct 20, 2026

Copy link
Copy Markdown
Contributor

Draft / prototype. Opening this for feedback on the approach before polishing it.

Summary

In workspaces with many projects, the language server activates every discovered project at startup. Each project globs, parses and validates all of its files, even if the user only ever opens files from one of them.

This adds an opt-in languageServer.lazyProjectActivation setting (default false). When it's on and more than one project is discovered, projects with no open files are left dormant and activated the first time one of their files is opened. This mirrors how tsserver only loads the project for a file the user opens.

How it works

All changes are in ProjectManager and LanguageServer.

  • Dormant projects. In syncProjects, a project that's allowed to be lazy (more than one project discovered, setting on) and owns none of the open documents becomes dormant. It only resolves its bsconfig.json via util.normalizeAndResolveConfig, the same call ProgramBuilder makes, to build a PathCollection for its rootDir/files patterns. No files are listed, read or parsed. Its patterns are still registered with the PathFilterer, like an active project's.
  • Waking. flushDocumentChanges first activates any dormant project that owns a set action for an open document (allowStandaloneProject: true), then applies the actions as usual. It runs before standalone-project creation, so an opened file is handled by its real project rather than getting a standalone project. The woken project gets the in-memory editor contents and validates.
  • Open-document tracking. LanguageServer now forwards documents.onDidOpen to a new ProjectManager.handleFileOpen, and handleFileClose removes the entry. This keeps a later re-sync (e.g. after a settings change) from leaving the project for an open file dormant.
  • Lifecycle.
    • Turning the setting off, or dropping to a single project, activates dormant projects on the next sync.
    • Editing a dormant project's bsconfig.json recomputes its file patterns.
    • Projects that are no longer discovered are dropped.
    • forceReload and dispose clear dormant projects.
  • Fallbacks. A single discovered project, or one whose config can't be resolved, activates as before. A config that can't be resolved activates so its errors are reported normally.

Rough numbers

Synthetic workspace, 6 projects × 300 .brs files, one file open, single-threaded:

Active projects Ready + validated
lazyProjectActivation: false 6 ~1.7–2.1 s
lazyProjectActivation: true 1 ~0.37 s

The memory measurements were too noisy to report.

Known gaps / open questions

  • No deactivation. A project stays active after all of its files are closed; tsserver closes such projects after a while.
  • Cross-project features (workspace symbols, find references, file-rename edits) only see active projects. That matches TS, but we may want a "load all projects" command.
  • Explicit projects from settings can also go dormant. Should explicitly configured projects always activate?
  • No busy/progress signal yet while a dormant project wakes up.
  • The setting isn't declared by the VS Code extension yet.

Tests

There's a new ProjectManager → lazy project activation block (8 tests):

  • dormancy with the setting on and off
  • a single project still activates eagerly
  • waking on open, using the in-memory contents, with no standalone project created
  • open documents survive a re-sync
  • unowned files still get a standalone project
  • turning the setting off wakes dormant projects
  • ownership respects the rootDir/files patterns in bsconfig.json

The existing LanguageServer getWorkspaceConfigs test was updated for the new setting. Full suite: 5361 passing, 0 failing; lint and tsc are clean.


Generated by Claude Code

Behind a new `languageServer.lazyProjectActivation` setting (off by default).
When more than one project is discovered, projects with no open files are
left dormant: only their bsconfig.json is resolved to know which files they
own, and nothing is loaded, parsed or validated. A dormant project is
activated the first time one of its files is opened.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ETmrNpsdDpbMJzc1iexFYJ
@chrisdp chrisdp added enhancement New feature or request LanguageServer labels Oct 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request LanguageServer

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants