38 Commits

Author SHA1 Message Date
Robin Jarry
0211c9bf23 reload: fix crash when reloading via IPC
When reloading the configuration with :reload, global variables in the
config package are reset to their startup values and then, the config is
parsed from disk. While the parsing is done, these variables are
temporarily in an inconsistent and possibly invalid state.

When commands are executed interactively from aerc, they are handled by
the main goroutine which also deals with UI rendering. No UI render will
be done while :reload is in progress.

However, the IPC socket handler runs in an independent goroutine. This
has the unfortunate side effect to let the UI goroutine to run while
config parsing is in progress and causes crashes:

[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x6bb142]

goroutine 1 [running]:
git.sr.ht/~rjarry/aerc/lib/log.PanicHandler()
	lib/log/panic-logger.go:51 +0x6cf
panic({0xc1d960?, 0x134a6e0?})
	/usr/lib/go/src/runtime/panic.go:783 +0x132
git.sr.ht/~rjarry/aerc/config.(*StyleConf).getStyle(0xc00038b908?, 0x4206b7?)
	config/style.go:386 +0x42
git.sr.ht/~rjarry/aerc/config.StyleSet.Get({0x0, 0x0, 0x0, {0x0, 0x0, 0x0}}, 0x421a65?, 0x0)
	config/style.go:408 +0x8b
git.sr.ht/~rjarry/aerc/config.(*UIConfig).GetStyle(...)
	config/ui.go:379
git.sr.ht/~rjarry/aerc/lib/ui.(*TabStrip).Draw(0xc000314700, 0xc000192230)
	lib/ui/tab.go:378 +0x15b
git.sr.ht/~rjarry/aerc/lib/ui.(*Grid).Draw(0xc000186fc0, 0xc0002c25f0)
	lib/ui/grid.go:126 +0x28e
git.sr.ht/~rjarry/aerc/app.(*Aerc).Draw(0x14b9f00, 0xc0002c25f0)
	app/aerc.go:192 +0x1fe
git.sr.ht/~rjarry/aerc/lib/ui.Render()
	lib/ui/ui.go:155 +0x16b
main.main()
	main.go:310 +0x997

Make the reload operation safe by changing how config objects are
exposed and updated. Change all objects to be atomic pointers. Expose
public functions to access their value atomically. Only update their
value after a complete and successful config parse. This way the UI
thread will always have access to a valid configuration.

NB: The account configuration is not included in this change since it
cannot be reloaded.

Fixes: https://todo.sr.ht/~rjarry/aerc/319
Reported-by: Anachron <gith@cron.world>
Signed-off-by: Robin Jarry <robin@jarry.cc>
2025-09-08 12:19:51 +02:00
Karel Balej
5919e9dfda term: allow setting custom title for the terminal tab
Add a template for the terminal tab title and define two
terminal-specific properties: Title which expands to whatever the
underlying application requests via OSC and defaults to the command name
and Bell which is a boolean indicating whether the application has
emitted bell, the flag is cleared when the corresponding tab gains focus
and is not set at all if it currently has it.

This can among other things be used to highlight the terminal tab when
the underlying process prints the bell, such as by setting the template
as such:

	tab-title-terminal={{if .Bell}}[BELL] {{end}}{{.Title}}

Implements: https://todo.sr.ht/~rjarry/aerc/138
Changelog-added: A tab-title-terminal setting for customizing the
 title of tabs in which the terminal widget is run.
Requested-by: Drew DeVault <drew@ddevault.org>
Signed-off-by: Karel Balej <balejk@matfyz.cz>
Acked-by: Robin Jarry <robin@jarry.cc>
2025-05-05 13:49:04 +02:00
Karel Balej
f0ec95d7dd account: allow indicating new messages in the tab title
Add a flag to indicate whether the account has received new messages
since it last had focus and allow its use in the templates.

Changelog-added: A `.HasNew` flag indicating whether the account has
 received new messages to be used in the templates.
Signed-off-by: Karel Balej <balejk@matfyz.cz>
Tested-by: Inwit <inwit@sindominio.net>
Acked-by: Robin Jarry <robin@jarry.cc>
2025-04-07 10:51:14 +02:00
Moritz Poldrack
c460e0e6f1 template: fix mailto on startup failing to open
During startup, d.account and d.folder are not set and thus not
lead to a segmentation fault when running a signature command.

