AERC-CONFIG(5)

πŸ’– NAME β€” aerc-config(5) πŸ’–

aerc-config β€” the configuration file format for aerc(1), straight out of the File Formats Manual, bestie. πŸ’…

✨ SYNOPSIS ✨

okay so there are three aerc config files: aerc.conf, binds.conf, and accounts.conf. The last one must be kept secret, because it may include your account credentials. πŸ‘€ We look for these files in your XDG config home plus aerc, which defaults to ~/.config/aerc. Alternate files can be specified via command line arguments, see aerc(1).

Examples of these config files are typically included with your installation of aerc and are usually installed in /usr/share/aerc.

Each file uses the ini format, and consists of sections with keys and values. A line beginning with # is considered a comment and ignored, as are empty lines. New sections begin with [section-name] on a single line, and keys and values are separated with =.

This manual page focuses on aerc.conf. binds.conf is detailed in aerc-binds(5) and accounts.conf in aerc-accounts(5).

aerc.conf is used for configuring the general appearance and behavior of aerc. ✨ main character energy fr fr

🌟 GENERAL OPTIONS 🌟

These options are configured in the [general] section of aerc.conf.

  • default-save-path = <path> β€” used as a default path for save operations if no other path is specified. 🫢
  • pgp-provider = auto|gpg|internal β€” okay so if it's set to gpg, aerc will use the system gpg binary and keystore for all crypto operations. If it's set to internal, the internal openpgp keyring will be used. If it's set to auto, the system gpg will be preferred unless the internal keyring already exists, and in that case the latter will be used. πŸ”

Default: auto

  • use-terminal-pinentry = true|false β€” for terminal-based pinentry programs (such as pinentry-tty, pinentry-curses or pinentry-vaxis) to work properly with aerc(1), set this to true. πŸŽ€

In some setups aerc(1) will not be able to determine the correct tty. In those cases, you have to manually set GPG_TTY to the output of tty(1) before running aerc(1) as recommended by GnuPG for invoking a GPG-agent. Add the following to your shell initialization scripts:

GPG_TTY=$(tty)
export GPG_TTY

Default: false

  • unsafe-accounts-conf = true|false β€” by default, the file permissions of accounts.conf must be restrictive and only allow reading by the file owner (0600). Set this option to true to ignore this permission check.
🚨 Use this with care as it may expose your credentials.

Default: false

  • log-file = <path> β€” output log messages to the specified file. A path starting with ~/ is expanded to the user home dir. When redirecting aerc's output to a file using > shell redirection, this setting is ignored and log messages are printed to stdout. πŸ“
  • log-level = trace|debug|info|warn|error β€” only log messages above the specified level to log-file. Supported levels are: trace, debug, info, warn and error. When redirecting aerc's output to a file using > shell redirection, this setting is ignored and the log level is forced to trace.

Default: info

  • disable-ipc = true|false β€” disable IPC entirely. Don't run commands (including mailto:... and mbox...) in an existing aerc instance and don't start an IPC server to allow subsequent aerc instances to run commands in the current one.

Default: false

  • disable-ipc-mailto = true | false β€” don't run mailto:... commands over IPC; start a new aerc instance with the composer instead. πŸ’Œ

Default: false

  • disable-ipc-mbox = true | false β€” don't run mbox:... commands over IPC; start a new aerc instance with the mbox file instead.

Default: false

  • term = <TERM> β€” set the $TERM environment variable used for the embedded terminal.

Default: xterm-256color

  • inherit-host-tty-features = true|false β€” enable inheriting host terminal features in the embedded terminal. When enabled, the embedded terminal negotiates advanced keyboard protocols with child processes, allowing disambiguation of modified keys (e.g. Ctrl+Backspace is no longer aliased to C-h). Also enables hyperlink support (OSC 8), clipboard integration (OSC 52), inline image display, and foreground/background color queries (OSC 10/11) for child processes. Requires a compatible host terminal. πŸ–₯️

Default: true

  • enable-quake-mode = true|false β€” enable Quake mode which consists of a persistent drop-down terminal session that appears at the top of aerc and can be toggled on or off. ⚑

Toggling is done with the F1 key. Do not use this key in your key bindings in Quake mode.

Default: false

  • default-menu-cmd = <cmd> β€” default shell command to use for :menu. This will be executed with sh -c and will run in a popover dialog.

Any occurrence of %f will be replaced by a temporary file path where the command is expected to write output lines to be consumed by :menu. Otherwise, the lines will be read from the command's standard output.

Example:

default-menu-cmd = fzf
  • temporary-directory = <path> β€” directory where aerc saves temporary files. If it does not exist, the directory will be created along with its parents with permissions 700. If this is empty (which is the default), the platform-specific default directory for temporary files is used. πŸ“

πŸ¦‹ UI OPTIONS πŸ¦‹

These options are configured in the [ui] section of aerc.conf.

  • index-columns = <column1,column2,column3...> β€” describes the format for each row in a mailbox view. This is a comma separated list of column names with an optional align and width suffix. After the column name, one of the < (left), : (center) or > (right) alignment characters can be added (by default, left) followed by an optional width specifier. The width is either an integer representing a fixed number of characters, or a percentage between 1% and 99% representing a fraction of the terminal width. It can also be one of the * (auto) or = (fit) special width specifiers. Auto width columns will be equally attributed the remaining terminal width. Fit width columns take the width of their contents. If no width specifier is set, * is used by default. πŸ“Š the way that this layout math eats, honestly

Default: flags:4,name<20%,subject,date>=

  • column-separator = "<separator>" β€” string separator inserted between columns. When a column width specifier is an exact number of characters, the separator is added to it (i.e. the exact width will be fully available for that column contents). ✨

