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>
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>
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>
In order to better align to vim functionality: deselect visual mode
selections after performing a command on the selection. This patch also
introduces a new command to allow for re-selecting (remarking) the
previous selection set so that commands can be chained together. The
deselection only applies to msg commands that *do not* move the message
from the store (those types of commands already deselect):
- read/unread
- flag/unflag
- modify-labels
- copy
- pipe
Previous usage to mark several messages as read and deselect all:
Vjjj:read<Enter>:unmark -a<Enter>
New usage, similar to vim:
Vjjj:read<Enter>
To chain a command together:
Vjjj:read<Enter>:remark<Enter>{next command}<Enter>
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Provide a choice to the user with the selector dialog to select the
desired unsubscribe method. Before, the first method that appeared in
the list-unsubscribe header was used.
For the http method, the user can now also confirm whether he wants to
open the provided link in the browser or not.
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Reply to iCalendar invitations with three commands: :accept,
:accept-tentative or :decline. Parse a text/calendar request, create a
reply and append it to the composer.
Suggested-by: Ondřej Synáček <ondrej@synacek.org>
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Add :help completion arguments (config, imap, etc). The option "aerc"
brings up the general manpage
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Koni Marti <koni.marti@gmail.com>
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>
Check that the signing key exists when the user issues the :sign
command. The signing key ID will be displayed in the security status
also, allowing the user to see what key will be used to sign the
message.
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Tested-by: Jens Grassel <jens@wegtam.com>
Commit bc593ac7cd ("recall: allow recalling messages from any folder")
added the possibility to recall any message by providing the -f flag.
Mention the flag in the error message.
Signed-off-by: inwit <inwit@sindominio.net>
Acked-by: Robin Jarry <robin@jarry.cc>
This commit refactors the internal PGP implementation to make way for
GPG integration.
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Clear filter when called with no arguments.
Fixes: https://todo.sr.ht/~rjarry/aerc/35
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Keep current message selected when clearing or changing filters and when
toggling threads.
Add -s flag to the clear command to also clear the selected message and
set cursor to the top of the message list.
Implements: https://todo.sr.ht/~rjarry/aerc/36
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Allow using the command ':forward -A' without specifying an email
address inline.
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
This commit fixes an out-of-bound error that happened while parsing
commands.
Signed-off-by: Moritz Poldrack <git@moritz.sh>
Acked-by: Robin Jarry <robin@jarry.cc>
With this commit trailing colons in the :header command's field are
removed to prevent double-colon-headers from being sent.
Signed-off-by: Moritz Poldrack <git@moritz.sh>
Acked-by: Robin Jarry <robin@jarry.cc>
By using :compose -H <header> a user should be able to add
arbitrary headers to an email. The existing implementation from
5b523880b4 added the headers as lines
to the beginning of the body. These lines were not interpreted as
headers anywhere and ended up as plain text in the body of the email.
Fix the code to parse and add the headers correctly.
Signed-off-by: Evan Gates <evan.gates@gmail.com>
Tested-by: Moritz Poldrack <moritz@poldrack.dev>
Ignore option flags and prepend default-save-path if the current path is
not absolute.
Signed-off-by: Robin Jarry <robin@jarry.cc>
Reviewed-by: Moritz Poldrack <moritz@poldrack.dev>
Keep the sort criteria applied to the selected folder until the default
sort order should be restored. Call the sort command without arguments
to restore the default sort order.
The current behavior is that the default sort order is restored as soon
as the folder reloads. This happens often and then the results of the
sort command are lost. This makes the sort command not very
user-friendly. Instead, we should keep the sort criteria applied until
the user explicitly wants to restore the default sort order again.
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Allow saving all message parts that have the content disposition
"attachment" header to a folder.
Suggested-by: Ondřej Synáček <ondrej@synacek.org>
Signed-off-by: Robin Jarry <robin@jarry.cc>
Acked-by: Koni Marti <koni.marti@gmail.com>
Tested-by: Moritz Poldrack <moritz@poldrack.dev>
Since panics still regularly "destroy" the terminal, it is hard to get a
stack trace for panics you do not anticipate. This commit adds a panic
handler that automatically creates a logfile inside the current working
directory.
It has to be added to every goroutine that is started and will repair
the terminal on a panic.
Signed-off-by: Moritz Poldrack <git@moritz.sh>
Acked-by: Robin Jarry <robin@jarry.cc>
Make statusline folder-specific. Update filter, search and threading
status when changing folders.
Commit 2512c04 ("statusline: implement per-account status") introduced
an account-specific statusline. This makes it account- and
folder-specific.
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Tested-by: Moritz Poldrack <moritz@poldrack.dev>
Focusing header editors was hardcoded as integers which only worked with
the default ui. If a user changed the UI to, for example, put CC as a
field below "to", FocusSubject would focus the CC field instead of the
subject. This commit reuses and modifies the function FocusEditor to
generalize the focusing of header editors - which can now be called by
name via FocusEditor(name string)
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Implement a statusline state for each account. Keep the ex line and the
push notifications global. Add account name prefix to push
notifications. Prefix status line with account name when multiple
accounts are available.
Use account-specific status line for each tab where an account is
defined.
Handle threading, filter/search, viewer passthrough and connection
status.
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Remove code duplication and provide completion even when acct is nil
Signed-off-by: kt programs <ktprograms@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Fix panic in the GetCompletions function when using the keybind for the
terminal command.
Fixes: https://todo.sr.ht/~rjarry/aerc/29
Reported-by: inwit <inwit@sindominio.net>
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
When trying to search in less, keys bound to viewer functions can't be
used as part of the search query, which makes the search useless.
Add a view::passthrough binding mode and a :toggle-key-passthrough
command go toggle in and out of that mode. By default, typing '/' in the
viewer is bound to enabling key passthrough and automatically inserting
'/', to easily enter "less" search mode. When in the passthrough mode,
all bindings are ignored by default. The default binds.conf only defines
a single keybinding in that mode: <Esc> to get back out. $ex is bound to
<C-x> to allow typing colons.
Signed-off-by: Kt Programs <ktprograms@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Change the option to enable fuzzy completion to be fuzzy-complete, since
it's no longer only used for folders
Signed-off-by: Kt Programs <ktprograms@gmail.com>
Acked-by: Koni Marti <koni.marti@gmail.com>
Some MUAs (namely Outlook) use localized prefixes for replied-to and
forwarded mail. With this patch aerc replaces known localized prefixes
and repetitions with the common Re: prefix.
Link: https://office-watch.com/2014/outlook-reply-forward-prefixes/
Signed-off-by: Moritz Poldrack <git@moritz.sh>
Acked-by: Robin Jarry <robin@jarry.cc>
When messages are marked, pipe their contents into the specified
command. The messages are ordered according to their respective
Message-Id headers. This allows applying complete patch series with
a single command.
When piping more than one message, make sure to write them in the mbox
format as git am expects them to be.
Link: https://en.wikipedia.org/wiki/Mbox
Link: https://github.com/git/git/blob/v2.35.1/builtin/mailsplit.c#L15-L44
Signed-off-by: Robin Jarry <robin@jarry.cc>
Reviewed-by: Koni Marti <koni.marti@gmail.com>
Tested-by: akspecs <akspecs@gmail.com>
aerc.SelectedAccount() is used in lots of places. Most of them without
checking the return value.
In some cases, the currently selected tab is not related to any account
(widget.Terminal for example). This can lead to unexpected crashes when
accessing account specific configuration.
When possible, return an error when no account is currently selected.
If no error can be returned, fallback to non-account specific
configuration.
Signed-off-by: Robin Jarry <robin@jarry.cc>
Reviewed-by: Koni Marti <koni.marti@gmail.com>
implement message threading on the message store level using the
jwz algorithm. Build threads on-the-fly when new message headers arrive.
Use the references header to create the threads and the in-reply-to
header as a fall-back option in case no references header is present.
Does not run when the worker provides its own threading (e.g. imap
server threads).
Include only those message headers that have been fetched and are
stored in the message store.
References: https://www.jwz.org/doc/threading.html
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Tested-by: Inwit <inwit@sindominio.net>
Tested-by: akspecs <akspecs@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
add the expand-folder and collapse-folder commands to navigate the
directory tree view. Provide keybinds for a vi-like folder navigation
experience.
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Add an extra attribute to the status line. When non-empty, display it
after the current status.
Set that extra status after a successful :search or :filter. Remove it
after :clear.
Signed-off-by: Robin Jarry <robin@jarry.cc>
The status is not cleared. It is annoying.
Fixes: c37f1eaaea ("filter/search: display current search/filter arguments")
Signed-off-by: Robin Jarry <robin@jarry.cc>
Make the statusbar message after search and filter completion more
informative by showing the full call that was used.
Signed-off-by: inwit <inwit@sindominio.net>
Fix the parsing of internationalized headers (RFC 6532). Enable
unsubscribe to work with regular and encoded headers.
Signed-off-by: Koni Marti <koni.marti@gmail.com>
re-opens the review UI when the postpone operation fails. Before, the
composer would close, even on error, and we would lose the email draft.
Now, the user can decide on how to proceed when postponing fails.
References: https://lists.sr.ht/~rjarry/aerc-devel/patches/28824
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Introduce an option in aerc.conf to disable the auto-including
of your own address when replying to your own emails (address
replies to the original To: and Cc: instead); default to true
(allow the auto-including)
implements a recover command that searches the local temp dir for aerc
emails. If a file is found and selected, a new composer tab will open
with the file contents as the message body. No header data is stored in
the temp file and thus this information cannot be recovered.
Recover will not remove the temporary file unless the force flag (-f) is
explicitly used.
This recovery method only works when the editor buffer is saved to
disk and the Close() function of the composer has not been called yet.
Sending, postponing or quitting will call the Close() function which
removes the temporary file completely. After Close() is called, no
recovery is possible anymore.
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Unless a template is specified with reply -T, use the new-message
template for non-quoted replies.
Fixes: 877a94f5d9 ("compose: add default template for new messages")
Signed-off-by: Robin Jarry <robin@jarry.cc>
fetches missing headers when in visual selection mode. This prevents
large archive operations from panicking due to a nil pointer
dereference.
The archive command will return an error to the ui when a nil message is
encountered to signal that the message store is not ready yet.
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Allow defining a default template to use when composing new messages.
Add an example to be used for new users.
Signed-off-by: Robin Jarry <robin@jarry.cc>
implements PGP/MIME encryption with go-pgpmail. The Encrypt() function of
go-pgpmail requires a list of public keys which are taken from the
keystore. The keystore is searched for the email addresses of all
recipients (to, cc, and bcc).
If you want to be able to read the encrypted email afterwards, add
yourself as a recipient in either to, cc, or bcc as well.
Public keys can be exported from gpg into aerc as follows:
$ gpg --export >> ~/.local/share/aerc/keyring.asc
When composing a message, the encryption is enabled with the
":encrypt" command. This sets a bool flag in the Composer struct.
A reapted application of this command will toggle the flag.
The encrypted message can also be signed by using the ":sign"
command before or after ":encrypt".
References: https://todo.sr.ht/~rjarry/aerc/6
Signed-off-by: Koni Marti <koni.marti@gmail.com>
implements PGP/MIME signing with go-pgpmail. The Sign() function of
go-pgpmail requires a private (signing) key. The signing key which matches
the senders email address (from field in email header) is looked up
in aerc's copy of the keyring.
Private keys can be exported from gpg into aerc as follows:
$ gpg --export-secret-keys >> ~/.local/share/aerc/keyring.asc
A message is signed with the ":sign" command. The sign command sets
a bool flag in the Composer struct. Using the command repeatedly will
toggle the flag.
References: https://todo.sr.ht/~rjarry/aerc/6
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Recall fails when called outside of the "postpone" folder (usually
"Drafts"). This makes sense for postponed messages. However, sometimes
the user would like to re-edit and re-send an old, possibly sent,
message, which would serve as a basis for the new one.
This patch allows recall to work outside the postpone folder, thus
allowing for re-edition of any message.
In the original recall function, if the recalled message is found in the
"postpone" folder, once the message has been recalled, re-edited and
sent, the original draft is deleted. With this patch, when the message
is not in the "postpone" folder, the original message is not deleted.
Signed-off-by: inwit <inwit@sindominio.net>
* Get rid of open_darwin
It just lead to code duplication for a simple one string change.
Instead we query it during initialization
* Accept user provided arguments
"open" on MacOS accepts things like -A to use a specific application
Pass trough arguments the user provided in order to facilitate this
* Refactor the function to a struct
This makes it more convenient for the caller and avoids signatures like
lib.OpenFile(nil, u.String(), nil) which are fairly unreadable
Also update to the tcell v2 PaletteColor api, which should keep the chosen
theme of the user intact.
Note, that if $TRUECOLOR is defined and a truecolor given, aerc will now stop
clipping the value to one of the theme colors.
Generally this is desired behaviour though.
Prior to this commit, the composer was based on a map[string]string.
While this approach was very versatile, it lead to a constant encoding / decoding
of addresses and other headers.
This commit switches to a different model, where the composer is based on a header.
Commands which want to interact with it can simply set some defaults they would
like to have. Users can overwrite them however they like.
In order to get access to the functions generating / getting the msgid go-message
was upgraded.
We made a new type out of go-message/mail.Address without any real reason.
This suddenly made it necessary to convert from one to the other without actually
having any benefit whatsoever.
This commit gets rid of the additional type
Aerc just sent the true / false update regardless, meaning if someone already
replied to a mail, then drafted yet another mail to the same parent the flag
would vanish. This commit fixes this behaviour.
This change handles message parse errors by printing the error when the
user tries to view the message. Specifically only handling unknown
charset errors in this patch, but there are many types of invalid
messages that can be handled in this way.
aerc currently leaves certain messages in the msglist in the pending
(spinner) state, and I'm unable to view or modify the message. aerc also
only prints parse errors with message when they are initially loaded.
This UX is a little better, because you can still see the header info
about the message, and if you try to view it, you will see the specific
error.
This allows us to hook into the std libs implementation of parsing related stuff.
For this, we need to get rid of the distinction between a mailbox and a host
to just a single "address" field.
However this is already the common case. All but one users immediately
concatenated the mbox/domain to a single address.
So this in effects makes it simpler for most cases and we simply do the
transformation in the special case.
The `:rmdir` command removes the current directory (`-f` is required if
the directory is not empty).
This is not supported on the notmuch backend.
An issue with the maildir backend is that some sync programs (e.g.
offlineimap) may recover the directory after it is deleted. They need
to specifically be configured to accept deletions, or special commands
need to be executed (e.g. `offlineimap --delete-folder`) to properly
delete folders.
A danger of using this on the IMAP backend is that it is possible for a
new message to be added to the directory and for aerc to not show it
immediately (due to a slow connection) - using `:rmdir` at this moment
(with `-f` if the directory already contains messages) would delete the
directory and the new message that just arrived (and all other
contents). This is documented in aerc(1) so that users are aware of
possible risks.
This piggybacks on the existing IMAP support, and uses the same
configuration format (my local testing example has the IMAP and SMTP
lines almost copy-pasted from one another).
It's a little clumsy in that a new token is negotiated for every
`Send()` command, but it's a start...
Introduce the ability to configure stylesets, allowing customization of
aerc's look (color scheme, font weight, etc). Default styleset is
installed to /path/to/aerc/stylesets/default.
Introduce the ability to configure stylesets, allowing customization of
aerc's look (color scheme, font weight, etc). Default styleset is
installed to /path/to/aerc/stylesets/default.
Aerc usually used the path []int{1} if it didn't know what the proper path is.
However this only works for multipart messages and breaks if it isn't one.
This patch removes all the hard coding and extracts the necessary helpers to lib.
More mail flags can now be set, unset, and toggled, not just the
read/seen flag.
This functionality is implemented with a new `:flag` and `:unflag`
command, which are extensions to the matching `:read` and `:unread`
commands, adding support for different flags. In fact, the
`read`/`unread` commands are now recognized aliases to `flag`/`unflag`.
The new commands are also well documented in aerc(1).
The change mostly extends the previous read/unread setting functionality
by adding a selection for the flag to change.
This stops the ui being blocked while the resource is opened. The wait
ensures that resources are reclaimed when the process finishes while
aerc is still running.
The data was passed around as a string for some reason, which led to time
precision loss and wrong dates being displayed.
Simply pass the time as is to fix that.
This changes the scrolling to be done on the draw, when the height is
updated, ensuring that the selected item is kept on screen during
resizing.
Also, this ensures that messages will fill the screen when resizing the
window, for instance, shrinking and then growing drags down more
messages if possible.
This is a transplant of the dirlist scrolling logic.
The grid used static sizes which meant that changing settings didn't
have an effect on elements of the ui, notably the sidebar width. This
patch makes the `Size` parameter of a cell a function which returns the
`int`, allowing for dynamic sizes.
A `Const` function is also included for ease of use for static sizes.
The following functionalities are added to configure aerc ui styles.
- Read stylesets from file with very basic fnmatch wildcard matching
- Add default styleset
- Support different stylesets as part of UiConfig allowing contextual
styles.
- Move widgets/ui elements to use the stylesets.
- Add configuration manual for the styleset