This patch adds a config option to force the use of client side threads.
This option will override a servers Thread capability, and only build
threads on the client. It can be enabled contextually. For example:
[ui]
threading-enabled = true
[ui:folder~^Archive]
force-client-threads = true
This config would enable threads for all views, and use client threads
for folders that start with Archive. This can be advantageous if, for
example, the folder is very large and the server has a slow response due
to building threads for the entire mailbox
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Enable the :toggle-threads command to work for workers which have Thread
capability. The implementation of that feature has the side effect that
the threading-enabled config option now sets the default view (threaded
or not threaded) for any worker, not just IMAP or notmuch.
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
This patch provides a method to report backend capabilities to the UI.
The intial capabilities included in the report are Sort and Thread.
Having these available to the UI enables the client to better handle
server side threading.
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Move and Delete commands perform a store.update() when their worker is
completed and also when the method is called. This patch removes the
call performed in the store.Move and store.Delete methods.
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Update statusline to display threading status at startup. Previously,
the threading status would only display from a :toggle-threads command.
Users who had the config option threading-enabled would not see the
status, as a result.
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
This change fixes a panic caused by the selected tab being out of sync
when selecting a new one in widgets.(*Aerc).SelectedTab(). This happens
if the tab is already removed from the list of tabs, but the selection
not yet being updated.
This was achieved by moving the tabs behind updating the selection.
Signed-off-by: Moritz Poldrack <git@moritz.sh>
Acked-by: Tim Culverhouse <tim@timculverhouse.com>
Remove a header when it is empty.
Commit a253e89bda ("compose: prevent sending empty address list
headers") tried to avoid sending empty headers; but instead of deleting
the header, the empty string value was just ignored.
Fixes: https://todo.sr.ht/~rjarry/aerc/55
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Tim Culverhouse <tim@timculverhouse.com>
I didn't save the stack trace, but msglist.Selected() can create a panic
for index out of range due to the math operations in the map. My stack
trace resulted in a [-9]. This patch reuses the msgstore.Selected()
method, which already has bounds checking.
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
PGP/MIME messages are stored encrypted and/or signed in the draft folder
for security reasons. Recall will open them through the lib.MessageView
interface in order to display the message content properly in the
composer tab. If the stored message was encrypted or signed, the
recalled message in the composer will also be encrypted or signed.
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Append attachments to the composer when a message with attachments is
recalled. Before the attachement refactoring in the composer, the
recalled attachments were ignored.
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Ask for user confirmation when a recalled message is deleted after the
composer is closed but the message has not been sent yet. The message
will only be deleted automatically when the message is sent. This might
prevent data loss since the recalled message is currently deleted either
way.
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Postpone will currently call composer.WriteMessage twice: once for
counting the bytes and another time for appending the message.
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
A panic occurs when an unknown backend is used. This regression was
introduced by commit a34be9eb36 ("status: use contextual ui styleset
for statusline"). Before this commit, an error screen for the unknown
backend was displayed. The contextual ui requires an account-specific ui
config but when the backend throws an error in the constructor of the
account view, the call to aerc.SelectedAccountUiConfig() panics:
panic: runtime error: index out of range [0] with length 0 [recovered]
panic: runtime error: index out of range [0] with length 0
goroutine 1 [running]:
git.sr.ht/~rjarry/aerc/logging.PanicHandler()
git.sr.ht/~rjarry/aerc/logging/panic-logger.go:47 +0x6de
panic({0xa42760, 0xc000427068})
runtime/panic.go:844 +0x258
git.sr.ht/~rjarry/aerc/widgets.(*Aerc).SelectedTab(...)
git.sr.ht/~rjarry/aerc/widgets/aerc.go:337
git.sr.ht/~rjarry/aerc/widgets.(*Aerc).SelectedAccount(...)
git.sr.ht/~rjarry/aerc/widgets/aerc.go:313
git.sr.ht/~rjarry/aerc/widgets.(*Aerc).SelectedAccountUiConfig(0x9c99c0?)
git.sr.ht/~rjarry/aerc/widgets/aerc.go:329 +0xe9
git.sr.ht/~rjarry/aerc/widgets.(*StatusLine).uiConfig(...)
git.sr.ht/~rjarry/aerc/widgets/status.go:112
git.sr.ht/~rjarry/aerc/widgets.(*StatusLine).SetError(0xc00043a420,
{0xc000429220, 0x1b})
git.sr.ht/~rjarry/aerc/widgets/status.go:66 +0x4d
git.sr.ht/~rjarry/aerc/widgets.(*Aerc).SetError(0xa7c4d7?,
{0xc000429220?, 0xc00035ec80?})
git.sr.ht/~rjarry/aerc/widgets/aerc.go:440 +0x25
git.sr.ht/~rjarry/aerc/widgets.NewAccountView(0xc000502000,
0xc0002b8000, 0xc000440700, 0xc000098960, {0xb72d58?, 0xc000502000},
0xc00042c3c0)
git.sr.ht/~rjarry/aerc/widgets/account.go:75 +0xafa
git.sr.ht/~rjarry/aerc/widgets.NewAerc(0xc0002b8000, 0xc000098960,
{0xb73300?, 0xc0004380f0}, 0xc000420108, 0xc000430630, {0xb71580?,
0xfae9a0}, 0x2?)
git.sr.ht/~rjarry/aerc/widgets/aerc.go:92 +0x8e5
main.main()
git.sr.ht/~rjarry/aerc/aerc.go:176 +0x5ff
This can be reproduced by adding the following as the first (!) backend
to your accounts.conf:
[test]
source = test
from = test
Expected behavior would be to see the error screen with the "Unknown
Backend" text.
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
GetUiConfig was being called many times, and came up as a high CPU user
in a cpuprofile. Every call would merge a UIConfig, which is a costly
operation. Ideally, we would only need to have a config for every
account X every directory. We also have a context for subjects. This
patch stores all FOLDER and ACCOUNT level configs and reuses those
merged objects. The SUBJECT contexts are not stored in favor of merging
on-the-go, with a TODO comment to deprecate that feature and implement a
better per-message styling option. I suspect this feature is not used
very much.
Before applying this patch with my setup, GetUiConfig is called 1159
times just to open aerc. After applying, this is reduced to 37.
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
This patch changes references to uiConfig in function signatures and
structs to be pointers.
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
This patch implements :prompt completion.
The completion mechanism only provides completions when there is at least
one argument specified (prompt text).
The mechanism is based on other commands' completions and works as follows:
1. Attempts to look up a command by the name specified in args[1].
2.a On success it uses command.Complete.
2.b Otherwise, if total arguments count is lesser or equals than 2
(i.e. no command arguments specified), it attempts to complete
the command's name.
Additional effort is made to preserve prompt text, which often contains
spaces and formatting.
Signed-off-by: Sergey Smirnykh <sergey.smirnykh@siborgium.xyz>
Acked-by: Robin Jarry <robin@jarry.cc>
Notmuch server-side threading added messages within a thread that didn't
match the query into the uidstore. By doing so, several UI issues
presented:
* All "hidden" messages displayed at the bottom of the msglist
* Selected messages wouldn't open properly
This patch stops these messages from being put into the message store,
thereby resolving the UI issues
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Koni Marti <koni.marti@gmail.com>
Remove crlf from the text body when forwarding a message.
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Tested-by: Tim Culverhouse <tim@timculverhouse.com>
Append all non-multipart attachments with the -A flag. Rename the flag
for forwarding a full message as an RFC2822 attachments to -F.
Suggested-by: psykose
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Tested-by: Tim Culverhouse <tim@timculverhouse.com>
Refactor the attachment handling process in the composer. The composer
can currently only handle attachments that are stored as files (or pgp
keys). This patch removes this limitation so that any message part can
be handled as an attachment. With this we can treat files, pgp keys and
message parts on an equal footing and it will enable us also to easily
forward attachments.
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Tested-by: Tim Culverhouse <tim@timculverhouse.com>
An non-zero exit code from the execution of gpg during decryption would
prevent aerc from parsing the output of gpg. The output should always be
parsed. Gpg can exit with an error due to not being able to validate a
signature. Aerc handles this error with the UI, and therefore all output
should be parsed regardless of exit state of gpg. The parsing of stdout
will find the errors and report back to aerc properly.
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Moritz Poldrack <moritz@poldrack.dev>
For some reason the official way of getting older Go versions does not
work, this patch makes the CI downgrade the package on a package manager
level
Signed-off-by: Moritz Poldrack <git@moritz.sh>
Tested-by: builds.sr.ht <builds@sr.ht>
Acked-by: Robin Jarry <robin@jarry.cc>
This replaces a channel that is used like a context with a context.
Signed-off-by: Moritz Poldrack <git@moritz.sh>
Acked-by: Koni Marti <koni.marti@gmail.com>
Add error handling for messages that were unable to be encrypted.
Previously, messages that failed encryption would be sent with no
content. This patch adds error handling - when encryption fails, the
user is returned to the Review screen and instructed to check the public
keys for their recipients.
Reported-by: Moritz Poldrack <moritz@poldrack.dev>
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Moritz Poldrack <moritz@poldrack.dev>
Mimetype discovery for the :open command is based on the BodyStructure
of the message. This patch fixes the method which got the BodyStructure
of the message to a more generalized one, which is set post-encryption
and post-validation. This allows encrypted or signed message parts to
have their proper mimetype discovered.
Fixes: https://todo.sr.ht/~rjarry/aerc/50
Reported-by: ~ph14nix
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Koni Marti <koni.marti@gmail.com>
Fix the following go vet error:
# git.sr.ht/~rjarry/aerc/worker/notmuch
worker/notmuch/worker.go:86:19:
git.sr.ht/~rjarry/aerc/worker/types.Done composite literal uses unkeyed
fields
Signed-off-by: Moritz Poldrack <git@moritz.sh>
Acked-by: Robin Jarry <robin@jarry.cc>
Acked-by: Tim Culverhouse <tim@timculverhouse.com>
Fix the following error:
+ make GO=/home/build/go/bin/go1.13
make: *** No targets specified and no makefile found. Stop.
Fixes: dbc5bb41a5 ("ci: slim down CI Pipeline")
Signed-off-by: Moritz Poldrack <git@moritz.sh>
Acked-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
This commit changes the signature validity display to not use valid as
the default. Now invalid is the default which can cause fewer issues if
an attack vector emerges.
Signed-off-by: Moritz Poldrack <git@moritz.sh>
Tested-by: Tim Culverhouse <tim@timculverhouse.com>
Since there is a prominent checkmark for encrypted messages, it might
not be entirely clear that the contents have not been signed.
Signed-off-by: Moritz Poldrack <git@moritz.sh>
Tested-by: Tim Culverhouse <tim@timculverhouse.com>
Signed and/or encrypted PGP messages did not behave properly for pipe,
open, and save commands. Specifically, the proper Message Part would not
be passed to the command in the MessageViewer. This is due to the
encapsulation of the body structure. This patch fixes the behavior for
piping|opening|saving of message parts.
Fixes: https://todo.sr.ht/~rjarry/aerc/47
Reported-by: ~ph14nix
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Tested-by: Moritz Poldrack <moritz@poldrack.dev>
Acked-by: Robin Jarry <robin@jarry.cc>
Run go vet only for now. More linters can be added later. Run linters in
the CI pipeline.
Signed-off-by: Moritz Poldrack <git@moritz.sh>
Acked-by: Robin Jarry <robin@jarry.cc>
Fix the following go vet error:
lib/calendar/calendar.go:191:11: github.com/arran4/golang-ical.Attendee
composite literal uses unkeyed fields
Signed-off-by: Moritz Poldrack <git@moritz.sh>
Acked-by: Robin Jarry <robin@jarry.cc>
Since the totality of sourcehut only has 4 CI slots at the moment, slim
the CI pipeline down to the lowest common denominator:
Linux (alpine-edge)
- GNU make
- latest Go version
- Go1.13
OpenBSD
- BSD make
- latest available Go Version (currently lagging behind 1 version)
We might also want to consider changing OpenBSD to FreeBSD as to my
knowledge FreeBSD is the more common Home-Computer-Version of BSD
instead of OpenBSD which is mainly used for servers. (please don't lynch
me, dear 3 OpenBSD people)
Signed-off-by: Moritz Poldrack <git@moritz.sh>
Acked-by: Robin Jarry <robin@jarry.cc>
Add a dev target which enables Go's race detector. This requires CGo to
be enabled and reduces performance significantly, but helps in finding
data races which can lead to hard to diagnose bugs.
Signed-off-by: Moritz Poldrack <git@moritz.sh>
Acked-by: Robin Jarry <robin@jarry.cc>
Replace the implicit shell-parsing with explicitly running the command.
This allows the built version to be reflected in the build log.
Signed-off-by: Moritz Poldrack <git@moritz.sh>
Acked-by: Robin Jarry <robin@jarry.cc>
Add the -trimpath flag to the default build command to remove the user's
path from stack traces.
Use a separate BUILD_OPTS make var to avoid it being accidentally
overridden on the command line.
Signed-off-by: Moritz Poldrack <git@moritz.sh>
Acked-by: Robin Jarry <robin@jarry.cc>
There are concurrent threads that are accessing and modifying
IMAPWorker.seqMap (the mapping of sequence numbers to message UIDs).
This can lead to crashes when trying to add and remove a message ID.
panic: runtime error: index out of range [391] with length 390
goroutine 1834 [running]:
git.sr.ht/~rjarry/aerc/logging.PanicHandler()
logging/panic-logger.go:47 +0x6de
panic({0xa41760, 0xc0019b3290})
/usr/lib/golang/src/runtime/panic.go:838 +0x207
git.sr.ht/~rjarry/aerc/worker/imap.(*IMAPWorker).handleFetchMessages.func1()
worker/imap/fetch.go:214 +0x185
created by git.sr.ht/~rjarry/aerc/worker/imap.(*IMAPWorker).handleFetchMessages
worker/imap/fetch.go:209 +0x12b
Use a map which makes more sense than a simple array for random access
operations. Also, it allows better typing for the key values. Protect
the map with a mutex. Add internal API to access the map. Add basic unit
tests to ensure that concurrent access works.
Fixes: https://todo.sr.ht/~rjarry/aerc/49
Signed-off-by: Robin Jarry <robin@jarry.cc>
Acked-by: Moritz Poldrack <moritz@poldrack.dev>
The default config had completion-{delay,popover} in the [viewer]
section, but they belong in the [ui] section
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Moritz Poldrack <moritz@poldrack.dev>
Acked-by: Robin Jarry <robin@jarry.cc>
When using section.MapTo(struct) (go-ini), if the struct has a default
value for a time.Duration type, a zero-value in the config will not
overwrite the default. If the type is *time.Duration, it will be
overwritten properly. One consideration was to change all
time.Duration types to *time.Duration. This method was chosen for ease
of implementation.
For example, if you set dirlist-delay = 0s, the delay will be 200ms.
This can be observed by logging the value just after mapping the ui
section in config.go. A config value of 0.1ms will have a delay of
0.1ms.
Currently, aerc has 4 time.Duration config values:
1. DirlistDelay - default 200 ms
2. CompletionDelay - default 250 ms
3. CheckMail - default unset (0)
4. CheckMailTimeout - default 10 s
1, 2, and 4 have a non-zero default value and are subject to this bug.
Only 1 and 2 are fixed in this patch. Number 4 would not make sense to
have a 0 second timeout, therefore we can prevent the user from doing
this by keeping it as it is.
Another option could be to set these to 0 in config.go. The default
config (aerc.conf) has these keys in it with their default values.
Presumably, we don't need to set them again in config.go. If a user
deletes the config values out of aerc.conf, the UI will function but
with 0s delays.
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Tested-by: Moritz Poldrack <moritz@poldrack.dev>
Add a default keybind to open messages in the default Postpone folder
("Drafts") in edit-mode.
A frequent question on IRC is "how do I edit a draft?". When a user
selects a Draft and presses <Enter>, the intent is usually to edit that
draft. This commit makes this the default behaviour for the default
Postpone folder.
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Add option to specify folder-specific binds for message lists. The binds
are layered: any existing binds in [messages] are overwritten by a more
specific bind in say, [messages:folder=Drafts]. The order is currently:
[messages] < [messages:account=<account>] < [messages:folder=<folder>]
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Add option to cache headers for imap accounts. Cache db is located at
$XDG_CACHE_DIR/aerc/{account name}. The cache is cleaned of stale
entries when aerc is first opened.
Two new account level configuration options are introduced:
* cache-headers (Default: false)
* cache-max-age (Default: 30 days (720 hours))
The change in worker/imap/open.go is to set the selected directory. This
is required to access the UIDVALIDITY field, which is used in
combination with the message ID to form the key for use in the cache db.
The key structure is: "header.{UIDVALIDITY}.{UID}"
Where reasonable, cache does not stop aerc from running. In general, if
there is an error in the cache, aerc should continue working as usual.
Errors are either displayed to the user or logged.
All messages are stored without flags, and when retrieved have the flags
set to SEEN. This is to prevent UI flashes. A new method to
FetchMessageFlags is introduced to update flags of cached headers. This
is done asynchronously, and the user will see their messages appear and
then any flags updated. The message will initially show as SEEN, but
will update to unread. I considered updating the cache with the
last-known flag state, however it seems prudent to spare the R/W cycle
and assume that - eventually - all messages will end up read, and if it
isn't the update will occur rather quickly.
Note that leveldb puts a lock on the database, preventing multiple
instances of aerc from accessing the cache at the same time.
Much of this work is based on previous efforts by Vladimír Magyar.
Implements: https://todo.sr.ht/~rjarry/aerc/2
Thanks: Vladimír Magyar <vladimir@mgyar.me>
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Tested-by: inwit <inwit@sindominio.net>
Reviewed-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>