11
11
use analysis:: AnalysisHost ;
12
12
use vfs:: Vfs ;
13
13
use config:: { Config , FmtConfig } ;
14
+ use serde_json;
15
+ use url:: Url ;
14
16
use span;
15
17
use Span ;
16
18
@@ -211,6 +213,51 @@ fn find_word_at_pos(line: &str, pos: &Column) -> (Column, Column) {
211
213
( span:: Column :: new_zero_indexed ( start) , span:: Column :: new_zero_indexed ( end) )
212
214
}
213
215
216
+ // TODO include workspace Cargo.tomls in watchers / relevant
217
+ /// Client file-watching request / filtering logic
218
+ /// We want to watch workspace 'Cargo.toml', root 'Cargo.lock' & the root 'target' dir
219
+ pub struct FileWatch < ' ctx > {
220
+ project_str : & ' ctx str ,
221
+ project_uri : String ,
222
+ }
223
+
224
+ impl < ' ctx > FileWatch < ' ctx > {
225
+ pub fn new ( ctx : & ' ctx InitActionContext ) -> Self {
226
+ Self {
227
+ project_str : ctx. current_project . to_str ( ) . unwrap ( ) ,
228
+ project_uri : Url :: from_file_path ( & ctx. current_project ) . unwrap ( ) . into_string ( ) ,
229
+ }
230
+ }
231
+
232
+ /// Returns json config for desired file watches
233
+ pub fn watchers_config ( & self ) -> serde_json:: Value {
234
+ let pattern = format ! ( "{}/Cargo{{.toml,.lock}}" , self . project_str) ;
235
+ let target_pattern = format ! ( "{}/target" , self . project_str) ;
236
+ // For target, we only watch if it gets deleted.
237
+ json ! ( {
238
+ "watchers" : [ { "globPattern" : pattern } , { "globPattern" : target_pattern, "kind" : 4 } ]
239
+ } )
240
+ }
241
+
242
+ /// Returns if a file change is relevant to the files we actually wanted to watch
243
+ // Implementation note: This is expected to be called a large number of times in a loop
244
+ // so should be fast / avoid allocation.
245
+ #[ inline]
246
+ pub fn is_relevant ( & self , change : & FileEvent ) -> bool {
247
+ let path = change. uri . as_str ( ) ;
248
+
249
+ if !path. starts_with ( & self . project_uri ) {
250
+ return false ;
251
+ }
252
+
253
+ let local = & path[ self . project_uri . len ( ) ..] ;
254
+
255
+ local == "/Cargo.lock" || local == "/Cargo.toml"
256
+ || local == "/target" && change. typ == FileChangeType :: Deleted
257
+ }
258
+ }
259
+
260
+
214
261
#[ cfg( test) ]
215
262
mod test {
216
263
use super :: * ;
@@ -244,4 +291,4 @@ mod test {
244
291
assert_range ( "span::Position<|T>" , ( 15 , 16 ) ) ;
245
292
assert_range ( "span::Position<T|>" , ( 15 , 16 ) ) ;
246
293
}
247
- }
294
+ }
0 commit comments