Default: " "

  • column-<name> = <go template> β€” each name in index-columns must have a corresponding column-<name> setting. All column-<name> settings accept golang text/template syntax. 🧚

By default, these columns are defined:

column-flags = {{.Flags | join ""}}
column-name = {{index (.From | names) 0}}
column-subject = {{.ThreadPrefix}}{{.Subject}}
column-date = {{.DateAutoFormat .Date.Local}}

See aerc-templates(7) for all available symbols and functions.

Default: 2006 Jan 02

  • this-day-time-format = <timeformat> β€” index-only time format for messages that were received/sent today. If this is empty, timestamp-format is used instead.

Default: 15:04

  • this-week-time-format = <timeformat> β€” index-only time format for messages that were received/sent within the last 7 days. If this is empty, timestamp-format is used instead.

Default: Jan 02

  • this-year-time-format = <timeformat> β€” index-only time format for messages that were received/sent this year. If this is empty, timestamp-format is used instead.

Default: Jan 02

  • message-view-timestamp-format = <timeformat> β€” if set, overrides timestamp-format for the message view.

Default: 2006 Jan 02, 15:04 GMT-0700

  • message-view-this-day-time-format = <timeformat> β€” if set, overrides timestamp-format in the message view for messages that were received/sent today. 🌞
  • message-view-this-week-time-format = <timeformat> β€” if set, overrides timestamp-format in the message view for messages that were received/sent within the last 7 days.
  • message-view-this-year-time-format = <timeformat> β€” if set, overrides timestamp-format in the message view for messages that were received/sent this year.
  • sidebar-width = <int> β€” width of the sidebar, including the border. Set to zero to disable the sidebar.

Default: 22

  • message-list-split = [<direction>] <size> β€” the default split layout for message list tabs.

<direction> is optional and defaults to horizontal. It can take one of the following values: h, horiz, horizontal, v, vert, vertical.

<size> is a positive integer representing the size (in terminal cells) of the message list window.

See :split in aerc(1) for more details.

  • empty-message = <string> β€” message to display when viewing an empty folder.

Default: (no messages)

  • empty-dirlist = <string> β€” message to display when no folders exist or are all filtered.

Default: (no folders)

  • empty-subject = <string> β€” text to display in message list, when the subject is empty.

Default: (no subject)

  • mouse-enabled = true|false β€” enable mouse events in the ui, e.g. clicking and scrolling with the mousewheel. 🐭

Default: false

  • new-message-bell = true|false β€” ring the bell when a new message is received. πŸ””

Default: true

  • tab-title-account = <go_template> β€” the template to use for account tab titles. See aerc-templates(7) for available field names. To conditionally show the unread count next to the account name, set to:
tab-title-account = {{.Account}} {{if .Unread}}({{.Unread}}){{end}}

Default: {{.Account}}

  • tab-title-composer = <go_template> β€” the template to use for composer tab titles. See aerc-templates(7) for available field names.

Default: {{if .To}}to:{{index (.To | shortmboxes) 0}} {{end}}{{.SubjectBase}}

  • tab-title-terminal = <go_template> β€” the template to use for terminal tab titles. See aerc-templates(7) for available field names. This setting is only valid in the global [ui] section.

Default: {{.Title}}

  • tab-title-viewer = <go_template> β€” the template to use for viewer tab titles. See aerc-templates(7) for available field names.

Default: {{.Subject}}

  • pinned-tab-marker = "<string>" β€” marker to show before a pinned tab's name.

