Repository: sxyazi/yazi
File: yazi-watcher/src/local/local.rs (Rust)

Code before:
		let (path, alt) =
			watchee.as_local().ok_or_else(|| notify::Error::generic("Not a local watchee"))?;

		let result = if alt {
			self.alternative.unwatch(path)
		} else if let Some(primary) = &mut self.primary {
			primary.unwatch(path)
		} else {
			Ok(())
		};

		match result {
			Ok(()) => Ok(()),
			Err(e) if matches!(e.kind, notify::ErrorKind::WatchNotFound) => Ok(()),
			Err(e) => Err(e)?,
		}
	}

	pub(crate) fn heuristic(path: &Path) -> bool {
		if cfg!(target_os = "netbsd") || yazi_adapter::WSL.get() {
			return true;
		}

		let Ok(meta) = path.metadata() else { return true };
		PARTITIONS.read().heuristic(Cha::new(path.file_name().unwrap_or_default(), meta))
	}

	async fn changed(rx: UnboundedReceiver<UrlBuf>) {
		// TODO: revert this once a new notification is implemented
		let rx = UnboundedReceiverStream::new(rx).chunks_timeout(1000, Duration::from_millis(250));
		pin!(rx);

		while let Some(chunk) = rx.next().await {
			let urls: HashSet<_> = chunk.into_iter().collect();

			let _permit = WATCHER.acquire().await.unwrap();
			let mut ops = Vec::with_capacity(urls.len());

			for u in urls {
				let Some((parent, urn)) = u.pair() else { continue };
				let Ok(file) = File::new(&u).await else {
					ops.push(FilesOp::Deleting(parent.into(), [urn.into()].into()));
					continue;
				};

				if let Some(p) = file.url.as_local()
					&& !provider::local::match_name_case(p).await
				{
					ops.push(FilesOp::Deleting(parent.into(), [urn.into()].into()));
					continue;
				}

Review comment (suggestion):
`Local::heuristic()` delegates to `PARTITIONS.read().heuristic(...)`, but `Partition::heuristic()` currently only treats `exfat` and `fuse.rclone` as needing polling (see `yazi-fs/src/mounts/partition.rs:19-22`). If this PR is intended to address NFS not emitting events (issue #2500), NFS mount types (e.g. `nfs`/`nfs4`) likely need to be included in that heuristic, otherwise NFS paths will still stick with the primary watcher.

Code after:
		let (path, alt) =
			watchee.as_local().ok_or_else(|| notify::Error::generic("Not a local watchee"))?;

		let result = if alt {
			self.alternative.unwatch(path)
		} else if let Some(primary) = &mut self.primary {
			primary.unwatch(path)
		} else {
			Ok(())
		};

		match result {
			Ok(()) => Ok(()),
			Err(e) if matches!(e.kind, notify::ErrorKind::WatchNotFound) => Ok(()),
			Err(e) => Err(e)?,
		}
	}

	pub(crate) fn soundless(path: &Path) -> bool {
		if cfg!(target_os = "netbsd") || yazi_adapter::WSL.get() {
			return true;
		}

		let Ok(meta) = path.metadata() else { return true };
		PARTITIONS.read().soundless(Cha::new(path.file_name().unwrap_or_default(), meta))
	}

	async fn changed(rx: UnboundedReceiver<UrlBuf>) {
		// TODO: revert this once a new notification is implemented
		let rx = UnboundedReceiverStream::new(rx).chunks_timeout(1000, Duration::from_millis(250));
		pin!(rx);

		while let Some(chunk) = rx.next().await {
			let urls: HashSet<_> = chunk.into_iter().collect();

			let _permit = WATCHER.acquire().await.unwrap();
			let mut ops = Vec::with_capacity(urls.len());

			for u in urls {
				let Some((parent, urn)) = u.pair() else { continue };
				let Ok(file) = File::new(&u).await else {
					ops.push(FilesOp::Deleting(parent.into(), [urn.into()].into()));
					continue;
				};

				if let Some(p) = file.url.as_local()
					&& !provider::local::match_name_case(p).await
				{
					ops.push(FilesOp::Deleting(parent.into(), [urn.into()].into()));
					continue;
				}