Skip to main content

Mountain/IPC/WindServiceHandlers/FileSystem/Native/
FileWatch.rs

1//! `file:watch` - register a native filesystem watcher for a URI.
2//!
3//! VS Code's `DiskFileSystemProvider.watch(resource, opts)` sends:
4//!   Arguments\[0\] = resource URI (object or path string)
5//!   Arguments\[1\] = `{ recursive: boolean, excludes: string[] }`
6//!
7//! Returns a numeric token that the caller passes to `file:unwatch`.
8//! The token is stored as the string key in `WatcherProvider::RegisterWatcher`.
9//!
10//! Events flow through `FileWatcherProvider` → `$fileWatcher:event` gRPC
11//! notification → Cocoon → `onDidChangeFile` extension API.
12
13use std::{
14	path::PathBuf,
15	sync::{
16		Arc,
17		atomic::{AtomicU64, Ordering},
18	},
19};
20
21use CommonLibrary::FileSystem::FileWatcherProvider::FileWatcherProvider;
22use serde_json::{Value, json};
23
24use crate::{
25	IPC::WindServiceHandlers::Utilities::PathExtraction::Fn as extract_path_from_arg,
26	RunTime::ApplicationRunTime::ApplicationRunTime,
27	dev_log,
28};
29
30static WATCH_HANDLE_SEQ:AtomicU64 = AtomicU64::new(1);
31
32pub async fn Fn(RunTime:Arc<ApplicationRunTime>, Arguments:Vec<Value>) -> Result<Value, String> {
33	let ResourceArg = Arguments.get(0).ok_or("file:watch: missing resource")?;
34
35	let Path = extract_path_from_arg(ResourceArg)?;
36
37	let Opts = Arguments.get(1).and_then(Value::as_object);
38
39	let IsRecursive = Opts.and_then(|O| O.get("recursive")).and_then(Value::as_bool).unwrap_or(false);
40
41	let Pattern:Option<String> = Opts.and_then(|O| O.get("excludes")).and_then(Value::as_array).and_then(|Arr| {
42		let Globs:Vec<&str> = Arr.iter().filter_map(Value::as_str).collect();
43
44		if Globs.is_empty() { None } else { Some(Globs.join("|")) }
45	});
46
47	let Handle = WATCH_HANDLE_SEQ.fetch_add(1, Ordering::Relaxed).to_string();
48
49	dev_log!(
50		"filewatcher",
51		"file:watch handle={} path={} recursive={} pattern={:?}",
52		Handle,
53		Path,
54		IsRecursive,
55		Pattern
56	);
57
58	let Root = PathBuf::from(&Path);
59
60	RunTime
61		.Environment
62		.RegisterWatcher(Handle.clone(), Root, IsRecursive, Pattern)
63		.await
64		.map_err(|E| format!("file:watch: {E}"))?;
65
66	Ok(json!(Handle))
67}