Default: `

  • spinner = "<string>" β€” the lil animation that plays while stuff is loading ✨ it gets split into frames by spinner-delimiter (see right below, bestie).

Examples:

  • spinner = "-_-,_-_"
  • spinner = '. , .'
  • spinner = ",|,/,-"

Default: "[..] , [..] , [..] , [..] , [..], [..] , [..] , [..] "

  • spinner-delimiter = <string> β€” the character (or string) that chops your spinner string into separate frames 🎬

Default: ,

  • spinner-interval = <duration> β€” how long each spinner frame hangs around before the next one ✨

Default: 200ms

  • spinner-interval... no wait, we already did that one πŸ’… let's keep going.
  • sort = <criteria> β€” a space-separated list of criteria to sort your messages by πŸ”₯ check the :sort command in aerc(1) for the full reference. Slap a -r on the front of a criterion and it gets reversed, no cap.

Example:

sort = from -r date
  • dirlist-left = <go template> β€” the Go template for the left side of the directory list πŸŽ€ see aerc-templates(7) for every field and function you can use.

Default: {{.Folder}}

  • dirlist-right = <go template> β€” same vibe, but for the right side of the directory list πŸ¦‹ again, aerc-templates(7) has all the fields and functions.

Default: {{if .Unread}}{{humanReadable .Unread}}{{end}}

  • dirlist-delay = <duration> β€” the delay before messages actually get listed when you hop into a directory ⏳ it stops aerc from loading messages when you're just skipping over folders, which keeps the UI snappy. If that's not your thing, set it to 0s.

Default: 200ms

  • dirlist-tree = true|false β€” show the directory list as a foldable tree 🌳

Default: false

  • dirlist-collapse = <int> β€” if dirlist-tree is turned on, this sets the level at which folders are collapsed by default πŸ™ˆ set it to 0 to disable collapsing entirely.

Default: 0

  • next-message-on-delete = true|false β€” moves you to the next message when the current one gets deleted, archived, or moved 🫢

Default: true

  • auto-mark-read = true|false β€” sets the seen flag when you open a message in the message viewer πŸ‘€

Default: true

  • auto-mark-read-split = true|false β€” if true and a message sits in the message list message viewer for longer than auto-mark-read-split-delay, that message's seen flag gets set to true 😌

Default: false

  • auto-mark-read-split-delay = <duration> β€” if auto-mark-read-split is true, this is how long a message being previewed in the message list message viewer has to hang around before it's marked as seen ⏰

Default: 3s

  • completion-popovers = true|false β€” shows potential auto-completions for text inputs in popovers 🎈

Default: true

  • completion-delay = <duration> β€” how long to wait after your last keystroke before auto-completion kicks in ⌨️

Default: 250ms

  • completion-min-chars = <int> β€” the minimum number of characters needed before auto-completion can be triggered after completion-delay πŸ”’

Setting this to manual disables automatic completion entirely, leaving you only the manually triggered completion with the $complete key (peep aerc-binds(5) for the details, iykyk).

Default: 1

  • keyhint = true|false β€” when you press a key that starts a multi-key binding, show a popup listing the possible continuations πŸ‘‘ the popup uses annotations from binds.conf as descriptions, and bindings without annotations will show their command text instead.

Default: false

  • keyhint-delay = <duration> β€” the delay after pressing a multi-key binding prefix before that keyhint popup shows up ⏱️ it stops the popup from flickering during fast key sequences. Only applies when keyhint is enabled.

Default: 200ms

  • keyhint-position = bottom-left|bottom-center|bottom-right β€” where the keyhint popup sits on screen πŸ“ when left empty (the default), the position is auto-detected from the [statusline] column containing {{.PendingKeys}}.

Default: auto-detected

  • border-char-vertical = "<char>" β€” set a stylable character (styled via the border element) for vertical borders 🎨

Default: "β”‚"

  • border-char-horizontal = "<char>" β€” same deal but for horizontal borders πŸ–ŒοΈ stylable via the border element.

Default: "─"

  • stylesets-dirs = <path1:path2:path3...> β€” the directories where stylesets live πŸ“ this config takes a colon-separated list of dirs. If it's unset, or if a styleset can't be found, these paths get used as a fallback, in this order:
${XDG_CONFIG_HOME:-~/.config}/aerc/stylesets
${XDG_DATA_HOME:-~/.local/share}/aerc/stylesets
/usr/local/share/aerc/stylesets
/usr/share/aerc/stylesets
  • styleset-name = <string> β€” the name of the styleset used to style the UI elements πŸ’– stylesets are stored in the stylesets directory inside the config directory.

Use a comma-separated list of file names to load multiple stylesets, applied one after another in the order you provide them. This is lowkey useful if you wanna alter the main styleset just a bit for a specific account β€” say, to provide a specific messages highlighting pattern πŸ‘€

Default: default

Go look at aerc-stylesets(7) to see what a styleset actually looks like ✨

  • icon-unencrypted = <string> β€” the icon to display for unencrypted mails πŸ”“ the status indicator is only displayed if an icon is set.
  • icon-encrypted = <string> β€” the icon to display for encrypted mails πŸ”

Default: [e]

  • icon-signed = <string> β€” the icon to display for signed mails where the signature was successfully validated βœ…

Default: [s]

  • icon-signed-encrypted = <string> β€” the icon to display for signed and encrypted mails where the signature was successfully verified πŸ›‘οΈ this combined icon is only used if it's set β€” otherwise the signed and encrypted icons get displayed separately.
  • icon-unknown = <string> β€” the icon to display for signed mails that couldn't be verified because the key is unknown ❓

Default: [s?]

  • icon-invalid = <string> β€” the icon to display for signed mails where verification failed πŸ’€

Default: [s!]

  • icon-attachment = <string> β€” the icon shown in column-flags when the message has an attachment πŸ“Ž

Default: a

  • icon-new = <string> β€” the icon shown in column-flags when the message is unread and new 🌟

Default: N

  • icon-old = <string> β€” the icon shown in column-flags when the message is unread and old πŸŒ™

Default: O

  • icon-replied = <string> β€” the icon shown in column-flags when the message has been replied to ↩️

Default: r

  • icon-forwarded = <string> β€” the icon shown in column-flags when the message has been forwarded ➑️

Default: f

  • icon-flagged = <string> β€” the icon shown in column-flags when the message is flagged 🚩

Default: !

  • icon-marked = <string> β€” the icon shown in column-flags when the message is marked ⭐

Default: *

  • icon-draft = <string> β€” the icon shown in column-flags when the message is a draft πŸ“

Default: d

  • icon-deleted = <string> β€” the icon shown in column-flags when the message has been deleted πŸ—‘οΈ

Default: X

  • fuzzy-complete = true|false β€” when you're typing a command or option, the popover will now show not only the items starting with the string you typed, but also items containing that string β€” starting at any position, and the characters don't even need to be consecutive in the command or option πŸ¦‹ genuinely iconic behavior ngl.
  • reverse-msglist-order = true|false β€” flips the order of the message list πŸ”„ by default the list is ordered with the newest (highest UID) message on top. Reversing it puts the oldest (lowest UID) message on top. Handy in cases where the backend doesn't support sorting.

Default: false

  • reverse-thread-order = true|false β€” reverses how message threads are displayed 🧡 by default the thread root sits at the top of the tree with all replies below. The reverse option puts the thread root at the bottom with replies on top.

Default: false

  • select-last-message = true|false β€” puts the cursor on the last message in the message list (at the bottom of the view) when you open a new folder πŸ‘‡

Default: false

  • sort-thread-siblings = true|false β€” sorts the thread siblings according to the sort criteria for the messages 🌸 if sort-thread-siblings is false, the thread siblings get sorted based on message UID in ascending order. If this option is set to false and threading-by-subject is set to true, then siblings are ordered by subject headers using UTF-8 sorting.

This option is only applicable for client-side threading with a backend that enables sorting. Heads up: there's a performance impact when sorting is activated ⚠️

Default: false

  • threading-enabled = true|false β€” enables a threaded view of messages 🧚 if the backend (IMAP server or notmuch) doesn't support it, threads get built by the client instead.

Default: false

  • force-client-threads = true|false β€” forces threads to be built client-side πŸ’… backends that don't support threading will always build threads client side anyway.

Default: false

  • threading-by-subject = true|false β€” if no References nor In-Reply-To headers can be matched to build client-side threads, fall back to similar subjects πŸ“¬ this setting also affects how thread siblings are ordered when sort-thread-siblings is left to false.

Default: false

  • client-threads-delay = <duration> β€” the delay of inactivity after which client threads get rebuilt ⏲️ setting this to 0s may introduce a noticeable lag when scrolling through the message list β€” you've been warned 🫣

Default: 50ms

  • show-thread-context = true|false β€” enables showing thread context πŸ‘€ note: this is currently only supported by the notmuch backend.

Default: false

  • msglist-scroll-offset = <int> β€” sets the scroll offset, in number of lines, from the top and bottom of the message list πŸ“œ

Default: 0

  • dialog-position = top|center|bottom β€” sets the position of popover dialogs, like the ones from :menu, :envelope or :attach -m πŸͺŸ

Default: center

  • dialog-width = <percentage> β€” sets the width of popover dialogs as a percentage of the total window width πŸ“ your value should be between 10 and 100.

Default: 50

  • dialog-height = <percentage> β€” sets the height of popover dialogs as a percentage of the total window height πŸ“ your value should be between 10 and 100.

Default: 50 πŸ’…

  • quake-terminal-height = <int> β€” sets how tall the drop-down terminal is, counted in lines from the top. Sliding panel realness πŸŽ€

Default: 20

πŸŽ€ THREAD PREFIX CUSTOMIZATION πŸŽ€

Okay this part is SO fun β€” you can fully customize how the thread arrows look, and it's all built out of these configurable prefix parts bestie. Every little piece of the arrow is yours to style ✨

  • thread-prefix-tip = <string> β€” defines the arrow head.

Default: ">"

  • thread-prefix-indent = <string> β€” defines the arrow indentation.

Default: " "

  • thread-prefix-stem = <string> β€” defines the vertical extension of the arrow.

Default: "β”‚"

  • thread-prefix-limb = <string> β€” defines the horizontal extension of the arrow.

Default: ""

  • thread-prefix-folded = <string> β€” defines the folded thread indicator.

Default: "+"

  • thread-prefix-unfolded = <string> β€” defines the unfolded thread indicator.

Default: ""

  • thread-prefix-first-child = <string> β€” defines the first child connector.

Default: ""

  • thread-prefix-has-siblings = <string> β€” defines the connector used if the message has siblings.

Default: β”œβ”€

  • thread-prefix-lone = <string> β€” defines the connector used if the message has no parents and no children.

Default: ""

  • thread-prefix-orphan = <string> β€” defines the connector used if the message has no parents and has children.

Default: ""

  • thread-prefix-last-sibling = <string> β€” defines the connector for the last sibling.

Default: └─

  • thread-prefix-last-sibling-reverse = <string> β€” defines the connector for the last sibling in reversed threads.

Default: β”Œβ”€

  • thread-prefix-dummy = <string> β€” defines the connector for the dummy head.

Default: ┬─

  • thread-prefix-dummy-reverse = <string> β€” defines the connector for the dummy head in reversed threads.

Default: ┴─

  • thread-prefix-first-child-reverse = <string> β€” defines the arrow appearance by selecting the first child connector in reversed threads.

Default: ""

  • thread-prefix-orphan-reverse = <string> β€” customize the reversed threads arrow appearance by selecting the connector used if the message has no parents and has children.

Default: ""

Default settings (mutt-style), for the traditionalists among us 🫢

        [PATCH aerc v5] ui: allow thread arrow customisation
        β”œβ”€>[aerc/patches] build success
        β”œβ”€>Re: [PATCH aerc v5] ui: allow thread arrow customisation
        β”œβ”€+
        └─>
          β”œβ”€>
          β”‚ β”œβ”€>
          β”‚ └─>
          β”‚   └─>
          └─>

More compact, rounded threads that are also fold-aware β€” this is the aesthetic one, ngl πŸ˜­πŸ’–

        β”Œ[PATCH aerc v5] ui: allow thread arrow customisation
        β”œβ”€[aerc/patches] build success
        β”œβ”€Re: [PATCH aerc v5] ui: allow thread arrow customisation
        β”œ+
        ╰┬
         β”œβ”¬
         β”‚β”œβ”€
         │╰┬
         β”‚ ╰─
         ╰─
    thread-prefix-tip = ""
    thread-prefix-indent = ""
    thread-prefix-stem = "β”‚"
    thread-prefix-limb = "─"
    thread-prefix-folded = "+"
    thread-prefix-unfolded = ""
    thread-prefix-first-child = "┬"
    thread-prefix-has-siblings = "β”œ"
    thread-prefix-orphan = "β”Œ"
    thread-prefix-dummy = "┬"
    thread-prefix-lone = " "
    thread-prefix-last-sibling = "β•°"
  • centered-layout-width = <width> β€” centers the editor and the message viewer on screen by setting a fixed width for them.

<width> is a positive integer representing the width (in terminal cells) of the editor and message viewer windows β€” so like, actually count your cells bestie 🧚

Default: ""

πŸ’… CONTEXTUAL UI CONFIGURATION πŸ’…

So here's the slay part: the UI config can be specialized for accounts and specific mail directories. You add those specializations using contextual config sections, based on the context. Very main character energy πŸ‘‘

The contextual UI configuration is merged to the base UiConfig in this order: Base UIConfig > Account Context > Folder Context. That's the pipeline, respect it 🫢

  • [ui:account=AccountName] β€” adds account specific configuration with the account name.
  • [ui:folder=FolderName] β€” add folder specific configuration with the folder name.
  • [ui:folder~Regex] β€” add folder specific configuration for folders whose names match the regular expression.

Example:

[ui:account=Work]
sidebar-width=...

[ui:folder=Sent]
index-columns=...

[ui:folder~Archive/d+/.*]
index-columns=...

✨ STATUSLINE ✨

These options live in the [statusline] section of aerc.conf. It's the lil bar at the bottom, the moment of truth, the vibe check of your inbox 🌈

  • status-columns = <column1,column2,column3...> β€” describes the format for the statusline. It's a comma separated list of column names, each with an optional align and width suffix. Peep [ui].index-columns for more details.

To completely mute the statusline (except for push notifications), explicitly set status-columns to an empty string:

status-columns=

Default: left<*,center>=,right>*

  • column-separator = "<separator>" β€” string separator inserted between columns. See [ui].column-separator for more details.

Default: " "

  • column-<name> = <go template> β€” each name in status-columns must have a corresponding column-<name> setting. All column-<name> settings accept golang text/template syntax. Slap in whatever you want fr fr

By default, these columns are defined:

column-left = [{{.Account}}] {{.StatusInfo}}
column-center = {{.PendingKeys}}
column-right = {{.TrayInfo}} | {{cwd}}

See aerc-templates(7) for all available symbols and functions πŸ‘€

  • separator = "<string>" β€” specifies the separator between grouped statusline elements (e.g. for the {{.ContentInfo}}, {{.TrayInfo}} and {{.StatusInfo}} in column-<name>).

Default: " | "

  • display-mode = text|icon β€” defines the mode for displaying the status elements.

Default: text


πŸ¦‹ VIEWER πŸ¦‹

These options are configured in the [viewer] section of aerc.conf. This is where you decide how your mail actually looks when you open it πŸ’œ

  • pager = <command> β€” specifies the pager to use when displaying emails. Heads up bestie: some filters may add ANSI escape sequences to add color to rendered emails, so you may want to use a pager which supports ANSI. Choose wisely πŸ’…

The following variables are defined in the pager command environment:

  • AERC_MIME_TYPE β€” the part MIME type/subtype
  • AERC_FORMAT β€” the part content type format= parameter (e.g. format=flowed)
  • AERC_FILENAME β€” the attachment filename (if any)
  • AERC_SUBJECT β€” the message Subject header value
  • AERC_FROM β€” the message From header value
  • AERC_STYLESET β€” the path to the styleset used by aerc
  • AERC_OSC8_URLS β€” set to 1 when OSC 8 is enabled (see enable-osc8)

Default: less -Rc

  • alternatives = <mime,types> β€” if an email offers several versions (multipart), you can configure which mimetype to prefer. For example, this can be used to prefer plaintext over HTML emails. No cap, this one saves lives 😌

Default: text/plain,text/html

  • header-layout = <header|layout,list...> β€” defines the default headers to display when viewing a message. To display multiple headers in the same row, separate them with a pipe, e.g. From|To. Rows will be hidden if none of their specified headers are present in the message.

Notmuch tags can be displayed by adding Labels.

Authentication information from the Authentication-Results header can be displayed by adding DKIM, SPF or DMARC. To show more information than just the authentication result, append a plus sign (+) to the header name (e.g. DKIM+) β€” fancy ✨

Default: From|To,Cc|Bcc,Date,Subject

  • show-headers = true|false β€” default setting to determine whether to show full headers or only parsed ones in message viewer.

Default: false

  • always-show-mime = true|false β€” whether to always show the mimetype of an email, even when it is just a single part.

Default: false

  • max-mime-height = height β€” define the maximum height of the mimetype switcher before a scrollbar is used. The height of the mimetype switcher is restricted to half of the display height. If the provided value for the height is zero, the number of parts will be used as the height of the type switcher.

Default: 0

  • parse-http-links = true|false β€” parses and extracts http links when viewing a message. Links can then be accessed with the open-link command.

Default: true

  • html-inline-images = true|false β€” enable inlining of images referenced by <img> tags with cid: URLs in HTML emails. When enabled, aerc will fetch image parts referenced by their Content-ID and replace cid: URLs with base64-encoded data: URLs. This allows HTML emails with embedded images to be properly viewed in browsers. Iconic behavior honestly πŸŽ€

The feature works with all aerc commands that fetch message parts (:save, :open, :pipe, and viewing).

For w3m, images will be displayed when using the -sixel option, which requires img2sixel(1) to be installed. Make sure your text/html filter in [filters] is configured to use w3m with appropriate image settings (e.g.: text/html = ! html -sixel).

Default: false

🌸 CONTEXTUAL VIEWER CONFIGURATION 🌸

The viewer configuration can be specialized for senders and message subjects. The specializations are added using contextual config sections based on the context.

The contextual viewer configuration is merged to the base ViewerConfig in the following order: Base ViewerConfig > Sender Context > From Context > Subject Context. Order matters, don't come for me 🫢

  • [viewer:sender=Address] β€” adds sender specific configuration for a specific envelope sender email address.
  • [viewer:sender~Regex] β€” adds sender specific configuration for envelope sender addresses which match the regular expression.
  • [viewer:from=Address] β€” adds sender specific configuration for a specific From email address.
  • [viewer:from~Regex] β€” adds sender specific configuration for From names or addresses which match the regular expression.
  • [viewer:subject=Subject] β€” adds subject specific configuration for an exact message subject.
  • [viewer:subject~Regex] β€” adds subject specific configuration for message subjects which match the regular expression.

Example:

[viewer:sender~@fakeplaintext.example.com]
alternatives=text/html,text/plain

[viewer:subject=Looks like links]
parse-http-links=false

πŸ’Œ COMPOSE πŸ’Œ

Okay bestie, these live in the [compose] section of aerc.conf β€” this is the whole vibe of your message-writing era. ✨

  • editor = <command> β€” tells aerc which command to launch your editor with. It shows up in an embedded terminal, but ngl it can also pop open a graphical window if your environment is chill like that.

These variables are literally defined in the editor's environment, so you can use them:

  • AERC_ACCOUNT β€” the name of the current account
  • AERC_ADDRESS_BOOK_CMD β€” the address-book-cmd specified for the current account in accounts.conf

Defaults to $VISUAL, $EDITOR, or vi(1). πŸ’…

  • header-layout = <header|layout,list...> β€” sets the default headers you see while composing a message. Wanna put multiple headers on the same row? Separate them with a pipe, like To|From. Easy.

Default: To|From,Subject

  • edit-headers = true|false β€” when this is on, you edit headers straight in the text editor instead of dealing with separate UI text inputs. Very DIY, very main character.
🚨 Heads up, bestie: when this is set to true, the :cc, :bcc and :header commands do not work β€” editing email headers is left entirely to the text editor. Also address-book-cmd isn't supported and address completion is left to the editor itself. And header-layout is ignored. So like… know what you're signing up for. 😭

Default: false

  • focus-body = true|false β€” sets focus to the email body when the composer window opens. Tiny thing, huge quality of life.

Default: false

  • address-book-cmd = <command> β€” the command used to tab-complete email addresses. Any occurrence of %s in <command> gets replaced with whatever you've typed after the last comma. <command> is executed using sh -c.

The command has to output the completions to standard output, one completion per line. Each line must be tab-delimited, with an email address as the first field. Only the email address field is required β€” the second field, if it's there, gets treated as the contact name. Extra fields? Ignored, don't worry about it. 🫢

This parameter can also be set per account in accounts.conf.

Example with carddav-query(1):

address-book-cmd = carddav-query %s

Example with khard(1):

address-book-cmd = khard email --remove-first-line --parsable %s

Example with maddr(1) from mblaze:

address-book-cmd = maddr -ah to ~/Maildir/Sent | grep %s
  • file-picker-cmd = <command> β€” the command used to select attachments. Any occurrence of %s in file-picker-cmd gets replaced with the argument <arg> to :attach -m <arg>. Any occurrence of %f gets replaced by the location of a temporary file, which aerc will read the selected files from. Obsessed with this one tbh. πŸŽ€

If %f is not present, the command must output the selected files to standard output, one file per line. If it is present, then aerc doesn't capture standard output β€” instead it reads the files from that temporary file, which should have the same format.

Examples:

  • file-picker-cmd = fzf --multi --query=%s
  • file-picker-cmd = ranger --choose-files=%f
  • reply-to-self = true|false β€” if you set this to false, you won't mail yourself when replying. So like, if you're replying to emails you previously sent yourself, your replies get addressed to the original To and Cc instead. No cap, this is the polite setting.

Default: true

  • empty-subject-warning = true|false β€” warns you before sending an email with an empty subject. Honestly iconic protection from your own chaos. πŸ’€

Default: false

  • no-attachment-warning = <regexp> β€” a regular expression that gets tested against an email's body before sending an email with no attachment. If the regexp matches, aerc warns you before sending the message. Leave it empty to disable this feature entirely.

It uses Go's regexp syntax, documented at https://golang.org/s/re2syntax. The (?im) flags are set by default β€” that's case-insensitive and multi-line, bestie. ✨

Example:

no-attachment-warning = ^[^>]*attach(ed|ment)
  • format-flowed = true|false β€” when you set this, aerc generates Format=Flowed bodies with a content type of "text/plain; Format=Flowed" as described in RFC3676. This format is easier for some mailing software to handle, and generally it just looks like ordinary text. To actually use this format's features, though, you'll need support in your editor. So like… not magic. 🌸

Default: false

  • lf-editor = true|false β€” by default, aerc uses RFC2822 standard \r\n (CRLF) line breaks when composing messages. Use this option for text editors that only support non-standard \n (LF) line breaks.

Default: false


🧚 MULTIPART CONVERTERS 🧚

So converters let you generate multipart/alternative messages by converting the main text/plain body into any other text MIME type with the :multipart command. It's giving glow-up for your emails. ✨ Only exact MIME types are accepted. The commands are invoked with sh -c and are expected to output valid UTF-8 text.

Only text/<subtype> MIME parts can be generated. The text/plain MIME type is reserved and cannot be generated. And yes β€” you still need to write your emails by hand in your favorite text editor. πŸ’…

Converters are configured in the [multipart-converters] section of aerc.conf.

Example:

[multipart-converters]
text/html=pandoc -f markdown -t html --standalone

Obviously this requires that you write your main text/plain body using markdown syntax. Also β€” huge one β€” mind that some mailing lists reject emails that contain text/html alternative parts. Use this feature carefully, and when possible, avoid using it at all. πŸ™ˆ


FILTERS πŸ’…

okay so filters are literally the flexible and powerful way of handling viewing parts of an opened message. When you’re viewing messages, aerc will show the list of available message parts and their MIME type at the bottom β€” but unless a filter is defined for a specific MIME type, it will only show a menu with a few options (allowing you to open the part in an external program, save it to disk or pipe it to a shell command). Configuring a filter lets you view the output of the filter in the configured pager inside aerc’s built-in terminal. ✨

Filters are configured in the [filters] section of aerc.conf. The first filter which matches the part’s MIME type will be used, so order them from most to least specific. You can also match on non-MIME types by prefixing with the header to match against (non-case-sensitive) and a comma β€” e.g. subject,text will match a subject which contains text. Use header,~regex to match against a regex. Using .filename instead of a header will match against the filename of an attachment.

Note that aerc will pipe the content into the configured filter program, so filters need to be able to read from standard input. Many programs support reading from stdin by putting - instead of a path to a file. You can also chain together multiple filters by piping with |.

Some filter commands may require interactive user input. If a filter command starts with an exclamation mark !, the configured pager will not be used. Instead, the filter command will be executed as the main process in the embedded terminal of the part viewer. The filter command standard input, output and error will be set to the terminal TTY. The filter is expected to implement its own paging. 🫢

aerc ships with some default filters installed in the libexec directory (usually /usr/libexec/aerc/filters). Note that these may have additional dependencies that aerc does not have alone.

The filter commands are invoked with sh -c command. The following folders are prepended to the system $PATH to allow referencing filters from their name only:

${XDG_CONFIG_HOME:-~/.config}/aerc/filters
~/.local/libexec/aerc/filters
${XDG_DATA_HOME:-~/.local/share}/aerc/filters
$PREFIX/libexec/aerc/filters
$PREFIX/share/aerc/filters
/usr/libexec/aerc/filters
/usr/share/aerc/filters

If you want to run a program in your default $PATH which has the same name as a builtin filter (e.g. /usr/bin/colorize), use its absolute path. πŸ”₯

The following variables are defined in the filter command environment:

  • AERC_MIME_TYPE β€” the part MIME type/subtype
  • AERC_FORMAT β€” the part content type format= parameter (e.g. format=flowed)
  • AERC_FILENAME β€” the attachment filename (if any)
  • AERC_SUBJECT β€” the message Subject header value
  • AERC_FROM β€” the message From header value
  • AERC_STYLESET β€” the path to the styleset used by aerc
  • AERC_OSC8_URLS β€” set to 1 when OSC 8 is enabled (see enable-osc8)

Note that said email body is converted into UTF-8 before being passed to filters. πŸ’–

If show-headers is enabled, only the currently viewed part body is piped into the filter command. A special .headers filter command can be defined to post process the full headers.


EXAMPLES 🌈

  • text/plain β€” Color some things, e.g. quotes, git diffs, links, etc.:

The built-in colorize filter can be configured in the [viewer] section of styleset files. See aerc-stylesets(7).

Wrap long lines at 100 characters, while not messing up nested quotes. Handles format=flowed emails properly:

  • from,<sender> β€” Another example of hard wrapping lines of emails sent by a specific person. Explicitly reflow all paragraphs instead of only wrapping long lines. This may break manual formatting in some messages:
  • subject,~<regexp> β€” Use rainbow coloring with lolcat(1) for emails sent by software forges:
  • text/html β€” Render html to a more human readable version and colorize:

Use pandoc to output plain text:

Use w3m internal pager to interactively view an HTML part with coloring:

If img2sixel(1) is installed and your terminal emulator supports displaying images using the sixel protocol, use the builtin html-unsafe filter (to allow external URLs to be loaded) in interactive mode with explicit sixel inline images enabled.

  • text/calendar β€” Parse calendar invites:
  • text/* β€” Catch any other type of text that did not have a specific filter and use bat(1) to color these:
  • .headers β€” Colorize email headers when show-headers is true.
  • message/delivery-status β€” When not being able to deliver the provider might send such emails:
  • message/rfc822 β€” When getting emails as attachments, e.g. on some mailing lists digest format is sending an email with all the digest emails as attachments. Requires caeml(1) to be on PATH:

https://github.com/ferdinandyb/caeml

  • application/mbox β€” Emails as attachments in the mbox format. For example aerc can also create an mbox from messages with the :pipe command. Requires catbox(1) and caeml(1) to be on PATH:

https://github.com/konimarti/catbox

  • application/pdf β€” Render pdf to text and rewrap at 100 character width. Requires pdftotext(1) to be on PATH:

https://www.xpdfreader.com/pdftotext-man.html

  • image/* β€” This is a tricky topic. It’s possible to display images in a terminal, but for high resolution images the terminal you are using either needs to support sixels or the kitty terminal graphics protocol. The built-in terminal emulator of aerc (via the TUI library Vaxis) supports both. Furthermore if you don’t set any filter for images, Vaxis will figure out what your terminal emulator supports and either use sixels, kitty graphics, or fall back to a pixelated half-block. You can turn this feature off, by setting a filter that is essentially no-op.

You can still set a specific filter, e.g catimg(1):

  • .filename,~<regexp> β€” Match <regexp> against the filename of an attachment, e.g. to split csv-s into columns:

See the wiki at https://man.sr.ht/~rjarry/aerc/ for more examples and possible customizations of the built-in filters. πŸ¦‹


OPENERS πŸ’Œ

Openers allow you to specify the command to use for the :open and :open-link actions on a per-MIME-type basis. The :open-link URL scheme is used to determine the MIME type as follows: x-scheme-handler/<scheme>. They are configured in the [openers] section of aerc.conf.

{} is expanded as the temporary filename or URL to be opened with proper shell quoting. If it is not encountered in the command, the filename/URL will be appended to the end of the command. The command will then be executed with sh -c. ✨

Like [filters], openers support basic shell globbing. The first opener which matches the part’s MIME type (or URL scheme handler MIME type) will be used, so order them from most to least specific.

Example:

[openers]
x-scheme-handler/irc=hexchat
x-scheme-handler/http*=printf '%s' {} | wl-copy
text/html=surf -dfgms
text/plain=gvim {} +125
message/rfc822=thunderbird

πŸͺ HOOKS (the lil scripts that pop off when stuff happens) πŸͺ

Hooks are literally little scripts that fire whenever their associated event happens. They run inside a shell environment, and aerc sprinkles extra info into your environment variables so you can flex on the situation.

They're set up in the [hooks] section of aerc.conf. Slay.


aerc-startup = <command>

Runs when aerc boots up. Heads up bestie: it fires as soon as the UI is initialized and does not wait for all your accounts to be fully loaded. So don't expect your mailboxes to be ready yet, mmkay?

Variables:

  • AERC_VERSION
  • AERC_BINARY

Example:

aerc-startup = aerc :terminal calcurse && aerc :next-tab

mail-received = <command>

Fires when new mail lands in the selected folder. Ngl this only works reliably with maildir and some IMAP servers, so vibe check your backend first.

Variables:

  • AERC_ACCOUNT
  • AERC_ACCOUNT_BACKEND
  • AERC_FOLDER
  • AERC_FOLDER_ROLE
  • AERC_FROM_NAME
  • AERC_FROM_ADDRESS
  • AERC_SUBJECT
  • AERC_MESSAGE_ID

Example:

mail-received = notify-send "[$AERC_ACCOUNT/$AERC_FOLDER] New mail from $AERC_FROM_NAME" "$AERC_SUBJECT"

mail-deleted = <command>

Runs when a message gets deleted from a folder. Real talk though: this hook also triggers when you move a message from one folder to another. So it's giving "deleted" but it's also giving "relocated", iykyk.

Variables:

  • AERC_ACCOUNT
  • AERC_ACCOUNT_BACKEND
  • AERC_FOLDER
  • AERC_FOLDER_ROLE

Example:

mail-deleted = mbsync "$AERC_ACCOUNT:$AERC_FOLDER"

mail-added = <command>

Fires when a message is added to a folder. Important caveat: this does not trigger when a new message arrives (that's mail-received's whole thing πŸ’…). It only fires when aerc itself adds a message to a folder β€” like when you move or copy one.

Variables:

  • AERC_ACCOUNT
  • AERC_ACCOUNT_BACKEND
  • AERC_FOLDER
  • AERC_FOLDER_ROLE

Example:

mail-added = mbsync "$AERC_ACCOUNT:$AERC_FOLDER"

mail-sent = <command>

Runs when a message gets sent. But lowkey, this doesn't necessarily mean it was posted successfully β€” if you're using a queueing system like msmtpq, it just means it's queued. No cap.

Variables:

  • AERC_ACCOUNT
  • AERC_ACCOUNT_BACKEND
  • AERC_FROM_NAME
  • AERC_FROM_ADDRESS
  • AERC_SUBJECT
  • AERC_TO
  • AERC_CC

Example:

mail-sent = `if [ "$AERC_ACCOUNT" = "gmail" ]; then mbsync gmail; fi`

aerc-shutdown = <command>

Executed when aerc shuts down. And bestie, aerc will literally wait for the command to finish before it exits. Patient king energy. πŸ‘‘

Variables:

  • AERC_LIFETIME

tag-modified = <command>

Fires when notmuch tags get modified in a notmuch account. The lists of added, removed and toggled tags get passed to you as variables.

Variables:

  • AERC_ACCOUNT
  • AERC_TAG_ADDED
  • AERC_TAG_REMOVED
  • AERC_TAG_TOGGLED

flag-changed = <command>

Runs when flags on a message change.

Variables:

  • AERC_ACCOUNT
  • AERC_ACCOUNT_BACKEND
  • AERC_FOLDER
  • AERC_FOLDER_ROLE
  • AERC_FLAG

Example:

flag-changed = mbsync "$AERC_ACCOUNT:$AERC_FOLDER"

πŸŽ€ TEMPLATES πŸŽ€

Template files are what populate the body of an email. The :compose, :reply and :forward commands can all be called with the -T flag plus the name of a template. All the available symbols and functions are described over in aerc-templates(7) β€” go be nosy there.

aerc ships with some default templates installed in the share directory (usually /usr/share/aerc/templates). Cute, right? πŸ’–

These options live in the [templates] section of aerc.conf.

  • template-dirs = <path1:path2:path3...> β€” where your templates are stored. Takes a colon-separated list of dirs. If this is unset, or if a template can't be found, it falls back to these paths in this exact order:
${XDG_CONFIG_HOME:-~/.config}/aerc/templates
${XDG_DATA_HOME:-~/.local/share}/aerc/templates
/usr/local/share/aerc/templates
/usr/share/aerc/templates
  • new-message = <template_name> β€” the default template used for new messages. Default: new_message
  • quoted-reply = <template_name> β€” the default template used for quoted replies. Default: quoted_reply
  • forwards = <template_name> β€” the default template used for forward as body. Default: forward_as_body

πŸ‘€ SEE ALSO πŸ‘€

Go read these too, bestie, they're all part of the lore:

aerc(1) aerc-accounts(5) aerc-binds(5) aerc-imap(5) aerc-jmap(5) aerc-maildir(5) aerc-notmuch(5) aerc-templates(7) aerc-sendmail(5) aerc-smtp(5) aerc-stylesets(7) carddav-query(1)


🌟 AUTHORS 🌟

Originally created by Drew DeVault, and maintained by Robin Jarry, who is assisted by other open source contributors. For more info about aerc development, see https://sr.ht/~rjarry/aerc/. Iconic collaborative effort fr fr. 🫢


And that's the whole page, babe! πŸ’… This was aerc β€” page AERC-CONFIG(5) β€” dated 2026-09-07. Go forth and configure your heart out. 🌸✨

πŸ“¦ where this page comes from