Only set these values if they are available.

Fixes: da5ca1a5 ("template: pass account and folder names to signature command")
Changelog-fixed: Fix an error when starting aerc through a `mailto:`
 link when the `new_message` template runs a signature command.
Signed-off-by: Moritz Poldrack <git@moritz.sh>
Acked-by: Robin Jarry <robin@jarry.cc>
2025-03-19 00:35:48 +01:00
inwit
930cece51d templates: add a template for forwaded messages
Add a {{.IsForwarded}} template to tell if a message has been forwarded
or not.

Changelog-added: Forwarded messages can be identified with the
 {{.IsForwarded}} template.
Signed-off-by: inwit <inwit@sindominio.net>
Acked-by: Robin Jarry <robin@jarry.cc>
2024-08-20 11:54:34 +02:00
Tristan Partin
a2cf34e2b4 log: explain why the signature command failed
It wasn't previously apparent why the command failed.

Signed-off-by: Tristan Partin <tristan@partin.io>
Acked-by: Robin Jarry <robin@jarry.cc>
2024-08-20 09:30:13 +02:00
Tristan Partin
da5ca1a530 template: pass account and folder names to signature command
This can help to dynamically determine what signature you want.

Changelog-added: `AERC_ACCOUNT` and `AERC_FOLDER` are now available
 in the signature command environment.
Signed-off-by: Tristan Partin <tristan@partin.io>
Acked-by: Robin Jarry <robin@jarry.cc>
2024-08-20 09:29:33 +02:00
Bence Ferdinandy
1d4eafb011 templates: add {{.AccountFrom}} template
Add template variable to access the current account's From address.

Implements: https://todo.sr.ht/~rjarry/aerc/150
Changelog-added: New `{{.AccountFrom}}` template variable.
Signed-off-by: Bence Ferdinandy <bence@ferdinandy.com>
Tested-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2024-08-03 17:42:11 +02:00
Koni Marti
7f66297c52 threadbuilder: show siblings even when no parent found
Show all threading associations even when not all nodes are present.
Indicate if a thread is incomplete, i.e. misses a direct parent node.

Use the `msglist_thread_orphan.fg=red` styleobject in your stylesheet to
indicate whether a messsage has a missing parent.

Also use a different thread prefix ("┬─" instead of "├─") not to confuse
them with regular threads that have a visible parent.

Signed-off-by: Koni Marti <koni.marti@gmail.com>
Signed-off-by: Robin Jarry <robin@jarry.cc>
Tested-by: Matěj Cepl <mcepl@cepl.eu>
2024-06-25 15:28:11 +02:00
Bence Ferdinandy
47c2266872 templates: add .AccountBackend
It's useful to know what the current account's backend is, especially if
one has multiple configs where the same account name might use
a different backend. Add AccountBackend to templates.

Changelog-added: Added `{{.AccountBackend}}` to templates.
Signed-off-by: Bence Ferdinandy <bence@ferdinandy.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2024-06-05 08:41:13 +02:00
Jason Cox
6a84f1331f templates: add visual mode indicator to TrayInfo
It's useful to have some indicator of whether or not aerc is in visual
mark mode. Add such an indicator to the TrayInfo available in the status
line.

Changelog-changed: The `TrayInfo` template variable now includes a
 visual mark mode indicator.
Signed-off-by: Jason Cox <me@jasoncarloscox.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2024-03-04 22:33:15 +01:00
Robin Jarry
8edf7b0e4d log: move package to lib
This has nothing to do at the root of the source tree.

Signed-off-by: Robin Jarry <robin@jarry.cc>
Acked-by: Bence Ferdinandy <bence@ferdinandy.com>
2024-02-14 23:04:38 +01:00
Tim Culverhouse
6314e2dc67 vaxis: update to v0.7.2 and update ansi parser
Update Vaxis to v0.7.2 to gain performance improvements and StyledString
parsing. The Vaxis parser fully accounts for the terminal's capability
to display wide characters.

