Commit graph

1551 commits

Author SHA1 Message Date
Tim Culverhouse
921382a9bf maildir: do not send dircontents on fs event
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>
2022-08-30 21:42:37 +02:00
Robin Jarry
8eab829649 changelog: add missing entry
Signed-off-by: Robin Jarry <robin@jarry.cc>
2022-08-24 17:14:24 +02:00
Tim Culverhouse
1c9fc7b6b1 maildir: remove filename encoded UID when moving messages
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>
2022-08-24 17:00:44 +02:00
Robin Jarry
8f8dee8303 aerc: fix build when GOFLAGS contains spaces
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>
2022-08-24 17:00:39 +02:00
Robin Jarry
3ba8a3b750 contributing: refine commit message rules
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>
2022-08-23 17:16:55 +02:00
Ben Cohen
cd72812781 archive: respect the next-message-on-delete flag
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>
2022-08-22 20:33:28 +02:00
Tim Culverhouse
50992cb9e6 main: add cli flag to load specified account(s)
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>
2022-08-22 20:33:04 +02:00
Thomas Faughnan
5ed849688a parse: remove trailing whitespace from rfc1123z regex
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>
2022-08-22 15:46:56 +02:00
Tim Culverhouse
c98f704874 move: enable MoveMessages from msgstore
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>
2022-08-22 15:46:55 +02:00
Tim Culverhouse
af72ca3607 maildir: implement MoveMessages handling
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>
2022-08-22 15:46:54 +02:00
Tim Culverhouse
64e1a7ca93 imap: implement MoveMessages handling
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>
2022-08-22 15:46:53 +02:00
Tim Culverhouse
57933f65ab mbox: implement MoveMessages handling
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>
2022-08-22 15:46:52 +02:00
Tim Culverhouse
e8c5bb641a worker: introduce MoveMessages type
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>
2022-08-22 15:46:51 +02:00
Tim Culverhouse
a0a5ba1538 imap: create copy of uids to retain sort order
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>
2022-08-22 15:46:49 +02:00
Robin Jarry
d7e6dc3649 aerc: add build info to version string
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>
2022-08-22 15:46:33 +02:00
Koni Marti
45e506e6ae delete: fix find-next function
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>
2022-08-22 10:04:12 +02:00
Koni Marti
588be1a284 store: improve cursor position
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>
2022-08-22 10:01:46 +02:00
Robin Jarry
d138da0c9f dirtree: fix build errors
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>
2022-08-22 09:57:23 +02:00
Thomas Faughnan
62ac7a5071 doc: fix man page typos
"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>
2022-08-22 09:49:26 +02:00
Sean Stiglitz
23639acd50 doc: clarify behavior of token_endpoint parameter
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>
2022-08-22 09:49:24 +02:00
Sijmen
db39ca181a dirtree: add dirtree-collapse config setting
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>
2022-08-22 09:45:02 +02:00
Robin Jarry
7377b8b05a changelog: add missing entries
Signed-off-by: Robin Jarry <robin@jarry.cc>
2022-08-22 09:41:05 +02:00
Tim Culverhouse
e1b62db583 fix: Set proper UIConfig for msgstores
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>
2022-08-22 09:30:37 +02:00
Koni Marti
0db924dc14 filters: fix calendar filter parsing
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>
2022-08-22 09:30:37 +02:00
Koni Marti
132b5fed9e mbox: filtering for mbox accounts
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>
2022-08-22 09:30:37 +02:00
Koni Marti
117f99e187 mark: (un)mark message threads
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>
2022-08-22 09:30:37 +02:00
Koni Marti
b12dd9f926 mark: allow multiple visual selections
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>
2022-08-22 09:30:37 +02:00
Koni Marti
16dbb94221 util: fetch message headers for nil messages
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>
2022-08-22 09:30:37 +02:00
Koni Marti
22e6c9e4fa store: remove unneeded header callback
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>
2022-08-22 09:30:37 +02:00
Koni Marti
cfc19a7ec2 store: extract marking behavior and add tests
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>
2022-08-22 09:30:37 +02:00
Koni Marti
ee961d3b1d wizard: add plaintext password warning
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>
2022-08-22 09:30:37 +02:00
Koni Marti
5c8a749cfa binds: display active keybinds in a dialog box
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>
2022-08-22 09:30:37 +02:00
Koni Marti
e31dbe9f31 widgets: add list box with filter/scrollbar
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>
2022-08-22 09:30:37 +02:00
Koni Marti
00e908e2ae widgets: add dialog interface
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>
2022-08-22 09:30:37 +02:00
Moritz Poldrack
9cffc45f03 go: removed io/ioutil
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>
2022-08-22 09:30:19 +02:00
Robin Jarry
1b91b68e73 bindings: fix FormatKeyStrokes for <tab> and <enter>
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>
2022-08-10 09:51:29 +02:00
Moritz Poldrack
d1838c8063 restore compatibility with Go 1.16
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>
2022-08-06 23:12:35 +02:00
Tim Culverhouse
67ded18fb6 readme: make contribution section more obvious
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>
2022-08-06 23:12:24 +02:00
Moritz Poldrack
8c64bda5a0 doc: add contribution guidelines including code style
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>
2022-08-05 21:57:12 +02:00
Tim Culverhouse
6057d156e6 delete: revert deleted messages if Delete is unsupported
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>
2022-08-05 21:57:12 +02:00
Moritz Poldrack
602a5778e8 go: bumped minimum required version 1.16
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>
2022-08-05 21:55:26 +02:00
Robin Jarry
6b1afc3ae3 tests: fix errors after lint series
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>
2022-08-04 22:52:40 +02:00
Moritz Poldrack
1b4b225318 lint: add information about false positive on missing notmuch
Signed-off-by: Moritz Poldrack <moritz@poldrack.dev>
Acked-by: Robin Jarry <robin@jarry.cc>
2022-08-04 21:58:09 +02:00
Moritz Poldrack
57de50b7d4 lint: add golangci-lint to the linters
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>
2022-08-04 21:58:06 +02:00
Moritz Poldrack
70bfcfef42 lint: work nicely with wrapped errors (errorlint)
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>
2022-08-04 21:58:04 +02:00
Moritz Poldrack
978d35d356 lint: homogenize operations and minor fixes (gocritic)
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>
2022-08-04 21:58:01 +02:00
Moritz Poldrack
c882cf9960 lint: removed unused code (deadcode, structcheck, unused)
Signed-off-by: Moritz Poldrack <moritz@poldrack.dev>
Acked-by: Robin Jarry <robin@jarry.cc>
2022-08-04 21:58:00 +02:00
Moritz Poldrack
5ca6022d00 lint: ensure errors are at least logged (errcheck)
Signed-off-by: Moritz Poldrack <moritz@poldrack.dev>
Acked-by: Robin Jarry <robin@jarry.cc>
2022-08-04 21:57:57 +02:00
Moritz Poldrack
a8d631177f lint: merge declaration and assignment (S1021)
Signed-off-by: Moritz Poldrack <moritz@poldrack.dev>
Acked-by: Robin Jarry <robin@jarry.cc>
2022-08-04 21:57:55 +02:00
Moritz Poldrack
ef599aa8fc lint: simplify code (gosimple)
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>
2022-08-04 21:57:52 +02:00