about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorRobin Jarry <robin@jarry.cc>2021-12-06 20:42:07 +0100
committerRobin Jarry <robin@jarry.cc>2021-12-06 20:54:29 +0100
commitf4d3c8fc77f97c1c01e85329c54c522c2cfd13bb (patch)
tree89be7d25fbce0657a158d520c5d6e2f667596546
parentf776fb82469d0b9aefffd3f16b27024d53d922c8 (diff)
downloadaerc-f4d3c8fc77f97c1c01e85329c54c522c2cfd13bb.tar.gz
maildir: watch for external changes
When a maildir is synchronized by an external process while aerc is
running (e.g. mbsync), some emails may be moved out of "new" to "cur" or
completely deleted.

These deletions are ignored and aerc may assume these messages are still
here, leading to errors.

Take file deletions into account. Also, add "cur" to the watched
folders since these can be modified as well.

Signed-off-by: Robin Jarry <robin@jarry.cc>
-rw-r--r--worker/maildir/worker.go16
1 files changed, 12 insertions, 4 deletions
diff --git a/worker/maildir/worker.go b/worker/maildir/worker.go
index 5888f11..099a85c 100644
--- a/worker/maildir/worker.go
+++ b/worker/maildir/worker.go
@@ -71,8 +71,8 @@ func (w *Worker) handleAction(action types.WorkerMessage) {
 }
 
 func (w *Worker) handleFSEvent(ev fsnotify.Event) {
-	// we only care about files being created
-	if ev.Op != fsnotify.Create {
+	// we only care about files being created or removed
+	if ev.Op != fsnotify.Create && ev.Op != fsnotify.Remove {
 		return
 	}
 	// if there's not a selected directory to rescan, ignore
@@ -275,22 +275,30 @@ func (w *Worker) handleOpenDirectory(msg *types.OpenDirectory) error {
 		return err
 	}
 
-	// remove existing watch path
+	// remove existing watch paths
 	if w.selected != nil {
 		prevDir := filepath.Join(string(*w.selected), "new")
 		if err := w.watcher.Remove(prevDir); err != nil {
 			return fmt.Errorf("could not unwatch previous directory: %v", err)
 		}
+		prevDir = filepath.Join(string(*w.selected), "cur")
+		if err := w.watcher.Remove(prevDir); err != nil {
+			return fmt.Errorf("could not unwatch previous directory: %v", err)
+		}
 	}
 
 	w.selected = &dir
 	w.selectedName = msg.Directory
 
-	// add watch path
+	// add watch paths
 	newDir := filepath.Join(string(*w.selected), "new")
 	if err := w.watcher.Add(newDir); err != nil {
 		return fmt.Errorf("could not add watch to directory: %v", err)
 	}
+	newDir = filepath.Join(string(*w.selected), "cur")
+	if err := w.watcher.Add(newDir); err != nil {
+		return fmt.Errorf("could not add watch to directory: %v", err)
+	}
 
 	if err := dir.Clean(); err != nil {
 		return fmt.Errorf("could not clean directory: %v", err)