Fix file explorer not refreshing on changes in nested subdirectories

Closed
ZA
1mo ago
+178-28

Summary

Fixes #4649.

The Files sidebar only auto-refreshed from a single, non-recursive kqueue vnode watch on the explorer root. A vnode source only reports changes to the immediate contents of the one directory it watches, so creating/deleting/renaming an entry inside an already-expanded nested subdirectory never tripped the watch — the change stayed invisible until a restart, a root switch, or some unrelated activity happened to touch a direct child of the root and trigger a full reload.

This implements the issue's preferred fix (option 1): watch every expanded directory, not just the root.

Changes

  • FileExplorerDirectoryWatcher now manages one vnode source per path via watch(paths:), diffing the requested set against live sources so existing watches are kept (in-flight events aren't dropped) and only deltas are added/removed. Each source owns and closes its own fd in its cancel handler.
  • updateDirectoryWatcher() computes {root} ∪ expandedPaths, filtered to the current root via the existing containment helper so stale paths from a previous root don't leak file descriptors.
  • expand() / collapse() resync the watch set, so the watched directories track exactly what the user can see.

reload() already re-lists every expanded subtree, so a single watcher firing is enough to refresh the visible tree. The fd count stays bounded by the directories the user has actually expanded, and node_modules/.git are only ever watched if the user explicitly expands them.

Test plan

Two-commit red/green structure per the contributing rules:

  1. Commit 1 adds testCreatingEntryInNestedExpandedDirectoryRefreshesTree, which drives a real LocalFileExplorerProvider against a temp directory, expands a nested subdirectory, then creates a folder inside it and asserts it appears in the tree without a restart. This fails against the root-only watcher.
  2. Commit 2 adds the fix; the test passes.

The test exercises the kqueue watch end-to-end through the store's public API.


View with Codesmith Autofix with Codesmith
Need help on this PR? Tag @codesmith with what you need. Autofix is disabled.


Summary by cubic

Watch the root and all visible expanded directories so nested folder changes refresh immediately. Prevents missing updates in expanded subfolders until a restart.

  • Bug Fixes
    • Switched to per-path vnode watching via watch(paths:) in FileExplorerDirectoryWatcher, diffing adds/removes and closing fds on cancel.
    • updateDirectoryWatcher() now watches {root} ∪ visibleExpandedPaths: only paths under the current root whose full ancestor chain is expanded; expand()/collapse() resync the set so fd usage matches the visible tree.
    • Guarded debounce scheduling with a lock to avoid races between the watch queue and main thread.
    • Tests: regression for nested-dir refresh and a watch-set visibility test via watchedDirectoryPathsForTesting().

Summary by CodeRabbit

  • New Features

    • File explorer now monitors changes in real-time across all expanded directories and nested subdirectories, improving responsiveness to filesystem updates.
  • Bug Fixes

    • Directory watcher now stays in sync with expanded/collapsed folders so new files and folders appear reliably without restarting.
  • Tests

    • Added regression tests validating nested expansion updates and that the watched set matches visible expanded directories.

Review Change Stack