contributing: cleanup

Remove outdated information. Add wiki specific instructions.

Signed-off-by: Robin Jarry <robin@jarry.cc>
doc: fix invalid markup

Extraneous underscore slipped in.

Fixes: 3d99fae3d224 ("term: add config options for TERM and osc8")
Signed-off-by: Robin Jarry <robin@jarry.cc>
doc: mention regex for the bindings definition

Document the possibility of using regex when defining bindings for specific
accounts or folders.

Signed-off-by: inwit <inwit@sindominio.net>
Acked-by: Moritz Poldrack <moritz@poldrack.dev>
lib: don't set seen flag upon error

Don't set the Seen flag when an error occurs during opening the message.

Fixes: https://todo.sr.ht/~rjarry/aerc/125
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Tested-by: Moritz Poldrack <moritz@poldrack.dev>
Acked-by: Robin Jarry <robin@jarry.cc>
dirstore: list the folders in arrival order

List the folders in arrival order when dirstore.List() is called instead
of returning it in an arbitrary order.

If enable-folders-sort=false and dirlist-tree=false, the directory list
will arbitrarly reshuffle when changing directories because the
dirlist.dirs are generated from keys in a map in the dirstore.

Fixes: https://todo.sr.ht/~rjarry/aerc/178
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
statusline: fix typo in deprecation warning

This was a bad copy paste from config/ui.go.

Fixes: d2e74cdb91e1 ("statusline: add column based render format")
Signed-off-by: Vlad-Stefan Harbuz <vlad@vladh.net>
Acked-by: Robin Jarry <robin@jarry.cc>
maildirpp: fix path separator

Fix path separator for the maildir++ backend. Maildir++ already
substitutes '.' for os.PathSeparator. Returning '.' will thus break the
directory tree and the other logic for this backend.

Fixes: 2040fc18 ("imap: use delimiter from server")
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
ui: fix deadlocks in message channel

There are several ways the ui message channel can fill up leading to

1) Invalidate() changes the value of uiState to DIRTY. The following
   call sequence:


   Leads to multiple nil messages being queued in the message channel
   whereas one could assume that the second QueueRedraw() would do
   nothing. This is caused by the tri-state nature of uiState.

2) We use the same channel to convey state change, keyboard events and
   redraw requests. Since a keyboard event almost always triggers
   a redraw, we end up trying to append a redraw message in the same
   goroutine that reads from the channel. This triggers a deadlock when
   there are more than 50 pending messages.

Solve the issue by using multiple channels, one per type of message that
needs to be sent to the main ui thread.

Remove QueueRedraw() and merge its functionality in Invalidate(). Only
use a DIRTY/CLEAN state to determine if something needs to be queued in
the redraw channel.

Use a channel for quitting instead of an atomic. Restructure some code
functions to have a cleaner API.

Use a for loop in the main thread and select from all channels.

Signed-off-by: Robin Jarry <robin@jarry.cc>
Tested-by: Koni Marti <koni.marti@gmail.com>
Tested-by: Maarten van Gompel <proycon@anaproy.nl>
templates: add boolean flags

Allow accessing email flags via boolean properties instead of having to
rely on obscure regular expressions on (.Flags | join ""). With this
patch, it is now possible to do this:

index-columns = star:1,name<15%,reply:1,subject,size>=,date>=
column-star = {{if .IsFlagged}}★{{end}}
column-name = {{if eq .Role "sent"}}{{.To | names | join ", "}}{{else}}{{.From | names | join ", "}}{{end}}
column-reply = {{if .IsReplied}}{{end}}
column-subject = {{.ThreadPrefix}}{{.Subject}}
column-size = {{if .HasAttachment}}📎 {{end}}{{humanReadable .Size}}
column-date = {{.DateAutoFormat .Date.Local}}

Signed-off-by: Robin Jarry <robin@jarry.cc>
Acked-by: Koni Marti <koni.marti@gmail.com>
templates: use template interface consistently

Use the template interface consistently. Before, we have exported the
state.TemplateData struct and used it in most places instead of the
models.TemplateData interface. This lead to some inconsistencies, i.e.
Role() has been defined on the exported struct but not on the interface.

