Expand description
LSP file-watcher subsystem (Phase 5.8.AF.5 / Slice 1).
Owns a notify::RecommendedWatcher and the per-server LSP
subscription map. Lives entirely on a dedicated tokio task on
the LSP runtime — paramount goal #4 (CLAUDE.md): nothing that
does I/O, classification, or LSP fan-out runs on the renderer’s
per-tick loop.
§Shape
LspFileWatcherHandle— whatEditorholds. Just acmd_tx. Cheap to construct, cheap to send through, never blocks.spawn_lsp_file_watcher_task— spawns the task onlsp_runtime. The task owns the watcher, the event rx, and aHashMap<server_id, CachedSubscription>. Itselect!s between commands fromEditorandnotifyevents.- Editor pushes a
SyncSubscriptionscommand whenever the actor roster or per-server caps change. The task installs/ tears down recursive watches and replaces its in-memory subscription map atomically. - When notify fires an event, the task classifies it, matches
it against every server’s
WatcherSubscriptions, and fans out oneworkspace/didChangeWatchedFilesper interested server via the clonedLspSupervisorHandle. The supervisor handle’sdid_change_watched_filesnotification is non-blocking (channel send on the per-server actor).
Constructing the notify watcher and calling watcher.watch/
watcher.unwatch are sync APIs; they’re invoked from inside
the task via [tokio::task::block_in_place] so the LSP
runtime (multi-thread) keeps polling other futures while a
large recursive walk is in flight.
§What’s NOT here (deferred to Slice 2)
.gitignore/.ignoreaware filtering at the notify callback so events fortarget/,.git/,node_modules/, etc. never enter the channel.- Per-server registered-glob filtering at the source so we don’t pay the inotify wakeup cost for irrelevant paths.
Both are pure-additive improvements that bolt onto this task’s existing structure.
Structs§
- Cached
Subscription - One server’s subscription snapshot + the fingerprint used to
detect changes.
Editorcomputes the fingerprint, stores its ownserver_id → fingerprintmap, and only sends aWatcherCommand::SyncSubscriptionswhen at least one server’s fingerprint flipped (or the actor roster changed). - LspFile
Watcher Handle - Handle held by
Editor. Owning this is cheap; sending through it is non-blocking. Drop the handle to tear down the task (the watcher itself drops + every inotify watch is released). - Watcher
Ignore Matcher - Matcher consulted in the notify callback. A path is rejected
when ANY of the per-root
.gitignorematchers OR the baked defaultGlobSetsays “ignore.” Built once persync_rootscall by the watcher task and published into theArc<ArcSwap<...>>shared with the notify callback.
Enums§
- Watcher
Command - Editor → watcher-task control commands.
Functions§
- classify
- Translate one
notify::Eventinto an LSPFileChangeType. - spawn_
lsp_ file_ watcher_ task - Spawn the watcher task on the LSP runtime. Returns the handle
Editorshould keep. ReturnsErronly ifnotifyitself fails to construct the OS watcher (out of inotify slots, etc.).