@@ -25,6 +25,10 @@ impl LinuxWatcher {
25
25
impl Watcher for LinuxWatcher {
26
26
fn add ( & self , path : & std:: path:: Path ) -> gpui:: Result < ( ) > {
27
27
let root_path = path. to_path_buf ( ) ;
28
+ // Canonicalize the root path to handle cases where it's a symlink or below one
29
+ let target_path = std:: fs:: canonicalize ( & path) . ok ( ) ;
30
+
31
+ let is_canonical = target_path == Some ( root_path. clone ( ) ) ;
28
32
29
33
let tx = self . tx . clone ( ) ;
30
34
let pending_paths = self . pending_path_events . clone ( ) ;
@@ -44,10 +48,47 @@ impl Watcher for LinuxWatcher {
44
48
. paths
45
49
. iter ( )
46
50
. filter_map ( |event_path| {
47
- event_path. starts_with ( & root_path) . then ( || PathEvent {
48
- path : event_path. clone ( ) ,
49
- kind,
50
- } )
51
+ // we canonicalize the parent and join with file name to handle cases
52
+ // where the file doesn't exist anymore
53
+ if let Some ( parent) = event_path. parent ( ) {
54
+ if event_path. clone ( ) . starts_with ( parent) {
55
+ if !is_canonical {
56
+ if let Ok ( canonical_parent) = std:: fs:: canonicalize ( & parent)
57
+ {
58
+ if let Some ( file_name) = event_path. file_name ( ) {
59
+ return Some ( PathEvent {
60
+ path : canonical_parent. join ( file_name) ,
61
+ kind,
62
+ } ) ;
63
+ }
64
+ }
65
+ } else {
66
+ return Some ( PathEvent {
67
+ path : event_path. clone ( ) ,
68
+ kind,
69
+ } ) ;
70
+ }
71
+ } else {
72
+ if let Ok ( canonical_parent) = std:: fs:: canonicalize ( & parent) {
73
+ if event_path. starts_with ( canonical_parent. clone ( ) ) {
74
+ if !is_canonical {
75
+ if let Some ( file_name) = event_path. file_name ( ) {
76
+ return Some ( PathEvent {
77
+ path : canonical_parent. join ( file_name) ,
78
+ kind,
79
+ } ) ;
80
+ }
81
+ } else {
82
+ return Some ( PathEvent {
83
+ path : event_path. clone ( ) ,
84
+ kind,
85
+ } ) ;
86
+ }
87
+ }
88
+ }
89
+ }
90
+ }
91
+ None
51
92
} )
52
93
. collect :: < Vec < _ > > ( ) ;
53
94
0 commit comments