From 4b3b2acf752dd5fa0b75e70154208f943bbbb5ac Mon Sep 17 00:00:00 2001 From: Michael Sloan Date: Mon, 8 Sep 2025 23:55:28 -0600 Subject: [PATCH] Fix hot reload of builtin TreeSitter queries on Linux (#37825) `fs.watch` is recursive on mac and non-recursive on Linux. Release Notes: - N/A --- crates/zed/src/main.rs | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/crates/zed/src/main.rs b/crates/zed/src/main.rs index ab24224119296c90739cacb4e44f878f8ac06cb3..b5fc8943eb6116016de14844f719c55e7abe7193 100644 --- a/crates/zed/src/main.rs +++ b/crates/zed/src/main.rs @@ -1419,30 +1419,35 @@ fn watch_themes(fs: Arc, cx: &mut App) { fn watch_languages(fs: Arc, languages: Arc, cx: &mut App) { use std::time::Duration; - let path = { - let p = Path::new("crates/languages/src"); - let Ok(full_path) = p.canonicalize() else { + cx.background_spawn(async move { + let languages_src = Path::new("crates/languages/src"); + let Some(languages_src) = fs.canonicalize(languages_src).await.log_err() else { return; }; - full_path - }; - cx.spawn(async move |_| { - let (mut events, _) = fs.watch(path.as_path(), Duration::from_millis(100)).await; + let (mut events, watcher) = fs.watch(&languages_src, Duration::from_millis(100)).await; + + // add subdirectories since fs.watch is not recursive on Linux + if let Some(mut paths) = fs.read_dir(&languages_src).await.log_err() { + while let Some(path) = paths.next().await { + if let Some(path) = path.log_err() + && fs.is_dir(&path).await + { + watcher.add(&path).log_err(); + } + } + } + while let Some(event) = events.next().await { - let has_language_file = event.iter().any(|event| { - event - .path - .extension() - .map(|ext| ext.to_string_lossy().as_ref() == "scm") - .unwrap_or(false) - }); + let has_language_file = event + .iter() + .any(|event| event.path.extension().is_some_and(|ext| ext == "scm")); if has_language_file { languages.reload(); } } }) - .detach() + .detach(); } #[cfg(not(debug_assertions))]