@@ -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