Use the Vaxis StyledString parser to parse and style ansi-encoded
strings. Remove unneeded code and tests.

Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2024-02-12 13:49:14 +01:00
Jason Cox
11b035f120 flags: add support for draft flag
Support the draft flag wherever flags are used. Automatically set it
when postponing a message, and allow recalling a message without the -f
flag if it has the draft flag set, regardless of what folder it's in.

Notmuch doesn't seem to pick up on the draft flag when indexing even
though the flag is set on the maildir file. Explicitly set all tags
corresponding to set flags when appending a message in notmuch.

Changelog-added: Support the `draft` flag.
Signed-off-by: Jason Cox <me@jasoncarloscox.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2024-01-26 21:36:15 +01:00
Bence Ferdinandy
b76bf1b7ee templates: move signature from compose to templates
Currently, when composing a new message, everything is read from the
template files, except the signature, which is added directly in the
compose code. Add a new template variable {{.Signature}}, by moving the
logic of reading signature from command or file from compose to
templates. Update the various default template files to preserve the
original placement of signatures. Users using the default templates
should not notice the change. Users with custom compose templates will
need to update their templates with {{.Signature}}.

Changelog-changed: Signature placement is now controlled via the
 `{{.Signature}}` template variable and not hardcoded.
Signed-off-by: Bence Ferdinandy <bence@ferdinandy.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2024-01-08 00:02:21 +01:00
Bence Ferdinandy
930e50328c templates: add full path of file(s) as Filename(s)
For the maildir and notmuch backends, add the full path of the message
as Filename to templates. In case of a notmuch message having multiple
files associated with it, it returns a random path. Also add Filenames
to templates, which is a list of all associated message paths. This is
relevant for the notmuch backend, where a single messages is shown, if
there are multiple copies of it.

Changelog-added: Add filepath to messages in templates as .Filename(s)
Signed-off-by: Bence Ferdinandy <bence@ferdinandy.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2023-12-31 11:56:48 +01:00
Bence Ferdinandy
8ee61777ad templates: display "(no subject)" when subject is empty
An empty subject, especially in a thread makes it for a slightly jarring
layout. Add a new option empty-subject option to UI with "(no subject")
as the default value. If the subject is empty and the current message is
not the same subject as it's parent in a thread make {{.Subject}}
evaluate to this option's value.

Changelog-added: The `{{.Subject}}` template is evaluated to the new
 option `[ui].empty-subject` if the subject is empty.
Signed-off-by: Bence Ferdinandy <bence@ferdinandy.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2023-11-24 22:45:03 +01:00
inwit
c13df79976 threads: add .ThreadUnread to template data
When a thread is folded, it can be useful to know how many unseen
messages lie below the root. For example, one might want to show that
count in the message list:

column-folded = {{if .ThreadFolded \
	}}{{if ne .ThreadUnread 0 \
		}}{{.ThreadUnread | printf "%s/"}}{{ \
	end}}{{ .ThreadCount | printf "%s"}}{{end}}

Add `.ThreadUnread` to the template functions.

Changelog-added: `.ThreadUnread` is now available in templates.
Signed-off-by: inwit <inwit@sindominio.net>
Acked-by: Robin Jarry <robin@jarry.cc>
2023-11-12 12:53:11 +01:00
Jason Cox
863e124e84 accounts: allow fnmatch-style wildcards in aliases
Wildcard aliases make it possible to always reply from the same address
to which a message was addressed, which is useful for catch-all email
domains. Support fnmatch-style wildcards in only the address portion of
an alias.

When replying to a message that matches a wildcard alias, substitute the
matching email address for the wildcard address, but keep the name
specified with the wildcard address. For example, when the alias
"Someone Awesome" <*@someone.com> is present, the reply to an email
addressed to "Someone" <hi@someone.com> would be from
"Someone Awesome" <hi@someone.com>.

Signed-off-by: Jason Cox <me@jasoncarloscox.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2023-10-22 15:12:45 +02:00
Tim Culverhouse
4ec1e1a5e4 ui: enable showing of thread-context
Add a UI config value to enable showing of "thread-context", similar
to `notmuch show --entire-thread=true`. Add an associated style called
"msglist_thread_context" which can be used to style such messages.

