notmuch-mailmover is a tool to move notmuch tagged mails into Maildir folders (e.g., created by offlineimap/mbsync).
For example, you can move all mails tagged as trash
to the Trash
folder.
Some use-cases are:
- delete mail from IMAP server (e.g. move trash mail to a non-synced folder and let offlineimap/mbsync do the rest)
- sync your notmuch tags across devices by using notmuch-mailmover in combination with offlineimap/mbsync (this is similarly to muchsync but easier to setup since you don't need a muchsync server)
- purge old mails from the IMAP server (by moving them out of synced folders)
Only Linux is tested, but Windows and Mac should work as well.
notmuch-mailmover-git is available on the AUR. Use your favorite AUR helper to install it, e.g.
$ yay -S notmuch-mailmover-git
$ nix-env -iA notmuch-mailmover
Otherwise, you have to build from source. You need the following build dependencies (see install-deps.sh):
- Rust
- libnotmuch-dev
- liblua5.4-dev
Then run
cargo install --git 'https://github.com/michaeladler/notmuch-mailmover/'
It's recommended to run notmuch-mailmover
as part of your notmuch pre-new hook.
You can also invoke notmuch-mailmover
directly, but don't forget to run notmuch new
afterward (this isn't necessary if you add it as a pre-hook).
Running notmuch-mailmover
for the first time will create $XDG_CONFIG_HOME/notmuch-mailmover/config.yaml
.
Then edit the file as you like, see below for an example.
Alternatively, it's possible to write the configuration in Lua 5.4 by creating config.lua
instead.
See the provided config.lua for an example.
The configuration is largely self-explanatory, except perhaps for the choice of the rule_match_mode
.
You need to decide whether you want your rules to be pairwise distinct (meaning the queries must not overlap) or ambiguous (where the first or last matching rule wins).
The unique
approach is more explicit but also more verbose, while the first
or all
approach is more concise but may lead to unexpected behavior if you have overlapping rules, as the order of the rules matters.
The unique
match-mode also allows to disambiguate message files based on a
prefix of their path, bypassing a limitation of folder:
and path:
notmuch
search terms.
The provided config.yaml does the following:
- move mails tagged as
trash
to folderTrash
- move mails tagged as
sent
to folderSent
- move mails tagged as
archive
to folderArchive
See config_first.yaml for a different approach (using the first
strategy for rule_match_mode
).
See config_filter_with_prefix.yaml
for disambiguation in unique
match-mode with prefixes.
While notmuch-mailmover
checks if two queries match the same messages and
refuses to proceed if rules are ambiguous, it is not idempotent, i.e. subsequent
runs may do different things.
This is noticeable with queries containing folder:
or path:
search terms.
Indeed, given the following mail directory:
.
├── left
│ └── msg1
└── right
└── msg2
and the following configuration:
rules:
- folder = right
query = folder:left
- folder = left
query = folder:right
notmuch-mailmover
would exchange msg1
and msg2
on each run.
It is advised that the user only use queries that aren't affected by
notmuch-mailmover
actions, i.e., queries without folder:
and path:
search
terms.
This work is inspired by afew's Mailmover plugin but doesn't require you to setup rules for each folder individually. Instead, notmuch-mailmover applies your rules once to all folders (so it may be easier to configure if you have many folders).