@@ -108,9 +108,11 @@ pub(crate) struct LanguageServerState {
108
108
pub workspace_folders : Option < Vec < WorkspaceFolder > > ,
109
109
/// Actively monitor file system changes. These changes will not be notified through lsp,
110
110
/// 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
+ > ,
114
116
> ,
115
117
}
116
118
@@ -152,11 +154,21 @@ impl LanguageServerState {
152
154
153
155
let fs_event_watcher = {
154
156
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
+ }
160
172
}
161
173
} ;
162
174
@@ -190,47 +202,50 @@ impl LanguageServerState {
190
202
/// Blocks until a new event is received from one of the many channels the language server
191
203
/// listens to. Returns the first event that is received.
192
204
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 {
199
226
let paths = e. paths ;
200
227
let kcl_config_file: Vec < PathBuf > = filter_kcl_config_file ( & paths) ;
201
228
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
+ ) ) ;
206
232
}
207
233
}
208
234
}
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
- }
221
235
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
+ }
230
245
}
231
246
}
247
+ _ => { }
232
248
}
233
- _ => { }
234
249
}
235
250
}
236
251
}
@@ -573,23 +588,26 @@ impl LanguageServerState {
573
588
if let Some ( workspace_folders) = & self . workspace_folders {
574
589
for folder in workspace_folders {
575
590
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
+ }
588
606
}
589
- }
590
607
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
+ }
593
611
}
594
612
}
595
613
}
0 commit comments