Currently this feature is only supported by notmuch. It would be
possible for maildir to implement as well, IMAP with gmail custom
extensions, and JMAP. This patch merely implements the notmuch version
and puts the groundwork in for handling these sorts of displays.

Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Tested-by: Inwit <inwit@sindominio.net>
Acked-by: Robin Jarry <robin@jarry.cc>
2023-09-27 23:12:41 +02:00
owl
43df87552c config: make all message list symbols/icons configurable
This patch removes the hard coded letters (which don't make sense in all
languages), and replaces them with configurable icons, like the existing
`icon-attachment` and other icons.

Signed-off-by: owl <owl@u8.is>
Acked-by: Robin Jarry <robin@jarry.cc>
Reviewed-by: Bence Ferdinandy <bence@ferdinandy.com>
2023-09-19 11:23:40 +02:00
Koni Marti
d29c9d1a2f templates: attach directly from templates
Attach a file from templates. Add a split template function.

{{- .Attach "LICENSE" -}}

or

{{range (exec "find ./doc -type f -name *.scd" "" | split "\n") -}}
	{{with . }}
		{{- $.Attach . -}}
	{{- end}}
{{- end}}

Fixes: https://todo.sr.ht/~rjarry/aerc/109
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2023-08-03 22:31:34 +02:00
Koni Marti
b267de83e3 templates: add ThreadCount and ThreadFolded
Add the number of threads and a flag to indicated folded threads to the
template data. Use {{.ThreadCount}} and {{.ThreadFolded}} in template
expression for the message list.

column-subject = {{.ThreadPrefix}}{{if .ThreadFolded}}[{{.ThreadCount}}] {{end}}{{.Subject}}

Update default configuration accordingly.

Signed-off-by: Koni Marti <koni.marti@gmail.com>
Signed-off-by: Robin Jarry <robin@jarry.cc>
Tested-by: inwit <inwit@sindominio.net>
2023-07-16 10:13:12 +02:00
Robin Jarry
9479513ec1 templates: add map functions
Similar to switch and .StyleSwitch, add map and .StyleMap to work on
lists. An extra "exclude" item is available to filter elements out of
the list.

Signed-off-by: Robin Jarry <robin@jarry.cc>
Tested-by: Inwit <inwit@sindominio.net>
2023-06-10 23:54:06 +02:00
Robin Jarry
02099cc6ea 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:

[ui]
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>
2023-05-20 22:08:21 +02:00
Koni Marti
30c1a30168 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
needed.

Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Tim Culverhouse <tim@timculverhouse.com>
2023-05-16 17:12:00 +02:00
Tim Culverhouse
d8c2d63ee9 directory: add role to template fields
Add .Role as a template field for use in distinguishing between
mailboxes with a given IANA role, or custom role defined by aerc
("query" for notmuch queries, for example).

Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry<robin@jarry.cc>
2023-04-22 22:40:12 +02:00
Robin Jarry
41ae363905 templates: add conditional style method
Add .StyleSwitch that takes a string and an arbitrary number of cases
(regexp, style). Reuse some of the constructs introduced by previous
commit.

The style of the first regular expression that matches will be applied.
If the string does not match any of the expressions, it will be left
as-is.

Signed-off-by: Robin Jarry <robin@jarry.cc>
Acked-by: Tim Culverhouse <tim@timculverhouse.com>
2023-03-08 00:43:08 +01:00
Robin Jarry
573b3266af templates: reverse args order for .Style
In preparation for .StyleMatch put the content first, followed by the
style name.

Signed-off-by: Robin Jarry <robin@jarry.cc>
Acked-by: Tim Culverhouse <tim@timculverhouse.com>
2023-03-08 00:43:00 +01:00
Robin Jarry
66c532f859 templates: make SubjectBase official api
Document .SubjectBase. Fix its value along the way. Do not reuse
d.Subject() which may be empty if d.threadSameSubject is true.

Signed-off-by: Robin Jarry <robin@jarry.cc>
Acked-by: Tim Culverhouse <tim@timculverhouse.com>
2023-03-08 00:42:58 +01:00
Robin Jarry
35040bec99 templates: separate thread prefix from subject
Extract {{.ThreadPrefix}} from {{.Subject}} so that the prefix can be
styled in a different color.

