Skip to content

Commit 543b906

Browse files
authored
fix: fix init fs event watcher. (#1881)
Signed-off-by: he1pa <[email protected]>
1 parent 1675fbe commit 543b906

File tree

1 file changed

+72
-54
lines changed

1 file changed

+72
-54
lines changed

kclvm/tools/src/LSP/src/state.rs

Lines changed: 72 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -108,9 +108,11 @@ pub(crate) struct LanguageServerState {
108108
pub workspace_folders: Option<Vec<WorkspaceFolder>>,
109109
/// Actively monitor file system changes. These changes will not be notified through lsp,
110110
/// e.g., execute `kcl mod add xxx`, `kcl fmt xxx`
111-
pub fs_event_watcher: Handle<
112-
Box<RecommendedWatcher>,
113-
mpsc::Receiver<std::result::Result<notify::Event, notify::Error>>,
111+
pub fs_event_watcher: Option<
112+
Handle<
113+
Box<RecommendedWatcher>,
114+
mpsc::Receiver<std::result::Result<notify::Event, notify::Error>>,
115+
>,
114116
>,
115117
}
116118

@@ -152,11 +154,21 @@ impl LanguageServerState {
152154

153155
let fs_event_watcher = {
154156
let (tx, rx) = mpsc::channel::<notify::Result<notify::Event>>();
155-
let mut watcher = notify::recommended_watcher(tx).unwrap();
156-
let handle = Box::new(watcher);
157-
Handle {
158-
handle,
159-
_receiver: rx,
157+
match notify::recommended_watcher(tx) {
158+
Ok(watcher) => {
159+
let handle = Box::new(watcher);
160+
Some(Handle {
161+
handle,
162+
_receiver: rx,
163+
})
164+
}
165+
Err(e) => {
166+
log_message(
167+
format!("Failed to init fs event watcher: {:?}", e),
168+
&task_sender,
169+
);
170+
None
171+
}
160172
}
161173
};
162174

@@ -190,47 +202,50 @@ impl LanguageServerState {
190202
/// Blocks until a new event is received from one of the many channels the language server
191203
/// listens to. Returns the first event that is received.
192204
fn next_event(&self, receiver: &Receiver<lsp_server::Message>) -> Option<Event> {
193-
for event in self.fs_event_watcher._receiver.try_iter() {
194-
if let Ok(e) = event {
195-
match e.kind {
196-
notify::EventKind::Modify(kind) => {
197-
if let notify::event::ModifyKind::Data(data_change) = kind {
198-
if let notify::event::DataChange::Content = data_change {
205+
if let Some(fs_event_watcher) = &self.fs_event_watcher {
206+
for event in fs_event_watcher._receiver.try_iter() {
207+
if let Ok(e) = event {
208+
match e.kind {
209+
notify::EventKind::Modify(kind) => {
210+
if let notify::event::ModifyKind::Data(data_change) = kind {
211+
if let notify::event::DataChange::Content = data_change {
212+
let paths = e.paths;
213+
let kcl_config_file: Vec<PathBuf> =
214+
filter_kcl_config_file(&paths);
215+
if !kcl_config_file.is_empty() {
216+
// TODO: wait for fix `kcl mod metadata` to read only. Otherwise it will lead to an infinite loop
217+
// return Some(Event::FileWatcher(
218+
// FileWatcherEvent::ChangedConfigFile(kcl_config_file),
219+
// ));
220+
}
221+
}
222+
}
223+
}
224+
notify::EventKind::Remove(remove_kind) => {
225+
if let notify::event::RemoveKind::File = remove_kind {
199226
let paths = e.paths;
200227
let kcl_config_file: Vec<PathBuf> = filter_kcl_config_file(&paths);
201228
if !kcl_config_file.is_empty() {
202-
// TODO: wait for fix `kcl mod metadata` to read only. Otherwise it will lead to an infinite loop
203-
// return Some(Event::FileWatcher(
204-
// FileWatcherEvent::ChangedConfigFile(kcl_config_file),
205-
// ));
229+
return Some(Event::FileWatcher(
230+
FileWatcherEvent::RemoveConfigFile(kcl_config_file),
231+
));
206232
}
207233
}
208234
}
209-
}
210-
notify::EventKind::Remove(remove_kind) => {
211-
if let notify::event::RemoveKind::File = remove_kind {
212-
let paths = e.paths;
213-
let kcl_config_file: Vec<PathBuf> = filter_kcl_config_file(&paths);
214-
if !kcl_config_file.is_empty() {
215-
return Some(Event::FileWatcher(
216-
FileWatcherEvent::RemoveConfigFile(kcl_config_file),
217-
));
218-
}
219-
}
220-
}
221235

222-
notify::EventKind::Create(create_kind) => {
223-
if let notify::event::CreateKind::File = create_kind {
224-
let paths = e.paths;
225-
let kcl_config_file: Vec<PathBuf> = filter_kcl_config_file(&paths);
226-
if !kcl_config_file.is_empty() {
227-
return Some(Event::FileWatcher(
228-
FileWatcherEvent::CreateConfigFile(kcl_config_file),
229-
));
236+
notify::EventKind::Create(create_kind) => {
237+
if let notify::event::CreateKind::File = create_kind {
238+
let paths = e.paths;
239+
let kcl_config_file: Vec<PathBuf> = filter_kcl_config_file(&paths);
240+
if !kcl_config_file.is_empty() {
241+
return Some(Event::FileWatcher(
242+
FileWatcherEvent::CreateConfigFile(kcl_config_file),
243+
));
244+
}
230245
}
231246
}
247+
_ => {}
232248
}
233-
_ => {}
234249
}
235250
}
236251
}
@@ -573,23 +588,26 @@ impl LanguageServerState {
573588
if let Some(workspace_folders) = &self.workspace_folders {
574589
for folder in workspace_folders {
575590
let path = file_path_from_url(&folder.uri).unwrap();
576-
let mut watcher = &mut self.fs_event_watcher.handle;
577-
match watcher.watch(std::path::Path::new(&path), RecursiveMode::Recursive) {
578-
Ok(_) => self.log_message(format!("Start watch {:?}", path)),
579-
Err(e) => self.log_message(format!("Failed watch {:?}: {:?}", path, e)),
580-
}
581-
self.log_message(format!("Start watch {:?}", path));
582-
let tool = Arc::clone(&self.tool);
583-
let (workspaces, failed) = lookup_compile_workspaces(&*tool.read(), &path, true);
584-
585-
if let Some(failed) = failed {
586-
for (key, err) in failed {
587-
self.log_message(format!("parse kcl.work failed: {}: {}", key, err));
591+
if let Some(fs_event_watcher) = &mut self.fs_event_watcher {
592+
let mut watcher = &mut fs_event_watcher.handle;
593+
match watcher.watch(std::path::Path::new(&path), RecursiveMode::Recursive) {
594+
Ok(_) => self.log_message(format!("Start watch {:?}", path)),
595+
Err(e) => self.log_message(format!("Failed watch {:?}: {:?}", path, e)),
596+
}
597+
self.log_message(format!("Start watch {:?}", path));
598+
let tool = Arc::clone(&self.tool);
599+
let (workspaces, failed) =
600+
lookup_compile_workspaces(&*tool.read(), &path, true);
601+
602+
if let Some(failed) = failed {
603+
for (key, err) in failed {
604+
self.log_message(format!("parse kcl.work failed: {}: {}", key, err));
605+
}
588606
}
589-
}
590607

591-
for (workspace, opts) in workspaces {
592-
self.async_compile(workspace, opts, None, false);
608+
for (workspace, opts) in workspaces {
609+
self.async_compile(workspace, opts, None, false);
610+
}
593611
}
594612
}
595613
}

0 commit comments

Comments
 (0)