Unexport the state.TemplateData struct, add a DataSetter interface to
set the data needed for the template data and call the Data() method
which returns a models.TemplateData interface when the template data is

Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Tim Culverhouse <tim@timculverhouse.com>
headers: enable partial header fetching

Enable partial header fetching by creating config values for headers to
specifically include, or specifically exclude. The References field will
always be fetched, regardless of the include list. Envelope data is
always fetched, but is not shown with :toggle-headers, since it isn't in
the RFC822 struct unless explicitly included in the list.

Partial headers can break the cache on changes. Update the cache tag key
to include the state of the partially-fetched headers.

Partial header fetching can have a significant performance increase for
IMAP, and for all backends a resource improvement. Some data to support
this is below. Gathered by opening aerc, selecting a mailbox with
approximately 800 messages and scrolling to the end.

Received measured with nethogs, RAM from btop

		   Received  |   RAM
All Headers	|   9,656 kb | 103 MB
Minimum Headers	|     896 kb |  36 MB

Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Moritz Poldrack <moritz@poldrack.dev>
Acked-by: Robin Jarry <robin@jarry.cc>
dirtree: fixup to apply correct patchset version

I had applied v2 instead of v4... It is time to automate these things
a bit better.

Fixes: 6e038c7fd510 ("dirtree: modify drawing of the dirtree")
Signed-off-by: Robin Jarry <robin@jarry.cc>
imap: handle the NonExistent attribute

Treat the "\NonExistent" attribute similar to the "\NoSelect" one. Only
list folders without the "\NonExistent" or "\NoSelect" attribute.

According to RFC 9501, section 7.3.1, the "\NonExistent" attribute
implies "\NoSelect".

When using the LIST-STATUS extension, some servers return a
"\NonExistent" flag instead of the "\NoSelect" one. We only check for
the "\NoSelect" attribute, and hence, a "\NonExistent" folder will
appear in the directory list and raise an error when being selected.

This occurs, e.g., for gmail accounts with the "[Gmail]" folder.

Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
dirtree: clear msglist for virtual nodes

Clear the message list when a virtual node is selected. Add a
VirtualNodeCallback to the Dirlist interface.

Reported-by: Tim Culverhouse <tim@timculverhouse.com>
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
da1f014b — Moritz Poldrack 20 days ago
config: update default pager

Since aercs embedded terminal now behaves correctly, a messages contents
are at the bottom of the pager by default, this has already sparked
confusion as this is uncommon and not matching previous behaviour.

Thanks: Stacy Harper <contact@stacyharper.net>
Suggested-by: Tim Culverhouse <tim@timculverhouse.com>
Signed-off-by: Moritz Poldrack <git@moritz.sh>
Acked-by: Robin Jarry <robin@jarry.cc>
d22f2bf4 — Moritz Poldrack 21 days ago
mkdir: add completion

In order to combat potential issues of not knowing ones servers
delimiter when creating directories, the delimiter is automatically
appended to all suggested matches.

Signed-off-by: Moritz Poldrack <git@moritz.sh>
Acked-by: Robin Jarry <robin@jarry.cc>
ecfb22ad — Moritz Poldrack 21 days ago
archive: respect delimiter

Since we now have support for using a server's custom delimiter, it's
only right to also make use of this circumstance in the :archive

Use the provided delimiter to join the path elements in the :archive

Signed-off-by: Moritz Poldrack <git@moritz.sh>
Acked-by: Robin Jarry <robin@jarry.cc>
2040fc18 — Moritz Poldrack 21 days ago
imap: use delimiter from server

To accommodate servers that use a delimiter other than "/" ("." being a
common alternative), the delimiter is fetched from the server when

Signed-off-by: Moritz Poldrack <git@moritz.sh>
Acked-by: Robin Jarry <robin@jarry.cc>
compose: warn before sending with empty subject

Ask user whether they want to abort before sending if the subject header
is empty and they have enabled the warn-empty-subject config option.

Signed-off-by: Jason Cox <me@jasoncarloscox.com>
Acked-by: Tim Culverhouse <tim@timculverhouse.com>
colorize: style chunk function name

It's nice to use a different style for the chunk's function name to make
it clear that the name is not necessarily adjacent to the chunk's actual

Signed-off-by: Jason Cox <me@jasoncarloscox.com>
Acked-by: Robin Jarry <robin@jarry.cc>