aboutsummaryrefslogtreecommitdiffstats
path: root/src/notmuchworker.cpp
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-09-13 20:17:43 +0200
committerDanilo M. <danix@danix.xyz>2026-09-13 20:17:43 +0200
commit533c9243bede053f4ea7e1f20de13e72c2b939b8 (patch)
tree9b2dfef2ed92cee363c825d3c29e6dcb7e6e3439 /src/notmuchworker.cpp
parent18ff1f33f64428ab96ca0b5ea22e681be564c886 (diff)
downloadqtmaildir-533c9243bede053f4ea7e1f20de13e72c2b939b8.tar.gz
qtmaildir-533c9243bede053f4ea7e1f20de13e72c2b939b8.zip
refactor: rename the origin tag to moved-from: with overwrite semantics
Diffstat (limited to 'src/notmuchworker.cpp')
-rw-r--r--src/notmuchworker.cpp26
1 files changed, 25 insertions, 1 deletions
diff --git a/src/notmuchworker.cpp b/src/notmuchworker.cpp
index bc3ae65..2672f6a 100644
--- a/src/notmuchworker.cpp
+++ b/src/notmuchworker.cpp
@@ -36,6 +36,7 @@
#include <QSet>
#include <cstdlib>
+#include <utility>
#include "maildirname.h"
#include "mimeparser.h"
@@ -1122,17 +1123,40 @@ void NotmuchWorker::applyTags(const TagChange &change)
// write, so the only way to know is to look first.
const QStringList before = tagsOf(message.get());
+ // One origin tag ever: writing a `moved-from:` tag strips any OTHER
+ // tag with that prefix the message still carries, so a message that
+ // travelled inbox -> spam -> trash ends with exactly one origin and
+ // Restore has one answer. Without this the reader's first-match
+ // break() picks silently.
+ QStringList strippedOrigins;
+ const bool writingOrigin =
+ std::any_of(change.added.cbegin(), change.added.cend(),
+ [](const QString &t) {
+ return t.startsWith(QLatin1String(kOriginTagPrefix));
+ });
+ if (writingOrigin) {
+ for (const QString &tag : std::as_const(before)) {
+ if (tag.startsWith(QLatin1String(kOriginTagPrefix))
+ && !change.added.contains(tag)) {
+ strippedOrigins.append(tag);
+ }
+ }
+ }
+
bool moves = false;
for (const QString &tag : change.removed)
moves = moves || before.contains(tag);
for (const QString &tag : change.added)
moves = moves || !before.contains(tag);
+ moves = moves || !strippedOrigins.isEmpty();
if (moves)
changedIds.append(id);
notmuch_message_freeze(message.get());
for (const QString &tag : change.removed)
notmuch_message_remove_tag(message.get(), tag.toUtf8().constData());
+ for (const QString &tag : strippedOrigins)
+ notmuch_message_remove_tag(message.get(), tag.toUtf8().constData());
for (const QString &tag : change.added)
notmuch_message_add_tag(message.get(), tag.toUtf8().constData());
notmuch_message_thaw(message.get());
@@ -1689,7 +1713,7 @@ void NotmuchWorker::resolveQuery(const QString &query,
QDir(dbRoot).relativeFilePath(QString::fromUtf8(rawName)));
// Joined by a TAB, not a space. A notmuch tag may absolutely contain
// a space: a Maildir folder named "Inbox/SlackBuilds users" produces
- // `deleted-from:Inbox/SlackBuilds users`, and splitting that on spaces
+ // `moved-from:Inbox/SlackBuilds users`, and splitting that on spaces
// truncated the folder to "Inbox/SlackBuilds". Restore then moved the
// messages into a folder of that name, CREATING it, so four real
// messages ended up in a directory mbsync does not sync and the user