The maildir worker watches the file system for events (new mail, moved
mail, copied mail, etc). On an event, the worker sends a
DirectoryContents message and a DirectoryInfo message.
Do not send DirectoryContents on FS Event in the maildir worker. The
DirectoryInfo message already triggers the UI to request the new
DirectoryContents, and does so in a more predictable way (IE any
currently applied filter is applied).
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
The built-in maildir.Dir.Move method performs an OS level file rename,
which allows for preserving file creation time. Commit c98f704874
("move: enable MoveMessages from msgstore") enabled the use of the Move
method for maildir. One particular maildir synchronizer (isync/mbsync)
encodes the UID within the filename of the email and cannot recover if
the UID is preserved during a move. mbsync encodes filenames like so:
/path/to/email/{maildir-key},U={uid}:2,S
OfflineIMAP encodes the UID within the filename, but also encodes a hash
of the originating folder so that it can recover from a move without a
rename of the underlying file. OfflineIMAP encodes like so:
/path/to/email{maildir-key},U={uid},FMD5={folder-hash}:2,S
Remove encoded UIDs of the form `,U={uid}` from filenames to prevent
sync issues.
Fixes: https://todo.sr.ht/~rjarry/aerc/75
Fixes: c98f704874 ("move: enable MoveMessages from msgstore")
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Due to multiple levels of nested quoting, it is not possible to escape
spaces and/or quotes from GOFLAGS and pass the value to go build
-ldflags to set a compile time variable.
Encode main.Flags in base64 and decode it when reading it.
Fixes: d7e6dc3649 ("aerc: add build info to version string")
Signed-off-by: Robin Jarry <robin@jarry.cc>
Acked-by: Moritz Poldrack <moritz@poldrack.dev>
There were a few hiccups recently. Make sure that there are no
ambiguities.
Signed-off-by: Robin Jarry <robin@jarry.cc>
Acked-by: Tim Culverhouse <tim@timculverhouse.com>
Reuse the next-message-on-delete configuration flag to mirror the
behavior of delete when archiving.
Signed-off-by: Ben Cohen <ben@bencohen.net>
Acked-by: Robin Jarry <robin@jarry.cc>
Make it possible to specify which account(s) to load. Preserve listed
order when creating account tabs.
aerc -a <account-name[,account-name]>
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
When there is no Date header in a message, aerc falls back to the
Received header and tries to extract an rfc1123z date from it
(introduced in commit d1600e46). The current regex for extracting the
date incorrectly allows for trailing whitespace, causing time.Parse() to
fail inside of parseReceivedHeader(). As a result, the message's date is
shown as "???????????????????" in the message list and as
"0000-12-31 07:03 PM" in the message view (the latter is likely related
to the zero value of time.Time).
Steps to reproduce:
1) Send yourself a message with no Date header, e.g. with msmtp:
printf 'Subject: foo bar\n\nbody text\n' | msmtp --set-date-header=off me@example.com
2) Note the message's displayed date in aerc's message list and message
view.
Signed-off-by: Thomas Faughnan <tom@tjf.sh>
Acked-by: Robin Jarry <robin@jarry.cc>
Enable the use of MoveMessages worker messages from the UI to the
backend. Completes implemention of MoveMessages for all supported
backends.
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Implement MoveMessages in the maildir worker. go-maildir supports Move
operations by default, and is functionally equivalent to a OS-level
rename. Creation date of the file is preserved by using Move, which is
used by at least one maildir-to-IMAP synchronizer (isync/mbsync). The
previous move method of copy-and-delete would reset the creation date of
the message, and potentially cause sorting issues in other email
clients.
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Implement MoveMessages in the imap backend. go-imap includes the MOVE
Imap extension by default, and if a server does not support it the
command fallsback to a copy-and-delete operation. Servers with the MOVE
extension will see a slight performance increase when moving messages
due to fewer round trips. The IMAP implementation uses a MessagesMoved
worker message to avoid polling the destination mailbox.
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Implement MoveMessages handling in the mbox backend. The mbox backend
exists entirely in memory, so the handling is equivalent to a
copy-and-delete.
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Introduce a MoveMessages worker message to use for improved message
moving in subsequent patches.
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Commit fdfec2c07a seqmap: refactor seqmap to use slice instead of map
introduced a regression to imap sorting (if supported). The slice passed
to seqmap was being sorted in place by UID, thus breaking any sort order
sent by the server.
Create a copy of the slice to retain the sort order reported to the UI
while also keeping a correct map for seqnum -> UID in the worker.
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Example:
$ aerc -v
aerc 0.11.0 +notmuch (go1.18.4 amd64 linux)
Also include that version information in the debug and panic logs.
debug.ReadBuildInfo() is only available in go 1.18+. Add a new variable
set at build time to store $GOFLAGS.
Suggested-by: Tim Culverhouse <tim@timculverhouse.com>
Signed-off-by: Robin Jarry <robin@jarry.cc>
Acked-by: Moritz Poldrack <moritz@poldrack.dev>
Fixes the find-next-loop when deleting the last message. The reverse
loop with store.Prev() will break too early because the value of
'previous' was not reset correctly.
Fixes: d941960f "delete: improve find next function"
References: https://todo.sr.ht/~rjarry/aerc/59
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Tested-by: Tim Culverhouse <tim@timculverhouse.com>
Improve cursor re-positioning while filtering with and without threads.
Reposition cursor in client-side threading mode with a callback that is
set during store.NextPrev(). Run callback when the threads are
constructed in order to reposition the cursor correctly. The callback is
deactivated when store.Select() is called.
Steps to reproduce two issues:
* Reproduce issue 1:
1. Activate client-side threading
2. Apply a filter, e.g. :filter -f Koni
3. Move cursor around so that a message is highlighted
4. clear filter with :clear
5. The cursor is expected to remain on the selected message but is
actually not
* Reproduce issue 2:
1. Activate client-side threading
2. Go the end of the message list
2. Apply a filter, e.g. :filter -f Koni
5. The cursor is now at the end of the filtered results instead of at
the beginning
This patch fixes both of those issues. Tested in regular and threaded
view according to the following check list (expected behavior in
parenthesis):
1. Apply filter from a message that remains in the filter (cursor on message,
message selected)
2. Apply filter from a message that will not remain (cursor at the top,
no message selected)
3. Clear filter (cursor remains on message, message selected)
4. Scroll line-by-line (threads: cursor remains on line, does not "jump"
with message)
5. Search (cursor on first result)
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Tested-by: Tim Culverhouse <tim@timculverhouse.com>
Fix the following errors:
widgets/dirtree.go:401:18: not enough arguments in call to dt.UiConfig
have ()
want (string) (typecheck)
if dt.UiConfig().DirListCollapse != 0 {
^
widgets/dirtree.go:402:38: not enough arguments in call to dt.UiConfig
have ()
want (string) (typecheck)
node.Hidden = depth > dt.UiConfig().DirListCollapse
^
Since commit e0b62db583c3 ("fix: Set proper UIConfig for msgstores"),
DirectoryTree.UiConfig() takes a path parameter.
Fixes: db39ca181a ("dirtree: add dirtree-collapse config setting")
Signed-off-by: Robin Jarry <robin@jarry.cc>
"behaviour" is not necessarily a typo, but currently 3/4 instances of
the word in the docs use the spelling "behavior".
Signed-off-by: Thomas Faughnan <tom@tjf.sh>
Acked-by: Robin Jarry <robin@jarry.cc>
Add language explaining the token_endpoint parameter is actually
optional and what happens when included or omitted.
Signed-off-by: Sean Stiglitz <stigz+sr.ht@netsplit.dev>
Acked-by: Robin Jarry <robin@jarry.cc>
Adds a setting to the configuration to choose at which level the
folders in the dirtree are collapsed by default.
In my case, this is useful because my organisation has some rather deep
nesting in the folder structure, and a _lot_ of folders, and this way I
can keep my dirtree uncluttered while still having all folders there if
I need them.
Signed-off-by: Sijmen <me@sijman.nl>
Acked-by: Koni Marti <koni.marti@gmail.com>
The merged UIConfig used to create new message stores is based on the
selected directory. If the message store is created by other means than
selecting (ListDirectories for maildir/notmuch/mbox, or check-mail) it
may have an incorrect configuration if the user has folder-specific
values for:
- Threaded view
- Client built threads
- Client threads delay
- Sort criteria
- NewMessage bell
Use the correct merged UIConfig when creating a new message store.
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Fix parsing of colons. Since the field separator is also the colon, it
could mess up the parsed fields, i.e. a subject line like "WG: dinner"
could end up as "WG" instead of keeping the entire string.
Fixes: ab941eb ("filters: posix compliant rewrite of calendar filter")
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Use FetchDirectoryContents for filtering instead of the SearchDirectory
message. This was an omission from rebasing the mbox worker and from not
realizing that c2f4404f ("threading: enable filtering of server-side
threads") changed the way we filter in the message store for the
server-side threading implementation. This patch enables filtering for
the mbox worker.
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Mark or unmark the shown message threads. Threads must be available in the
message store. Use the -T option for the mark or unmark commands. Can be
used in combination with the toggle flag (-t).
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
When entering visual selection mode, the current selection is deleted.
This patch extends the visual mode behavior to select multiple blocks of
messages.
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Fix large archive operations that covers messages in the store with
unfetched headers. Commit e5ad877af5 ("msgstore: fetch missing headers
in visual mode") fixed this for the visual selection mode but omitted
the case when 'mark -a' is used to mark all messages.
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
The message store keeps a map of callbacks for headers that are being
fetched. This is not used anywhere in the code base. Instead of a
func(*types.MessageInfo) callback use a general
func(types.WorkerMessage) in the worker.PostAction function to make it
more useful. This callback allows now to get a feedback when all headers
are fetched successfully. Note that the pending header map remains so
that the same header is not fetched multiple times.
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Separate the marking functions from the message store and extract the
marking behavior into its own class with tests.
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Warn users that the passwords are stored as plaintext. Add
recommmendation to use personal password store.
Implements: https://todo.sr.ht/~rjarry/aerc/39
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Show contextual keybinds in a textbox when using the ':help keys'
command. This command is bound to '?' by default.
Fixes: https://todo.sr.ht/~rjarry/aerc/42
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Implement a scrollable text box that displays a list of strings which
can be filtered. The widget is closed by pressing ESC or ENTER. If ENTER
is pressed and an entry has been selected, this text will be passed to
the closing callback.
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Implement an interface for aerc's dialog implementation. Provide dialogs
the ability to set their own height and width of their drawing context.
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Since the minimum required version of Go has been bumped to 1.16, the
deprecation of io/ioutil can now be acted upon. This Commit removes the
remaining dependencies on ioutil and replaces them with their io or os
counterparts.
Signed-off-by: Moritz Poldrack <git@moritz.sh>
Acked-by: Robin Jarry <robin@jarry.cc>
Sometimes, a <tab> or <enter> key in a binding will be formatted as
a <c-i> or <c-m> respectively. This is because these keys are
equivalent. Prefer their canonical name instead of the control modifier
variant.
Fixes: 5e600d7ab4 ("binds: fix ctrl-i and ctrl-m key definitions")
Signed-off-by: Robin Jarry <robin@jarry.cc>
Tested-by: Koni Marti <koni.marti@gmail.com>
Fix build error with go 1.16:
//go:build comment without // +build comment
Signed-off-by: Moritz Poldrack <git@moritz.sh>
Acked-by: Robin Jarry <robin@jarry.cc>
Move link to contribution guidelines to it's own section in README.
Fixes: 8c64bda5a0 ("doc: add contribution guidelines including code style")
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
The Linux kernel code style rules have been used as a well-tested basis
and sections pertaining C-specific rules – such as macros – have been
removed. For it a short section on the used formatter is added for
further reference.
Link: https://www.kernel.org/doc/html/v5.19-rc8/process/coding-style.html
Signed-off-by: Moritz Poldrack <git@moritz.sh>
Signed-off-by: Robin Jarry <robin@jarry.cc>
Delete operations are not supported by the notmuch backend. Revert
deleted messages when the operation is not supported, and reselect the
original selection.
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Tested-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Due to github.com/daixiang0/gci requiring io/fs, the minimum required
Go version for aerc needs to be bumped to 1.16
Signed-off-by: Moritz Poldrack <git@moritz.sh>
Signed-off-by: Robin Jarry <robin@jarry.cc>
Fix the following test failures:
FAIL: TestMessageInfoHandledError (0.00s)
parse_test.go:53: could not parse envelope: date parsing failed:
unrecognized date format:
FAIL: TestReader (0.07s)
gpg_test.go:27: using GNUPGHOME = /tmp/TestReader2384941142/001
reader_test.go:108: Test case: Invalid Signature
reader_test.go:112: gpg.Read() = gpgmail: failed to read PGP
message: gpg: failed to run verification: exit status 1
Fixes: 5ca6022d00 ("lint: ensure errors are at least logged (errcheck)")
Fixes: 70bfcfef42 ("lint: work nicely with wrapped errors (errorlint)")
Signed-off-by: Robin Jarry <robin@jarry.cc>
Signed-off-by: Moritz Poldrack <moritz@poldrack.dev>
go vet has been removed from the lint step as it is run by the new
linter.
Signed-off-by: Moritz Poldrack <moritz@poldrack.dev>
Acked-by: Robin Jarry <robin@jarry.cc>
Error wrapping as introduced in Go 1.13 adds some additional logic to
use for comparing errors and adding information to it.
Signed-off-by: Moritz Poldrack <moritz@poldrack.dev>
Acked-by: Robin Jarry <robin@jarry.cc>
Apply GoDoc comment policy (comments for humans should have a space
after the //; machine-readable comments shouldn't)
Use strings.ReplaceAll instead of strings.Replace when appropriate
Remove if/else chains by replacing them with switches
Use short assignment/increment notation
Replace single case switches with if statements
Combine else and if when appropriate
Signed-off-by: Moritz Poldrack <moritz@poldrack.dev>
Acked-by: Robin Jarry <robin@jarry.cc>
Replaces infinite for loops containing a select on a channel with a
single case with a range over the channel.
Removes redundant assignments to blank identifiers.
Remove unnecessary guard clause around delete().
Remove `if condition { return true } return false` with return condition
Signed-off-by: Moritz Poldrack <moritz@poldrack.dev>
Acked-by: Robin Jarry <robin@jarry.cc>