Signed-off-by: Robin Jarry <robin@jarry.cc>
Acked-by: Tim Culverhouse <tim@timculverhouse.com>
2023-03-08 00:42:56 +01:00
Tim Culverhouse
d9a8edd8e9 templates: allow inline user styles
Allow custom user-defined styles in a styleset. The styles can take any
name, and must be under the [user] ini section. All attributes apply to
user defined styles.

Example:

	[user]
	red.fg=red
	red.bold=true

Add a .Style function which accepts the name of a user-defined style and
applies it to the string.

	{{.Style "red" "foo"}}

Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2023-03-02 23:04:35 +01:00
Robin Jarry
6cfbc87d8a dirlist: use templates instead of % mini language
Replace dirlist-format with two settings: dirlist-left & dirlist-right.
These two settings take aerc-templates(7) and may be left empty.

Add automatic translation of dirlist-format to these new settings.
Display a warning on startup if dirlist-format has been converted.

Signed-off-by: Robin Jarry <robin@jarry.cc>
Acked-by: Tim Culverhouse <tim@timculverhouse.com>
2023-02-20 14:48:42 +01:00
Robin Jarry
d2e74cdb91 statusline: add column based render format
In the spirit of commit 535300cfdb ("config: add columns based index
format"), reuse the column definitions and table widget.

Add automatic translation of render-format to column definitions. Allow
empty columns to be compatible with the %m (mute) flag.

Rename the State object to AccountState to be more precise. Reuse that
object in state.TempateData to expose account state info. Move actual
status line rendering in StatusLine.Draw().

Add new template fields for status specific data:

{{.ConnectionInfo}}
	Connection state.
{{.ContentInfo}}
	General status information (e.g. filter, search)
{{.StatusInfo}}
	Combination of {{.ConnectionInfo}} and {{.StatusInfo}}
{{.TrayInfo}}
	General on/off information (e.g. passthrough, threading,
	sorting)
{{.PendingKeys}}
	Currently pressed key sequence that does not match any key
	binding and/or is incomplete.

Display a warning on startup if render-format has been converted to
status-columns.

Signed-off-by: Robin Jarry <robin@jarry.cc>
Acked-by: Tim Culverhouse <tim@timculverhouse.com>
2023-02-20 14:48:42 +01:00
Robin Jarry
6af06c9dfe statusline: move files to lib/state
These modules will not handle statusline rendering after next commit.
Move them in lib/state to make next commit easier to review.

Signed-off-by: Robin Jarry <robin@jarry.cc>
Acked-by: Tim Culverhouse <tim@timculverhouse.com>
2023-02-20 14:48:42 +01:00
Aivars Vaivods
420a82a356 commands: expand template placeholders
Interpret go template constructs in all aerc command arguments based on
the currently selected account, folder and message (if any).

Signed-off-by: Aivars Vaivods <aivars@vaivods.lv>
Signed-off-by: Robin Jarry <robin@jarry.cc>
Reviewed-by: Tim Culverhouse <tim@timculverhouse.com>
2023-02-20 14:48:42 +01:00
Robin Jarry
87e3d4bafa templates: add message counts for specific folders
Change the {{.Recent}}, {{.Unread}} and {{.Exists}} template fields to
take an arbitrary number of folder names as arguments. If no folder name
is specified, these return the counts for all folders.

Signed-off-by: Robin Jarry <robin@jarry.cc>
Acked-by: Tim Culverhouse <tim@timculverhouse.com>
2023-02-20 14:44:37 +01:00
Robin Jarry
9fa296fb76 templates: unify data interface
Require that all aerc template data objects implement the same
TemplateData interface.

Implement that interface in two different places:

1) state.TemplateData (renamed/moved from templates.TemplateData).
   This structure (along with all its methods) needs to be decoupled
   from the templates package to break the import cycle with the config
   package. This allows much simpler construction of this object and
   ensure that values are calculated only when requested.

2) config.dummyData (extracted from templates).
   This is only used in the config package to validate user templates.
   Putting it here allows also to break an import cycle.

Use state.TemplateData everywhere (including for account tabs title
rendering).

Signed-off-by: Robin Jarry <robin@jarry.cc>
Reviewed-by: Moritz Poldrack <moritz@poldrack.dev>
2023-02-20 14:40:59 +01:00