package config import ( "log" "path/filepath" "github.com/fsnotify/fsnotify" ) // WatchConfig watches the config file for changes and triggers the callback func WatchConfig(path string, onChange func(*Config)) error { watcher, err := fsnotify.NewWatcher() if err != nil { return err } absPath, err := filepath.Abs(path) if err != nil { return err } configDir := filepath.Dir(absPath) go func() { defer watcher.Close() for { select { case event, ok := <-watcher.Events: if !ok { return } // Many editors trigger Write or Rename when saving if event.Has(fsnotify.Write) || event.Has(fsnotify.Create) { if filepath.Base(event.Name) == filepath.Base(absPath) { log.Printf("Config file changed: %s", event.Name) newCfg, err := LoadConfig(absPath) if err != nil { log.Printf("Failed to reload config: %v", err) continue } onChange(newCfg) } } case err, ok := <-watcher.Errors: if !ok { return } log.Printf("Watcher error: %v", err) } } }() // Watch the directory instead of the file to handle cases where // editors use atomic saves (create new file, delete old, rename new) return watcher.Add(configDir) }