Debounce client-side thread building in the message store. Debouncing is
useful when multiple messages are loaded, i.e. when scrolling with
PgUp/PgDown.
Without the debouncing, all client-side threads will be built everytime
the message store is updated which creates a noticable lag in the
message list ui when client-side threading is activated.
The default debouncing delay can be changed by changing
'client-threads-delay' in the UI config section.
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
check-mail was triggered to run at startup after a Done:FetchHeaders
message. This message would only occur if there were messages in the
default folder. In the case where there are no messages, check-mail
would not run at startup as intended. Run check-mail even if there are
no messages found in the default folder at startup.
Fixes: https://todo.sr.ht/~rjarry/aerc/60
Reported-by: ~foutrelis
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Change the message store architecture from an index-based to a uid-based
one. Key advantage of this design approach is that no reselect mechanism
is required anymore since it comes with the design for free.
Fixes: https://todo.sr.ht/~rjarry/aerc/43
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Tested-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
This prevents dereferencing nil when updating RUE counts. This seems to
happen for messages that were not yet loaded, but were selected for
copy operation. This can happen when using `mark -a` command and then
initiating copy operation.
When such message is encountered during RUE counting, it is stopped
and full recount is triggered.
**Original backtrace:**
Error: runtime error: invalid memory address or nil pointer dereference
goroutine 1 [running]:
runtime/debug.Stack()
runtime/debug/stack.go:24 +0x65
git.sr.ht/~rjarry/aerc/logging.PanicHandler()
git.sr.ht/~rjarry/aerc/logging/panic-logger.go:45 +0x64b
panic({0x9e5f80, 0xecc360})
runtime/panic.go:844 +0x258
git.sr.ht/~rjarry/aerc/widgets.(*AccountView).onMessage(0xc0001be870, {0xb7f860?, 0xc00073b4c0?})
git.sr.ht/~rjarry/aerc/widgets/account.go:353 +0xecc
git.sr.ht/~rjarry/aerc/widgets.(*AccountView).Tick(0xc0001be870)
git.sr.ht/~rjarry/aerc/widgets/account.go:116 +0x6c
git.sr.ht/~rjarry/aerc/widgets.(*Aerc).Tick(0xc0003ba000)
git.sr.ht/~rjarry/aerc/widgets/aerc.go:144 +0x7a
main.main()
git.sr.ht/~rjarry/aerc/aerc.go:225 +0xbb8
Signed-off-by: Ensar Sarajčić <dev@ensarsarajcic.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Do not pass logger objects around anymore. Shuffle some messages to make
them consistent with the new logging API. Avoid using %v when a more
specific verb exists for the argument types.
The loggers are completely disabled (i.e. Sprintf is not even called)
by default. They are only enabled when redirecting stdout to a file.
Signed-off-by: Robin Jarry <robin@jarry.cc>
Acked-by: Moritz Poldrack <moritz@poldrack.dev>
The Tabs object exposes an array of Tab objects and the current selected
index in that array. The these two fields are sometimes modified in
goroutines, which can lead to data races causing fatal out of bounds
accesses on the tab array.
Hide these fields as private API. Expose only what needs to be seen from
the outside. This will prepare for protecting concurrent access with
a lock in the next commit.
Signed-off-by: Robin Jarry <robin@jarry.cc>
Acked-by: Koni Marti <koni.marti@gmail.com>
This function returns an ui.Drawable. Use a more explicit name. This
prepares for adding a new SelectedTab function which will return
an ui.Tab.
Signed-off-by: Robin Jarry <robin@jarry.cc>
Acked-by: Koni Marti <koni.marti@gmail.com>
Cleanup existing PartSwitcher before recreating a new one when command
:toggle-headers is executed, ensuring existing part pagers are cleaned
up. This fixes a leak in pager processes when :toggle-headers is
executed repeatedly without closing the message.
Signed-off-by: Jose Lombera <jose@lombera.dev>
Acked-by: Koni Marti <koni.marti@gmail.com>
When using multiple accounts, the contacts may be different. Allow using
specific address book commands per account.
Signed-off-by: Robin Jarry <robin@jarry.cc>
Acked-by: Moritz Poldrack <moritz@poldrack.dev>
Use Aerc as an mbox viewer. Open an mbox file from the command line in a
new tab with the mbox backend. Provide a convenient and quick way to
display emails from an mbox.
Usage: aerc mbox://<path>
where the path can either be a directory or an mbox file. If it is a
directory, every file with an .mbox suffix will be loaded as a folder.
The account config will be copied from the selected account. This allows
the answer emails in the mbox account.
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
This patch refactors reselection of a message during certain operations
(searching, filtering, clearing, deleting, moving, new message arrival).
The addition of server-side filtering for threaded views broke the
existing reselection logic.
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
This patch enables the filtering of a threaded view which uses
server-built threads. Filtering is done server-side, in order to
preserve the use of server-built threads.
In adding this feature, the filtering of notmuch folders was brought up
to feature parity with the other workers. The filters function the same
(ie: they can be stacked). The notmuch filters, however, still use
notmuch syntax for the filtering.
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
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>
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>
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>
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>
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>
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>
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>
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>
Parse http links from a message and display them as completions in the
:open-link command.
Add the following binds to the [view] section in your binds.conf:
<C-l> = :open-link <space>
Parsing can be disabled in aerc.conf by setting parse-http-links to
false in the viewer section.
Thanks to Moritz for the help with the regular expression.
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Reviewed-by: Moritz Poldrack <git@moritz.sh>
Acked-by: Robin Jarry <robin@jarry.cc>
Commit 8b6f971 broke ruestring counts when AccurateCounts=true, which
primarily occur from a checkmail. This restores the functionality.
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Parse the Authentication-Results header and display it in the message
viewer (not enabled by default). DKIM, SPF and DMARC authentication
methods are supported. Implement recommendation from RFC 7601 Sec 7.1 to
have an explicit list of trustworthy hostnames before displaying the
authentication results. Be aware that the authentication headers can be
forged.
To display the results for a specific authentication method, add the
corresponding name to the layout of headers in the viewer section of
aerc.conf, e.g. to display all three, use:
header-layout = From|To,Cc|Bcc,Date,Subject,DKIM|SPF|DMARC
More information will be displayed when "+" is appended to the
authentication method name, e.g. DKIM+ or SPF+ or DMARC+.
Also, add the trustworthy hosts per account with the trusted-authres
parameter, e.g.
trusted-authres = *
to trust every host or use regular expressions for a finer control.
Multiple hosts can be entered as a comma-separated list. Authentication
results will only be displayed when the host is listed in the
trusted-authres list.
Link: https://datatracker.ietf.org/doc/html/rfc7601
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Tested-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Commit 2027223a created a panic when attempting to clear the dirlist
when the config option dirlist-tree is set to false.
This patch fixes that panic by creating a dirlist.ClearList() function
to prevent needing to check a callback.
Tested with both dirlist-tree=false and true
Fixes: 2027223ab3 ("fix: clear dirlist on disconnect")
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
A message of Done:Disconnect will trigger an update of the dirlist. An
update of the dirlist will issue a ListDirectories message, which causes
an imap: client not ready error by trying to use the imap connection -
which is disconnected. By not issuing the update, we prevent using a
disconnected client.
This patch checks for connection state prior to updating the dirlist. A
disconnected state will clear out the dirlist.
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
When moving/copying/deleting/archiving a message in imap, the RUE counts
displayed in the dirlist would not update properly. Maildir has (had) an
implementation that recounts the entire directory and updates the
DirectoryInfo after one of these actions.
This patch implements a more efficient method of updating, and also
enables it to apply to IMAP without any additional requests. Upon
completion of the action, the counts are manually updated with the count
of messages in the action and recent and/or unseen states of those
messages. This is more efficient for maildir, because we aren't counting
everything in the store. For IMAP, we get the updates for free because
we are only performing the update after confirmation from the server
that the action has happened.
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
The countRUE function was inaccurately counting flags. If a message was
unread and recent, it was only counted as recent. The two flags are not
mutually exclusive. A previous count for a mailbox with 1 recent, 1
unread, and 5 existing would be :
1/0/5
An accurate count of this state would be:
1/1/5
This patch fixes the count.
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Check for new mail (recent, unseen, exists counts) with an external
command, or for imap with the STATUS command, at start or on
reconnection and every X time duration
IMAP:
The selected folder is skipped, per specification. Additional config
options are included for including/excluding folders explicitly.
Maildir/Notmuch:
An external command will be run in the background to check for new mail.
An optional timeout can be used with maildir/notmuch. Default is 10s
New account options:
check-mail
check-mail-cmd (maildir/notmuch only)
check-mail-timeout (maildir/notmuch only), default 10s
check-mail-include (IMAP only)
check-mail-exclude (IMAP only)
If unset, or set less than or equal to 0, check-mail will be ignored
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Tested-by: Moritz Poldrack <moritz@poldrack.dev>
Acked-by: Robin Jarry <robin@jarry.cc>
Provide a generic selector dialog popup where the user can select from
different options.
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Check bounds before drawing a dialog window to avoid a panic when
resizing the terminal window.
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Append text parts to emails in the composer as multipart/alternative.
Display the mime-type of the parts in the review window.
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Aerc was sending empty address list header fields (specifically CC by
default). This was causing DKIM failures in lists.sr.ht. RFC 5322 states
that an address field should consist of the field name and one or more
addresses, implying empty fields are not allowed.
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Commit 1bac87e804 ("terminal: fix race when closing a terminal") fixed
a race in Terminal.Draw by using a mutex. The current locking of the
entire Draw function could create a deadlock, however, since this
function itself might call Terminal.Close which is protected by the same
mutex. A finer-grained locking solves both the race and deadlock
problem.
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Fix panic when resizing the terminal by dynamically adjusting the width
of the option selector. The selector does not check the width of the
terminal before printing. This can lead to a panic in the account wizard
when reducing the terminal width.
If the terminal width is not large enough, the space between the options
is reduced. If this is still not enough, then the selector will only
show the focused option and arrows indicating the alternatives.
Fixes: https://todo.sr.ht/~rjarry/aerc/41
Reported-by: Omar Polo <op@omarpolo.com>
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Add compose command ("attach-key") to attach the public key associated
with the sending account. Public key is attached in ascii armor format,
with the mimetype set according to RFC 3156 ("application/pgp-keys").
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Tested-by: Koni Marti <koni.marti@gmail.com>
Add check for public keys of all message recipients (to, cc, and bcc)
before sending the message. Adds an OnFocusLost callback to header
editors to facilitate a callback for checking keys whenever a new
recipient is added (OnChange results in too many keyring checks).
Once encryption is initially set, the callbacks are registered. If a
public key is not available for any recipient, encryption is turned off.
However, notably, the callbacks are still registered meaning as s soon
as the user removes the recipients with missing keys, encryption is
turned back on.
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Tested-by: Koni Marti <koni.marti@gmail.com>