Path-scoped resource locking for vault files and folders, with three enforcement layers over one shared locked-path set:
Editor read-only — while a path is locked, every current and future MarkdownView of that note (in any window, including popouts) is made read-only and shows a lock indicator in its tab header, its view action bar, and the status bar; a note inside a subtree-locked folder is covered too. Locks are reference-counted per locking plugin (the indicators’ tooltip lists which plugins hold a lock), so nested/concurrent operations are safe — the path is unlocked only when the last lock is released. 2. Vault-mutation blocking (opt-in via shouldBlockMutations) — any edit/delete/rename/move/ create of a locked path through the Vault/FileManager API throws ResourceLockedError, unless the owning operation has opened a ResourceLockComponent.bypassBlockedMutations scope over that path. 3. External-change detection — a vault/metadata event on a locked path that no bypass scope covers is treated as an intruder (Sync / raw filesystem / another plugin) and aborts the owning operation’s AbortController.
The acquirers return a Disposable, so the preferred call style is a using declaration that releases automatically at scope exit (including on throw):
A per-plugin handle for path-scoped resource locking (editor read-only, optional vault-mutation blocking, and external-change detection — see the file overview). Add it as a child of your plugin (this.addChild(new ResourceLockComponent(this.app))) so that any locks it still holds are released automatically when the plugin unloads — a resource can never be left stuck locked because the plugin that locked it was disabled or reloaded mid-operation. Locks are reference-counted and attributed to this plugin, so the lock indicators’ tooltip names it among the plugins currently holding a lock.
Locks the note at the given path, making it read-only in every current and future MarkdownView until the lock is released, and showing a lock indicator in the tab header, view action bar, and (while active) the status bar. The indicators’ tooltip lists the plugins that currently hold a lock on the note. The lock is reference-counted per calling plugin: each call must be balanced by exactly one release (either disposing the returned Disposable — ideally via a using declaration — or a matching unlockResourceForPath call).
Requests an unlock of the note at the given path by aborting every AbortController that was associated with a lock on it (via ResourceLockComponent.lockForPath’s ResourceLockComponentLockForPathParams.abortController). The operations holding the lock observe the abort and release their own locks. A no-op when no abortable lock is registered for the path. This lets a consuming plugin wire its own “unlock active note” command without reaching into the lock manager directly.
Releases one lock previously acquired for the note at the given path via lockResourceForPath. When the last lock is released the note becomes fully editable again and its lock indicators are removed. Calling this when the note is not locked is a no-op.
The scope of a lock. - 'file' locks only the exact path. - 'subtree' locks the path and every descendant under it (its whole folder subtree), so a file inside a subtree-locked folder is treated as locked too.