Skip to main content

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

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