Start begins watching. It blocks until Stop is called or an error occurs. nolint:gocognit // TODO: refactor to reduce complexity
()
| 34 | // |
| 35 | //nolint:gocognit // TODO: refactor to reduce complexity |
| 36 | func (w *Watcher) Start() error { |
| 37 | fsw, err := fsnotify.NewWatcher() |
| 38 | if err != nil { |
| 39 | return err |
| 40 | } |
| 41 | w.mu.Lock() |
| 42 | w.watcher = fsw |
| 43 | w.mu.Unlock() |
| 44 | |
| 45 | defer fsw.Close() |
| 46 | |
| 47 | if err := w.addRecursive(fsw, w.dir); err != nil { |
| 48 | return err |
| 49 | } |
| 50 | |
| 51 | var timer *time.Timer |
| 52 | for { |
| 53 | select { |
| 54 | case event, ok := <-fsw.Events: |
| 55 | if !ok { |
| 56 | return nil |
| 57 | } |
| 58 | if !isMarkdown(event.Name) { |
| 59 | // Watch new directories for recursive support |
| 60 | if event.Op&fsnotify.Create != 0 { |
| 61 | if info, err := os.Stat(event.Name); err == nil && info.IsDir() { |
| 62 | _ = w.addRecursive(fsw, event.Name) |
| 63 | } |
| 64 | } |
| 65 | continue |
| 66 | } |
| 67 | if event.Op&(fsnotify.Write|fsnotify.Create|fsnotify.Remove|fsnotify.Rename) == 0 { |
| 68 | continue |
| 69 | } |
| 70 | // Debounce |
| 71 | if timer != nil { |
| 72 | timer.Stop() |
| 73 | } |
| 74 | timer = time.AfterFunc(w.debounce, w.onChange) |
| 75 | |
| 76 | case err, ok := <-fsw.Errors: |
| 77 | if !ok { |
| 78 | return nil |
| 79 | } |
| 80 | _ = err // log in verbose mode if needed |
| 81 | |
| 82 | case <-w.done: |
| 83 | return nil |
| 84 | } |
| 85 | } |
| 86 | } |
| 87 | |
| 88 | // Stop signals the watcher to stop. |
| 89 | func (w *Watcher) Stop() { |