@@ -11,6 +11,11 @@ import (
1111 "github.com/fsnotify/fsnotify"
1212)
1313
14+ const (
15+ internalVaultDir = ".zennotes"
16+ vaultSettingsFilePath = ".zennotes/vault.json"
17+ )
18+
1419// Watcher recursively watches the vault root and fans out change
1520// events to any subscribed channels. Mirrors the chokidar-based
1621// watcher in src/main/watcher.ts.
@@ -41,7 +46,7 @@ func Start(root string) (*Watcher, error) {
4146 }
4247 if d .IsDir () {
4348 name := d .Name ()
44- if path != root && strings .HasPrefix (name , "." ) {
49+ if path != root && strings .HasPrefix (name , "." ) && name != internalVaultDir {
4550 return filepath .SkipDir
4651 }
4752 _ = fsw .Add (path )
@@ -102,9 +107,21 @@ func (w *Watcher) loop() {
102107 }
103108}
104109
110+ func (w * Watcher ) relativePath (absPath string ) string {
111+ rel , err := filepath .Rel (w .root , absPath )
112+ if err != nil {
113+ return ""
114+ }
115+ return filepath .ToSlash (rel )
116+ }
117+
118+ func (w * Watcher ) isVaultSettingsPath (absPath string ) bool {
119+ return w .relativePath (absPath ) == vaultSettingsFilePath
120+ }
121+
105122func (w * Watcher ) handle (ev fsnotify.Event ) {
106123 base := filepath .Base (ev .Name )
107- if strings .HasPrefix (base , "." ) {
124+ if strings .HasPrefix (base , "." ) && ! w . isVaultSettingsPath ( ev . Name ) && base != internalVaultDir {
108125 return
109126 }
110127 info , statErr := os .Stat (ev .Name )
@@ -114,11 +131,23 @@ func (w *Watcher) handle(ev fsnotify.Event) {
114131 }
115132 return
116133 }
117- rel , err := filepath .Rel (w .root , ev .Name )
118- if err != nil {
134+ relPosix := w .relativePath (ev .Name )
135+ if relPosix == "" {
136+ return
137+ }
138+ if relPosix == vaultSettingsFilePath {
139+ kind := eventKind (ev )
140+ if kind == "" {
141+ return
142+ }
143+ w .broadcast (vault.ChangeEvent {
144+ Kind : kind ,
145+ Path : relPosix ,
146+ Folder : vault .FolderInbox ,
147+ Scope : "vault-settings" ,
148+ })
119149 return
120150 }
121- relPosix := filepath .ToSlash (rel )
122151 if strings .HasPrefix (relPosix , "." ) || strings .Contains (relPosix , "/." ) {
123152 return
124153 }
@@ -134,15 +163,8 @@ func (w *Watcher) handle(ev fsnotify.Event) {
134163 }
135164 }
136165
137- kind := ""
138- switch {
139- case ev .Op & fsnotify .Create != 0 :
140- kind = "add"
141- case ev .Op & fsnotify .Write != 0 :
142- kind = "change"
143- case ev .Op & fsnotify .Remove != 0 , ev .Op & fsnotify .Rename != 0 :
144- kind = "unlink"
145- default :
166+ kind := eventKind (ev )
167+ if kind == "" {
146168 return
147169 }
148170
@@ -152,6 +174,23 @@ func (w *Watcher) handle(ev fsnotify.Event) {
152174 Folder : folder ,
153175 }
154176
177+ w .broadcast (change )
178+ }
179+
180+ func eventKind (ev fsnotify.Event ) string {
181+ switch {
182+ case ev .Op & fsnotify .Create != 0 :
183+ return "add"
184+ case ev .Op & fsnotify .Write != 0 :
185+ return "change"
186+ case ev .Op & fsnotify .Remove != 0 , ev .Op & fsnotify .Rename != 0 :
187+ return "unlink"
188+ default :
189+ return ""
190+ }
191+ }
192+
193+ func (w * Watcher ) broadcast (change vault.ChangeEvent ) {
155194 w .mu .Lock ()
156195 for ch := range w .subs {
157196 select {
0 commit comments