From 1ce82f50d0981a9ee047e75d94c7ab496070bd4a Mon Sep 17 00:00:00 2001 From: Jason Cox Date: Fri, 23 Feb 2024 11:40:17 -0500 Subject: notmuch: add strategies for multi-file messages A single notmuch message can represent multiple files. As a result, file-based operations like move, copy, and delete can be ambiguous. Add a new account config option, multi-file-strategy, to tell aerc how to handle these ambiguous cases. Also add options to relevant commands to set the multi-file strategy on a per-invocation basis. If no multi-file strategy is set, refuse to take file-based actions on multi-file messages. This default behavior is mostly the same as aerc's previous behavior, but a bit stricter in some cases which previously tried to be smart about multi-file operations (e.g., move and delete). Applying multi-file strategies to cross-account copy and move operations is not implemented. These operations will proceed as they have in the past -- aerc will copy/move a single file. However, for cross-account move operations, aerc will refuse to delete multiple files to prevent data loss as not all of the files are added to the destination account. See the changes to aerc-notmuch(5) for details on the currently supported multi-file strategies. Changelog-added: Tell aerc how to handle file-based operations on multi-file notmuch messages with the account config option `multi-file-strategy` and the `-m` flag to `:archive`, `:copy`, `:delete`, and `:move`. Signed-off-by: Jason Cox Tested-by: Maarten Aertsen Acked-by: Robin Jarry --- commands/msg/delete.go | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) (limited to 'commands/msg/delete.go') diff --git a/commands/msg/delete.go b/commands/msg/delete.go index 0abde31c..0d269eab 100644 --- a/commands/msg/delete.go +++ b/commands/msg/delete.go @@ -13,7 +13,9 @@ import ( "git.sr.ht/~rjarry/aerc/worker/types" ) -type Delete struct{} +type Delete struct { + MultiFileStrategy *types.MultiFileStrategy `opt:"-m" action:"ParseMFS" complete:"CompleteMFS"` +} func init() { commands.Register(Delete{}) @@ -27,7 +29,22 @@ func (Delete) Aliases() []string { return []string{"delete", "delete-message"} } -func (Delete) Execute(args []string) error { +func (d *Delete) ParseMFS(arg string) error { + if arg != "" { + mfs, ok := types.StrToStrategy[arg] + if !ok { + return fmt.Errorf("invalid multi-file strategy %s", arg) + } + d.MultiFileStrategy = &mfs + } + return nil +} + +func (Delete) CompleteMFS(arg string) []string { + return commands.FilterList(types.StrategyStrs(), arg, nil) +} + +func (d Delete) Execute(args []string) error { h := newHelper() store, err := h.store() if err != nil { @@ -46,7 +63,7 @@ func (Delete) Execute(args []string) error { marker.ClearVisualMark() // caution, can be nil next := findNextNonDeleted(uids, store) - store.Delete(uids, func(msg types.WorkerMessage) { + store.Delete(uids, d.MultiFileStrategy, func(msg types.WorkerMessage) { switch msg := msg.(type) { case *types.Done: var s string -- cgit