filter files inside ignored directories in the watcher

isIgnored only matched a directory path itself, not files beneath it, so
a recursive watch still surfaced changes inside .dart_tool/, build/, etc.
Linux usually hid this because inotify drops the nested creates; macOS
FSEvents delivers them, so the tree reacted to churn it should ignore.
Check each ancestor segment as a directory.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Jeroen Schweitzer
2026-06-03 10:00:29 +02:00
co-authored by Claude Opus 4.8
parent fa1e71d175
commit da4bc267cb
2 changed files with 18 additions and 1 deletions
+4
View File
@@ -58,6 +58,10 @@ heading, and (b) bumping `pubspec.yaml` `version:` in the same commit.
### Fixed
- File watcher no longer emits change events for files inside ignored
directories (`.dart_tool/`, `build/`, etc.): it now checks ancestor dirs,
not just the leaf. Most visible on macOS, where FSEvents delivers the nested
creates that inotify usually drops.
- The Claude sidebar's Activity / Team / Config sub-tabs are now keyboard-
activatable: they were pointer-only (raw `GestureDetector`), so Tab traversal
skipped them and Enter/Space did nothing. They now use `ClideTappable`
+14 -1
View File
@@ -86,7 +86,7 @@ class FileWatcher {
final rel = _toRelative(e.path);
if (rel == null) return;
final isDir = e.isDirectory;
if (ignore.isIgnored(rel, isDirectory: isDir)) return;
if (_ignored(rel, isDir)) return;
_controller.add(FileChange(
kind: FileChangeKind.fromEvent(e),
path: rel,
@@ -94,6 +94,19 @@ class FileWatcher {
));
}
/// True if `rel` is ignored, or sits inside an ignored directory.
/// A `foo/` rule hides the directory *and everything under it*, but a
/// recursive watch still delivers events for those descendants — notably
/// macOS FSEvents, which reports nested creates that inotify often drops.
/// So check each ancestor segment as a directory, not just the leaf.
bool _ignored(String rel, bool isDir) {
if (ignore.isIgnored(rel, isDirectory: isDir)) return true;
for (var slash = rel.indexOf('/'); slash != -1; slash = rel.indexOf('/', slash + 1)) {
if (ignore.isIgnored(rel.substring(0, slash), isDirectory: true)) return true;
}
return false;
}
String? _toRelative(String abs) {
final rootPath = root.absolute.path;
if (!abs.startsWith(rootPath)) return null;