MELI.CONF(5)
๐ MELI.CONF(5) ๐
File Formats Manual ยท MELI.CONF(5)
okay bestie so this is the manual page for meli.conf โ the configuration file for the meli(1) terminal e-mail client ๐โจ
โจ NAME โจ
meli.conf โ configuration file for the meli(1) terminal e-mail client ๐ฆ
๐ธ SYNOPSIS ๐ธ
$XDG_CONFIG_HOME/meli/config.toml
๐ DESCRIPTION ๐
So meli's config is written in TOML, and there's a few things you gotta know about it (this is straight from the spec, no cap):
- TOML is case sensitive. case sensitive!! don't be out here capitalizing stuff and wondering why nothing works ๐ญ
- A TOML file must be a valid UTF-8 encoded Unicode document.
- White-space means tab (
0x09) or space (0x20). - Newline means LF (
0x0A) or CRLF (0x0D 0x0A).
Go check the TOML documentation if you want the full valid-syntax tea โ
Now here's the fun part โ even though it's not technically part of TOML syntax, meli.conf can have nested configuration files using this m4(1) include macro:
include("/path/to/file")
the way that just works?? obsessed ๐
๐ฆ SECTIONS ๐ฆ
The top level sections of the config are:
accountsshortcutsnotificationspagerlistingcomposingpgpterminallog
๐ EXAMPLES ๐
Here's an example configuration, bestie โ take notes ๐โจ
# Setting up a Maildir account
[accounts.account-name]
root_mailbox = "/path/to/root/folder"
format = "Maildir"
listing.index_style = "Compact"
identity="email@example.com"
subscribed_mailboxes = ["folder", "folder/Sent"] # or [ "*", ] for all mailboxes
display_name = "Name"
send_mail = 'msmtp --read-recipients --read-envelope-from'
#send_mail = { hostname = "smtp.example.com", port = 587, auth = { type = "auto", username = "user", password = { type = "command_eval", value = "gpg2 --no-tty -q -d ~/.passwords/user.gpg" } }, security = { type = "STARTTLS" } }
# Set mailbox-specific settings
[accounts.account-name.mailboxes]
"INBOX" = { alias="Inbox" } #inline table
"drafts" = { alias="Drafts" } #inline table
[accounts.account-name.mailboxes."foobar-devel"] # or a regular table
ignore = true # don't show notifications for this mailbox
# Setting up an mbox account
[accounts.mbox]
root_mailbox = "/var/mail/username"
format = "mbox"
listing.index_style = "Compact"
identity="username@hostname.local"
send_mail = { hostname = "localhost", port = 25, auth = { type = "none" }, security = { type = "none" } }
[pager]
filter = "COLUMNS=72 /usr/local/bin/pygmentize -l email"
html_filter = "w3m -I utf-8 -T text/html"
[notifications]
script = "notify-send"
[composing]
editor_command = 'vim +/^$'
[shortcuts]
[shortcuts.composing]
edit = 'e'
[shortcuts.listing]
new_mail = 'm'
set_seen = 'n'
[terminal]
theme = "light"
Available options are listed below ๐
๐ ACCOUNTS ๐
๐ง Account configuration settings
Default values are shown in parentheses, bestie.
root_mailboxString โ The backend-specific path of theroot_mailbox, usuallyINBOX.send_mailString|SmtpServerConf โ Command to pipe new mail to (exit code must be0for success) or settings for an SMTP server connection. See section "SMTP Connections" for its fields.default_mailboxString โ (optional) The mailbox that is the default to open or view for this account. Must be a valid mailbox path. If not specified, the default will be the root mailbox.formatString [maildirmboximapnotmuchjmap] โ The format of the mail backend.subscribed_mailboxes[String,] โ An array of mailbox paths to display in the UI. Paths are relative to the root mailbox (e.g.INBOX/Sent, notSent). The glob wildcard*can be used to match every mailbox name and path.identityString โ Your e-mail address that is inserted in theFrom:headers of outgoing mail.extra_identities[String,] โ Extra e-mail address identities. When replying to an e-mail addressed to one of these identities, theFrom:header will be adjusted to its value instead of the default identity.display_nameString โ (optional) A name which can be combined with your address:"Name <email@example.com>".read_onlyboolean โ Attempt to not make any changes to this account. (false)manual_refreshboolean โ (optional) Iftrue, do not monitor account for changes (you can use shortcutlisting.refresh). (false)refresh_commandString โ (optional) command to execute when manually refreshing (shortcutlisting.refresh) (None)search_backendString โ (optional) Choose which search backend to use. Available options are"none"and"sqlite3". ("sqlite3")vcard_folderString โ (optional) Folder that contains.vcffiles. They are parsed and imported read-only.mutt_alias_fileString โ (optional) Path ofmutt(1)compatible alias file in the option They are parsed and imported read-only.notmuch_address_book_queryString โ (optional) Query passed to"notmuch address"to import contacts into meli. Contacts are parsed and imported read-only.mailboxesmailbox โ (optional) Configuration for each mailbox. Its format is described below in "mailboxes".
๐ notmuch only
notmuch is supported by loading the dynamic library libnotmuch. If its location is missing from your library paths, you must add it yourself. Alternatively, you can specify its path by using a setting. iykyk โจ
notmuch mailboxes are virtual, since they are defined by user-given notmuch queries. You must explicitly state the mailboxes you want in the mailboxes field and set the query property to each of them. To create a tree hierarchy with virtual mailboxes, define the parent property to a mailbox as the name of the parent mailbox you have used in your configuration. ๐ณ
Account properties:
root_mailboxโ points to the directory which contains the.notmuch/subdirectory.library_file_pathPath โ Use an arbitrary location oflibnotmuchby specifying its full filesystem path. (optional)
Mailbox properties:
queryString โ The notmuch query that defines what content this virtual mailbox has. Refer tonotmuch-search-terms(7)for notmuch's search syntax.parentString โ If you wish to build a mailbox hierarchy, define the name of a parent mailbox you have used in your configuration. (optional)
Example:
[accounts.notmuch]
format = "notmuch"
#library_file_path = "/opt/homebrew/lib/libnotmuch.5.dylib"
...
[accounts.notmuch.mailboxes]
"INBOX" = { query="tag:inbox", subscribe = true }
"Drafts" = { query="tag:draft", subscribe = true }
"Sent" = { query="from:username@example.com from:username2@example.com", subscribe = true }
"Archives" = { query="tag:archived", subscribe = true }
"Archives/2019" = { query="tag:archived date:01-2019..12-2019", parent="Archives", subscribe = true }
๐ IMAP only
IMAP specific options are, like, right here ๐ :
server_hostnameString โ example:"mail.example.com"server_usernameString โ Server usernameserver_passwordString โ Server passwordserver_password_commandString โ (optional) Use instead ofserver_passwordserver_portnumber โ (optional) The port to connect to (143)use_starttlsboolean โ (optional) If port is993and"use_starttls"is unspecified, it becomesfalseby default. (true)use_tlsboolean โ (optional) Connect with TLS (or upgrade from plain connection to TLS if STARTTLS is set.) (true)danger_accept_invalid_certsboolean โ (optional) Do not validate TLS certificates. (false) โ ๏ธ
okay so danger_accept_invalid_certs is literally named danger for a reason bestie โ it turns off TLS certificate validation. the girlies are NOT doing that in prod, fr fr ๐
offline_cacheboolean โ (optional) Keep mail headers in an sqlite3 database. (true)use_idleboolean โ (optional) Use IDLE extension. (true)use_condstoreboolean โ (optional) Use CONDSTORE extension. (true)use_deflateboolean โ (optional) Use COMPRESS=DEFLATE extension (if built with DEFLATE support) (true)use_oauth2boolean โ (optional) turn on OAUTH2 auth ๐ bestie this one only works alongsideserver_password_command, and that command has to hand back a base64-encoded OAUTH2 token that's ready to be yeeted straight into IMAP. Wanna set it up with Gmail? The Gmail section down below has your back. Default:falseuse_auth_anonymousboolean โ (optional) use theAUTH=ANONYMOUSextension for authentication. Default:falseuse_idboolean โ (optional) use the ID extension to grab server metadata (you can peek at it on the account status page ๐). Turning this on does not send any info to the server, so chill. Default:falseuse_connection_poolboolean โ (optional) use a connection pool with more than one server connection, so you don't get time-outs while doing a bunch of operations back to back. Here's the tea ๐: IMAP connections are stateful and can only handle one mailbox at a time, so using a connection means locking it. Having a pool of spare connections that get created on demand โ in case they're ready faster than the main connection can be unlocked โ might ease up that lock contention. Default:truetimeoutinteger โ (optional) how long (in seconds) to wait on server connections before giving up. A timeout of0seconds means there is no timeout at all, live your truth. Default:16
๐ Gmail ๐
Gmail has non-standard IMAP behaviors that need to be worked around. Not Gmail being quirky again ๐ญ
โจ Gmail - sending mail โจ
The store_sent_mail option should be disabled, because Gmail auto-saves sent mail all by its own self. Let it cook ๐ซถ
๐ Gmail OAUTH2 ๐
To use OAUTH2, you have to go through a whole process to register your own private "application" with Google that can use OAUTH2 tokens, and then set the option use_oauth2 to 'true' in the account configuration section. For convenience, in the meli repository under the contrib/ directory you can find a python3 file named oauth2.py to generate and request the appropriate data to perform OAUTH2 authentication. Little gift from us to you ๐
Steps:
- In Google APIs, create a custom OAuth client ID and note down the Client ID and Client Secret. You may need to create a consent screen; just follow the steps described in the website.
- Run the
oauth2.pyscript as follows (after adjusting binary paths and credentials):
python3 oauth2.py --user=xxx@gmail.com
--client_id=1038[...].apps.googleusercontent.com
--client_secret=VWFn8LIKAMC-MsjBMhJeOplZ --generate_oauth2_token
and follow the instructions. Note down the refresh token.
- In
server_password_commandenter a command like this (after adjusting binary paths and credentials):
TOKEN=$(python3 oauth2.py --user=xxx@gmail.com --quiet
--client_id=1038[...].apps.googleusercontent.com
--client_secret=VWFn8LIKAMC-MsjBMhJeOplZ
--refresh_token=1/Yzm6MRy4q1xi7Dx2DuWXNgT6s37OrP_DW_IoyTum4YA) &&
python3 oauth2.py --user=xxx@gmail.com --generate_oauth2_string
--quiet --access_token=$TOKEN
- On startup, meli should evaluate this command which if successful must only return a base64-encoded token ready to be passed to IMAP.
Your account section should look like this:
[accounts."gmail"]
root_mailbox = '[Gmail]'
format = "imap"
server_hostname='imap.gmail.com'
server_username="username@gmail.com"
use_oauth2 = true
server_password_command = "TOKEN=$(py...th2_string --quiet --access_token=$TOKEN"
server_port="993"
listing.index_style = "Conversations"
identity = "username@gmail.com"
display_name = "Name Name"
subscribed_mailboxes = ["*" ]
send_mail = { hostname = "smtp.gmail.com", port = 587, auth = { type = "xoauth2", token_command = "...", require_auth = true }, security = { type = "STARTTLS" } }
composing.store_sent_mail = false
๐ฆ JMAP only ๐ฆ
JMAP specific options, bestie. Only for the JMAP girlies โจ
server_urlString โ example:"http://mail.example.com""http://mail.example.com:8080""https://mail.example.com"server_usernameString โ Server usernameserver_passwordString โ Server passwordserver_password_commandString โ (optional) Use instead ofserver_passworduse_tokenboolean โ Authenticate using the API Bearer token method. If enabled, the token value must be provided as the configured password. Default:falsedanger_accept_invalid_certsboolean โ (optional) Do not validate TLS certificates. Default:falsetimeoutinteger โ (optional) Timeout to use for server connections in seconds. A timeout of0seconds means there is no timeout. Default:16
๐ธ mbox only ๐ธ
mbox specific options:
prefer_mbox_typeString โ (optional) Prefer a specific mbox format reader for each message. Default is"mboxcl2"format. If the preferred format fails, the message is retried withmboxrdand then if it fails again there is a recover attempt, which discards the invalid message. ๐ญ
Valid values:
automboxomboxrdmboxclmboxcl2
Default: auto
To set multiple mailboxes, you have to explicitly state the mailboxes you want in the mailboxes field and set the path property to each of them. Example:
[accounts.mbox]
format = "mbox"
mailboxes."Python mailing list" = { path = "~/.mail/python.mbox", subscribe = true, autoload = true }
๐ NNTP ๐
NNTP specific options, no cap ๐ฐ
server_hostnameString โ example:"nntp.example.com"server_usernameString โ Server usernameserver_passwordString โ Server passwordrequire_authboolean โ (optional) require authentication in every case. Default:trueuse_tlsboolean โ (optional) Connect with TLS. Default:falseserver_portnumber โ (optional) The port to connect to. Default:119danger_accept_invalid_certsboolean โ (optional) Do not validate TLS certificates. Default:falsestore_flags_locallyboolean โ (optional) Store seen status locally in ansqlite3database. Default:truetimeoutinteger โ (optional) Timeout to use for server connections in seconds. A timeout of0seconds means there is no timeout. Default:16
You have to explicitly state the groups you want to see in the mailboxes field. Example:
[accounts.sicpm.mailboxes]
"sic.all" = {}
To submit articles directly to the NNTP server, you must set the special value server_submission in the account send_mail field. Example:
send_mail = "server_submission"
๐ MAILBOXES ๐
aliasString โ (optional) Show a different name for this mailbox in the UI. Glow-up your folder names ๐autoloadboolean โ (optional) Load this mailbox on startup. Default:truecollapsedboolean โ (optional) Collapse this mailbox subtree in the menu. Default:falsesubscribeboolean โ (optional) Watch this mailbox for updates. Default:trueignoreboolean โ (optional) Silently insert updates for this mailbox, if any. Default:falseusageboolean โ (optional) special usage of this mailbox. Valid values are:Normal(default)InboxArchiveDraftsFlaggedJunkSentTrash
otherwise usage is inferred from the mailbox title. So if, for example, your Sent folder is not named "Sent", you must explicitly set it. Fr fr, it won't guess for you ๐
conf_overrideboolean โ (optional) Override global settings for this mailbox. The available sections to override arepager,notifications,shortcuts,composingand the account optionsidentity. Example:
...and the rest of that example goes a little something like this, bestie:
[accounts."imap.example.com".mailboxes]
"INBOX" = { index_style = "plain" }
"INBOX/Lists/devlist" = { autoload = false, pager = { filter = "pygmentize -l diff -f 256"} }
sort_orderunsigned integer โ (optional) okay so this one lets you override the sort order for this specific mailbox in the sidebar โจ. You're basically telling the sidebar "no babe, this is the order, respect it." Here's the vibe:
[accounts."imap.example.com".mailboxes]
"INBOX" = { index_style = "plain" }
"INBOX/Sent" = { sort_order = 0 }
"INBOX/Drafts" = { sort_order = 1 }
"INBOX/Lists" = { sort_order = 2 }
So INBOX/Sent gets to be first, Drafts is right behind it, and Lists brings up the rear โ main character, supporting cast, and the group chat, fr fr. ๐
encodingString โ (optional) this one overrides the default UTF-8 charset for the mailbox name ๐. And lowkey, it's only useful for UTF-7 mailboxes โ like, don't come for it if you're living that UTF-8 life, it's not for you ๐ .
The values it takes are: utf7, utf-7, utf8, utf-8.
UTF-7 mailboxes are genuinely giving cursed energy but we support them anyway because we're nothing if not inclusive ๐ฆ
๐ COMPOSING ๐
โจ Composing specific configuration settings โจ
bestie this is the part where you tell meli how to write your emails for you and honestly it's giving main character energy. Default values are shown in parentheses, so when you see (false) just know that's what meli does when you say absolutely nothing. ๐
editor_commandString โ the command that launches your editor. It can totally have arguments, it's fine. Your draft's filename gets handed over as the last argument. If this setting is just... not there, meli goes looking for the environment variableEDITORinstead.embedded_ptyboolean โ (optional) an embedded editor living inside meli. Your editor has to be xterm compliant for this to work. (false)format_flowedboolean โ (optional) setsformat=flowed[RFC3676] intext/plainattachments. (true)insert_user_agentboolean โ (optional) adds the meliUser-Agentheader to your shiny new drafts. (true)default_header_valueshash table String[String] โ (optional) the default header values meli uses when it's creating a new draft. ({})wrap_header_preambleOption<(String, String)> โ (optional) wraps the header pre-ample when you're editing a draft in an editor. This is the slay trick that lets you write non-plain text email without the preamble creating syntax errors. They get stripped when you come back from the editor, don't worry. The value should be a two element array of strings: a prefix and a suffix. Super useful when you're writing Markdown for example โ set the value to["<!--", "-->"]and boom, your headers are wrapped in an HTML comment. (None)store_sent_mailboolean โ (optional) stores your sent mail after a successful submission. Lowkey this setting exists so you can disable it for non-standard behaviour in Gmail, since Gmail auto-saves sent mail all on its own. (true)attribution_format_stringString โ (optional) the attribution line, aka the little text that appears above the quoted reply. The format specifiers for the replied address are:%+fโ the sender's name and email address.%+nโ the sender's name (or the email address, if no name is included).%+aโ the sender's email address.
The format string gets passed to strftime(3) along with the replied envelope's date. (On %a, %0e %b %Y %H:%M, %+f wrote:%n)
attribution_use_posix_localeboolean โ (optional) whether thatstrftime(3)call for the attribution string uses the POSIX locale instead of the user's active locale. (true)forward_as_attachmentboolean or ask โ (optional) forwarding emails as an attachment? (the alternative is inline, fyi). (ask)reply_prefix_list_to_strip[String] โ (optional) alternative lists of reply prefixes (like["Re:", "RE:", ...]) to strip. Here's the default, in all its multilingual glory:
[Re:, RE:, Fwd:, Fw:, ๅๅค:, ๅ่ฆ:, SV:, Sv:, VS:, Antw:, Doorst:, VS:, VL:, REF:,
TR:, TR:, AW:, WG:, ฮฮ :, ฮฯ:, ฮฑฯ:, ฮ ฮกฮ:, ฮ ฯฮธ:, ฯฯฮธ:, ฮฃฮงฮฮค:, ฮฃฯฮตฯ:, ฯฯฮตฯ:, ฮ ฮกฮ:,
ฮ ฯฮธ:, ฯฯฮธ:, Vรก:, Tovรกbbรญtรกs:, R:, I:, RIF:, FS:, BLS:, TRS:, VS:, VB:, RV:, RES:,
Res, ENC:, Odp:, PD:, YNT:, ฤฐLT:, ATB:, YML:]
reply_prefixString โ (optional) the prefix to use in reply subjects. The default prefix is 'Re:'. ('Re:')
and ok because the manpage is a nerd, RFC 2822, "Internet Message Format" has this to say on the matter:
When used in a reply, the field body MAY start with the string "Re: " (from the Latin "res", in the matter of) followed by the contents of the "Subject:" field body of the original message.
custom_compose_hooks[{ name = String, command = String }] โ (optional) custom compose-hooks that run shell scripts. compose-hooks run before submitting an e-mail, and they do draft validation and/or transformations. If a custom hook exits with an error status, or prints output tostdoutandstderr, it will show up in the UI as a notification. ๐
Example:
[composing]
editor_cmd = '~/.local/bin/vim +/^$'
embedded_pty = true
custom_compose_hooks = [ { name ="spellcheck", command="aspell --mode email --dont-suggest --ignore-case list" }]
disabled_compose_hooks[String] โ (optional) disabled compose-hooks. compose-hooks run before submitting an e-mail and they perform draft validation and/or transformations. If a hook encounters an error or warning, it will show up as a notification. The currently available hooks are:past-date-warnโ warns you if theDateheader value is far in the past or future.important-header-warnโ warns you if important headers (From,Date,To,Cc,Bcc) are missing or invalid.missing-attachment-warnโ warns you ifSubjector draft body mention attachments but they are missing. ๐ญempty-draft-warnโ warns you if the draft has no subject and no body.
signature_filePath โ (optional) a plain text file with a signature that will pre-populate an email draft. Signatures must be explicitly enabled to be used, otherwise this setting just gets ignored, periodt. (None)use_signaturebool โ pre-populate email drafts with a signature, if any. meli will lookup the signature value in this order:- The
signature_filesetting. ${XDG_CONFIG_DIR}/meli/<account>/signature${XDG_CONFIG_DIR}/meli/signature${XDG_CONFIG_DIR}/signature${HOME}/.signature- No signature otherwise.
- The
(false)
signature_delimiterString โ (optional) the signature delimiter, that is, the text that gets prefixed to your signature to separate it from the email body. ('\n\n-- \n')allow_reply_to_selfboolean โ (optional) when you're replying to an e-mail authored by our main identity or one of our extra identities, reply to those addresses instead of reusing the receivers of the original e-mail we're replying to. The default isfalse, because the intuitive behavior when replying to ourselves is to follow-up on an e-mail we sent. (false)
โจ SHORTCUTS โจ
okay bestie, this is the part where you get to tell meli which keys do what. shortcuts are fully customizable and it's giving main character energy. ๐
๐น Values corresponding to keyboard keys, keycodes
Shortcuts can take the following values:
BackspaceLeftRightUpDownHomeEndPageUpPageDownDeleteInsertEnterTabEscF1..F12M-charC-charchar
Where char is a single character string, maximum 4 bytes long, like the corresponding type in Rust.
In the next subsection, you will find lists for each shortcut category. The headings before each list indicate the map key of the shortcut list. For example for the first list titled general the configuration is typed as follows:
[shortcuts.general]
next_tab = 'T'
and for listing:
[shortcuts.listing]
open_entry = "Enter"
exit_entry = 'i'
commands
In addition, each shortcuts section supports a TOML array of commands to associate a key to an array of COMMAND mode commands.
[shortcuts.listing]
commands = [ { command = [ "tag remove trash", "flag unset trash" ], shortcut = "D" },
{ command = [ "tag add trash", "flag set trash" ], shortcut = "d" } ]
โ๏ธ Shortcut configuration settings
Default values are shown in parentheses.
general
toggle_helpโ Pops open the help and shortcuts view. (?)enter_command_modeโ Drops you into COMMAND mode. (:)quitโ Says bye to meli. (q)go_to_tabโ Jumps to the nth tab (M-n)next_tabโ Slides over to the next tab. (T)scroll_rightโ Generic scroll right (catch-all setting). (l)scroll_leftโ Generic scroll left (catch-all setting). (h)scroll_upโ Generic scroll up (catch-all setting). (k)scroll_downโ Generic scroll down (catch-all setting). (j)next_pageโ Go to next page (catch-all setting). (PageDown)prev_pageโ Go to previous page (catch-all setting). (PageUp)home_pageโ Go to first page (catch-all setting). (Home)end_pageโ Go to last page (catch-all setting). (End)open_entryโ Open list entry (catch-all setting). (Enter)info_message_nextโ Show next info message, if any. (>)info_message_previousโ Show previous info message, if any. (<)focus_in_text_fieldโ Focus on a text field. (Enter)next_search_resultโ Scroll to next search result. (n)previous_search_resultโ Scroll to previous search result. (N)
listing
scroll_upโ Scroll up the list. (k)scroll_downโ Scroll down the list. (j)next_pageโ Go to next page. (PageDown)prev_pageโ Go to previous page. (PageUp)new_mailโ Start a new mail draft in a new tab. (m)next_accountโ Go to next account. (H)prev_accountโ Go to previous account. (L)next_mailboxโ Go to next mailbox. (J)prev_mailboxโ Go to previous mailbox. (K)open_mailboxโ Open the selected mailbox. (Enter)toggle_mailbox_collapseโ Toggle mailbox visibility in the menu. (Space)searchโ Search within the list of e-mails. (/)refreshโ Manually request a mailbox refresh. (F5)set_seenโ Set thread as seen. (n)send_to_trashโ Send entry to the trash folder. (D)union_modifierโ Union modifier. (C-u)diff_modifierโ Difference modifier. (C-d)intersection_modifierโ Intersection modifier. (i)select_entryโ Select (or toggle) a thread entry. (V)select_motionโ Perform a select motion with a movement. (v)increase_sidebarโ Increase sidebar width. (C-f)decrease_sidebarโ Decrease sidebar width. (C-d)next_entryโ When reading a mail item, change focus to the next entry according to the current sorting. (C-n)previous_entryโ When reading a mail item, change focus to the previous entry according to the current sorting. (C-p)toggle_menu_visibilityโ Toggle visibility of the side menu in the mail list. (`)focus_leftโ Switch focus to the left. (Left)focus_rightโ Switch focus to the right. (Right)exit_entryโ Exit e-mail entry. (i)open_entryโ Open e-mail entry. (Enter)
pager
page_downโ Go to next page. (PageDown)page_upโ Go to previous page. (PageUp)scroll_downโ Scroll down the pager. (j)scroll_upโ Scroll up the pager. (k)select_filterโ Select content filter. (f) See alsonamed_filterssetting.
contact-list
scroll_upโ Scroll up the list. (k)scroll_downโ Scroll down the list. (j)create_contactโ Create a new contact. (c)edit_contactโ Edit the contact under the cursor. (e)export_contactโ Export the contact under the cursor to.vcf. (E)delete_contactโ Delete the contact under the cursor. (d)mail_contactโ Mail the contact under the cursor. (m)next_accountโ Go to next account. (H)prev_accountโ Go to previous account. (L)toggle_menu_visibilityโ Toggle visibility of the side menu in the mail list. (`)
composing
editโ Edit mail. (e)send_mailโ Deliver draft to mailer. (s)scroll_upโ Change field focus. (k)scroll_downโ Change field focus. (j)
envelope-view
To select an attachment, type its index (you will see the typed result in the command buffer on the bottom right of the status line), then issue the corresponding command.
add_addresses_to_contactsโ Select addresses from the envelope to add to contacts. (c)editโ Open envelope in the composer. (e)go_to_urlโ Go to the url of the given index (with the commandurl_launchersetting in the โPAGERโ section). (g)open_attachmentโ Opens the selected attachment withxdg-open. (a)open_mailcapโ Opens the selected attachment according to its mailcap entry. Seemeli(1)FILES for the mailcap file locations. (m)open_htmlโ Opens the html attachment in the default browser. (v)replyโ Reply to envelope. (R)reply_to_authorโ Reply to author. (C-r)reply_to_allโ Reply to all/Reply to list/Follow up. (C-g)forwardโ Forward email. (C-f)return_to_normal_viewโ Return to envelope if viewing raw source or attachment. (r)toggle_expand_headersโ Expand extra headers (References and others). (h)toggle_url_modeโ Toggles url open mode. When active, it prepends an index next to each url that you can select by typing the index and open by issuinggo_to_url. (u)view_raw_sourceโ View raw envelope source in a pager. (M-r)change_charsetโ Force attachment charset for decoding. (d)
thread-view
scroll_upโ Scroll up the list. (k)scroll_downโ Scroll down the list. (j)collapse_subtreeโ Collapse thread branches. (h)next_pageโ Go to next page. (PageDown)prev_pageโ Go to previous page. (PageUp)reverse_thread_orderโ Reverse thread order. (C-r)toggle_mailviewโ Toggle mail view visibility. (p)toggle_threadviewโ Toggle thread view visibility. (t)toggle_layoutโ Toggle between horizontal and vertical layout. (Space)
๐ NOTIFICATIONS ๐
โจ System notifications โจ
okay so meli(1) can display notifications for asynchronous, out-of-band events that happen. These events can be any event of interest that is not a direct result of the user's interaction with the user interface, like for example receiving a new e-mail, or an SMTP server accepting an e-mail for delivery, or a backend watch mechanism error. The used notification mechanism is dbus if it is available on your system and if meli(1) has been compiled with support for it (check output of compiled-with CLI subcommand). Otherwise the fallback mechanism is calling a script to display a notification. If script is defined in your configuration, this mechanism will be preferred even if dbus is available.
On macos, without a script configured, meli(1) calls the osascript binary to display notifications:
osascript -e 'display_notification "<MESSAGE>" with title "<TITLE>" subtitle "<SUBTITLE>"'
You can override the script setting with variations of this command for customization.
๐ UI notifications ๐
Information that is in response to user interface actions should be instead shown within the user interface as floating message boxes. If you don't want UI notifications to be displayed, you can set the ui_notifications option to hide to hide them, or system to display them as system notifications.
Even when UI notifications are not displayed, you can still browse through them manually using shortcuts.general.info_message_next and shortcuts.general.info_message_previous shortcuts. iykyk ๐
๐ Notification configuration settings ๐
Default values are shown in parentheses.
enableboolean โ (optional) Enable notifications. Default:true.scriptString โ (optional) Script to pass notifications to, with title as 1st arg and body as 2nd. Default:none.new_mail_scriptString โ (optional) A command to pipe new mail notifications through (preferred overscript), with title as 1st arg and body as 2nd. Default:none.xbiff_file_pathString โ (optional) File that gets its size updated when new mail arrives. Default:none.play_soundboolean โ (optional) Play theme sound in notifications if possible. Default:false.sound_fileString โ (optional) Play sound file in notifications if possible. Default:none.ui_notificationsUINotifications โ (optional) How to handle UI notifications. Default:show. Valid values:showโ Always show.hideโ Hide from UI.systemโ Show them as system notifications.
๐ PAGER ๐
๐ธ Pager (viewing text) configuration settings ๐ธ
Default values are shown in parentheses.
sticky_headersboolean โ (optional) Always show headers when scrolling. Default:false.html_filterString โ (optional) Pipe html attachments through this filter before display. Default:none.html_openString โ (optional) A command to open html files. Default:none.filterString โ (optional) A command to pipe mail output through for viewing in pager.named_filtersString[String] โ (optional) Named filter commands to use at will. Default:empty.
Show menu with an empty filter command. Example:
[pager]
named_filters = { diff = "pygmentize -l diff -f 256", par = "par 72" }
format_flowedboolean โ (optional) Respectformat=flowed. Default:true.split_long_linesboolean โ (optional) Split long lines that would overflow on the x axis. Default:true.minimum_widthnum โ (optional) Minimum text width in columns. Default:80.auto_choose_multipart_alternativeboolean โ (optional) Choosetext/htmlalternative iftext/plainis empty inmultipart/alternativeattachments. Default:true.show_date_in_my_timezoneboolean โ (optional) ShowDate:in local timezone. Default:true.url_launcherString โ (optional) A command to launch URLs with. The URL will be given as the first argument of the command. Default:xdg-open.show_extra_headers[String] โ (optional) Extra headers to display, if present, in the default header preamble of the pager. Default:empty.
This setting is useful especially when used per-folder or per-account. For example, if you use rss2email (See r2e(1)) the e-mail you will receive will have the X-RSS-Feed header by default. You can show them only in the folder where you keep your feed items:
[accounts."personal".mailboxes]
INBOX = {}
"INBOX/Sent" = { sort_order=0 }
"INBOX/Feeds" = { pager.show_extra_headers = ["X-RSS-Feed"] }
๐๏ธ LISTING
ok so this whole section is about Listing โ aka the actual list of e-mail entries chillin' in a mailbox. This is the main character of your screen fr fr. Default values are in parentheses, bestie, don't forget.
show_menu_scrollbarboolean โ (optional) show an auto-hiding scrollbar in the accounts sidebar menu. (true)datetime_fmtString โ (optional) datetime formatting, passed verbatim tostrftime(3). (%Y-%m-%d %T)recent_datesBoolean โ (optional) show recent dates like 'X {minutes,hours,days} ago', but only up to 7 days. (true)filterQuery โ (optional) show only envelopes matching this query. (For query syntax, go peek atmeli(1)QUERY ABNF SYNTAX.) (None)
Example:
filter = "not flags:seen" # show only unseen messages
index_styleString โ sets the way mailboxes are displayed. โจconversationsโ shows one entry per threadcompactโ shows one row per threadthreadedโ shows threads as a tree structureplainโ shows one row per mail, regardless of threading
sidebar_mailbox_tree_has_siblingString โ (optional) sets the string to print in the mailbox tree for a level where its root has a sibling. (See the example below for a clear explanation and examples. ๐)sidebar_mailbox_tree_no_siblingString โ (optional) sets the string to print in the mailbox tree for a level where its root has no sibling.sidebar_mailbox_tree_has_sibling_leafString โ (optional) sets the string to print in the mailbox tree for a leaf level where its root has a sibling.sidebar_mailbox_tree_no_sibling_leafString โ (optional) sets the string to print in the mailbox tree for a leaf level where its root has no sibling.sidebar_dividerchar โ (optional) sets the character to print as the divider between the accounts list and the message list.sidebar_ratioInteger โ (optional) this is the width of the right container to the entire screen width. (90)unseen_flagOption<String> โ flag to show if a thread entry contains unseen mail. (โ)thread_snoozed_flagOption<String> โ flag to show if a thread has been snoozed. ("๐ค\u{FE0E}") [Rendered as:r##"๐ค"##]selected_flagOption<String> โ flag to show if a thread entry has been selected. ("โ \u{2007}") [Rendered as:r##"โ "##]attachment_flagOption<String> โ flag to show if a thread entry contains attachments. ("๐\u{FE0E}") [Rendered as:r##"๐"##]highlight_self_flagOption<String> โ flag to show if any thread entry contains your address as a receiver. Super useful for making mailing-list threads that CC you stand out. (โธ)highlight_selfboolean โ showhighlight_self_flagor not. (false)thread_subject_packboolean โ should threads with differentiating Subjects show a list of those subjects on the entry title? (true)threaded_repeat_identical_from_valuesboolean โ in threaded listing style, repeat identical From column values within a thread. Not repeating adds empty space in the From column, which might result in less visual clutter. (false)relative_menu_indicesboolean โ show relative indices in menu mailboxes to quickly help with jumping to them. (true)relative_list_indicesboolean โ show relative indices in listings to quickly help with jumping to them. (true)hide_sidebar_on_launchboolean โ start the app with the sidebar hidden. (false)mail_view_dividerchar โ character to show in the divider space between mail view and listing. (' ')thread_layoutโauto | vertical | horizontal. Force a specific layout in thread view. You can also toggle the layout at runtime with thelisting.toggle_layoutshortcut. (auto)
๐ธ Examples of sidebar mailbox tree customization
The default values, bestie:
has_sibling = " "
no_sibling = " ";
has_sibling_leaf = " "
no_sibling_leaf = " "
and that renders a mailbox tree like this:
0 Inbox 3
1 Archive
2 Drafts
3 Lists
4 example-list-a
5 example-list-b
6 Sent
7 Spam
8 Trash
Other possible trees ๐ฆ:
has_sibling = " โ"
no_sibling = " "
has_sibling_leaf = " โฃโ"
no_sibling_leaf = " โโ"
0 Inbox 3
1 โฃโArchive
2 โฃโDrafts
3 โฃโLists
4 โ โฃโexample-list-a
5 โ โโexample-list-b
6 โฃโSent
7 โฃโSpam
8 โโTrash
And a completely ASCII one, for the purists ๐ :
has_sibling = " |"
no_sibling = " "
has_sibling_leaf = " |\_"
no_sibling_leaf = " \_"
0 Inbox 3
1 |\_Archive
2 |\_Drafts
3 |\_Lists
4 | |\_example-list-a
5 | \_example-list-b
6 |\_Sent
7 |\_Spam
8 \_Trash
๐ท๏ธ TAGS
ok so Tags = e-mail metadata, but only in backends that actually support them, no cap. Default values are in parentheses, as always. ๐
colours hash tableString[Color] โ (optional) set UI colors for tagsignore_tagsArray String โ (optional) hide tags (not the tagged messages themselves ๐)
Example:
[tags]
# valid inputs: #HHHHHH, #ABC -> #AABBCC, XTERM_NAME, 0-255 byte
colors = { signed="#Ff6600", replied="DeepSkyBlue4", draft="#f00", replied="8" }
[accounts.dummy]
...
[accounts.dummy.mailboxes]
# per mailbox override:
"INBOX" = { tags.ignore_tags=["inbox", ] }
๐ PGP ๐
okay bestie, this is where you tell meli how to handle your โจsecret agentโจ mail. defaults are chillin' in parentheses, as always.
auto_verify_signaturesboolean โ auto-verify signed e-mail according to RFC3156 (true). she checks the vibes (and the crypto) for you ๐auto_decryptboolean โ (optional) always decrypt encrypted e-mail (true). no cap, it just does it ๐auto_signboolean โ (optional) always sign sent messages (false). main character energy requires a signature, but she won't do it unless you say so โ๏ธauto_encryptboolean โ (optional) always encrypt sent messages (false)sign_keyString โ (optional) ID of key to be used for signatures (none)decrypt_keyString โ (optional) ID of key to be used for decryption (none)encrypt_keyString โ (optional) ID of key to be used for encryption (none)auto_remote_lookupboolean โ (optional) allow remote lookups (false). say yes and she'll go hunting for keys across the internet ๐ต๏ธโโ๏ธremote_lookup_mechanismsLocateKey โ (optional) remote lookup mechanisms. use a comma to separate values. (Local,WKD)
possible mechanisms:
certpkadanewkdldapkeyserverkeyserver-urllocal
๐ TERMINAL ๐
๐ Note about emojis and other multi-width characters in string values ๐
some unicode combining marks are lowkey iconic (they're invisible little characters that change how the visible character before them shows up). here are the useful ones:
\u{FE0E}โ Emoji variation sequence select 15: renders an emoji as text style (monochrome)\u{FE0F}โ Emoji variation sequence select 16: renders an emoji in color\u{2007}โ Figure space, a space character with the width of a digit in a monospace typeface
โจ Terminal configuration settings โจ
defaults live in parentheses, you know the drill ๐
themeString โ (optional) theme name to use. (dark)tab_widthu8 โ how many cells a tab character occupies. (4)ascii_drawingboolean โ (optional) if true, box drawing will be done with ASCII characters. (false)use_colorboolean โ (optional) if false, no ANSI colors are used. (true)force_text_presentationboolean โ (optional) if true, text presentations of color symbols and emoji will be enforced as much as possible. might not work on all non-text symbols and is experimental. (false)window_titleString โ (optional) set window title in xterm compatible terminals. an empty string means no window title is set. (meli)file_picker_commandString โ (optional) set command that prints file paths in stdout, separated by NUL bytes. used withadd-attachment-file-pickerwhen composing new mail. (None)themeshash table String[String[Attribute]] โ define UI themes. seemeli-themes(5)for details.
[terminal]
theme = "themeB"
[terminal.themes.themeA]
"mail.view.body" = {fg = "HotPink3", bg = "LightSalmon1"}
...
[terminal.themes.themeB]
"mail.view.body" = {fg = "CadetBlue", bg = "White"}
...
[terminal.themes.themeC]
...
use_mouseboolean โ use mouse events. this will disable text selection, but you will be able to resize some widgets. this setting can be toggled withtoggle mouse. (false)
bestie. read that again. mouse mode = no text selection. choose wisely ๐
mouse_flagString โ string to show in status bar if mouse is active. (๐ฑ)progress_spinner_sequenceEither < Integer, ProgressSpinner > โ choose between 37 built in sequences (integers between0-36) or define your own list of strings for the progress spinner animation. set to an empty array to disable the progress spinner. (20)
built-in sequences are:
0 ["-", "\", "|", "/"]
1 ["โ", "โ", "โ", "โ", "โ
", "โ", "โ", "โ"]
2 ["โฃ", "โฃ", "โฃค", "โฃฆ", "โฃถ", "โฃท", "โฃฟ"]
3 ["โฃ", "โฃ", "โฃ", "โฃ", "โฃง", "โฃท", "โฃฟ"]
4 ["โ", "โ", "โ", "โ", "โฌค"]
5 ["โก", "โฑ", "โง", "โฃ", "โ "]
6 ["โก", "โฑ", "โจ", "โฉ", "โ "]
7 ["โก", "โฑ", "โฅ", "โฆ", "โ "]
8 ["โ", "โ", "โ", "โ"]
9 ["โ", "โ"]
10 ["โฌ", "โฌ"]
11 ["โฑ", "โฐ"]
12 ["โญ", "โผ"]
13 ["โฏ", "โฎ"]
14 ["โฏ", "โฌค"]
15 ["โช", "โซ"]
16 ["โ", "โ", "โ", "โ", "โ", "โ", "โ", "โ", "โ", "โ"]
17 ["|", "/", "-", "\"]
18 [".", "o", "O", "@", "*"]
19 ["โกโก", "โโ", "โ โ ", "โโ"]
20 ["โ ", " โ", " โ", "โ "]
21 ["โ", "โ", "โ", "โ", "โ", "โ", "โ", "โ"]
22 ["โ", "โ", "โ", "โ
", "โ", "โ", "โ", "โ", "โ", "โ
", "โ", "โ"]
23 [ "โ", "โ", "โ", "โ", "โ", "โ", "โ", "โ", "โ", "โ", "โ", "โ", "โ" ]
24 ["โ", "โ", "โ", "โ"]
25 ["โ", "โ", "โ", "โ"]
26 ["โค", "โ", "โด", "โ", "โ", "โ", "โฌ", "โ"]
27 ["โข", "โฃ", "โค", "โฅ"]
28 ["โ ", "โ ", "โ ", "โก", "โข", "โ ", "โ ", "โ "]
29 ["โขโกฐ", "โขโกก", "โขโก", "โขโ ฑ", "โ โกฑ", "โขโกฑ", "โขโกฑ", "โขโกฑ"]
30 [".", "o", "O", "ยฐ", "O", "o", "."]
31 ["ใ", "ใ", "ใ"]
32 ["๐ ", "๐ ", "๐ ", "๐ ", "โค๏ธ "]
33 [ "๐ ", "๐ ", "๐ ", "๐ ", "๐ ", "๐ ", "๐ ", "๐ ", "๐ ", "๐ ", "๐ ", "๐ " ]
34 ["๐ ", "๐ ", "๐ "]
35 [ "[ ]", "[= ]", "[== ]", "[=== ]", "[ ===]", "[ ==]", "[ =]", "[ ]", "[ =]", "[ ==]", "[ ===]", "[====]", "[=== ]", "[== ]", "[= ]" ]
36 ["๐ ", "๐ ", "๐ ", "๐ ", "๐ ", "๐ ", "๐ ", "๐ "]
or, define an array of strings each consisting of a frame in the progress sequence indicator for a custom spinner:
interval_msu64 โ (optional) frame interval. (50)frames[String] โ the animation frames.
example:
progress_spinner_sequence = { interval_ms = 150, frames = [ "-", "=", "โก" ] }
spinner 32 through 36? absolutely ate. 32 is giving heart-eyes every single frame ๐๐๐๐โค๏ธ
๐ LOG ๐
Logging configuration settings
Default values are shown in parentheses. As always, bestie ๐
log_fileString โ (optional) where your log file lives. Default is($XDG_DATA_HOME/meli/meli.log). Yes she keeps receipts ๐maximum_levelString โ (optional) the max level of messages to log. Every level less than or equal tomaximum_levelgets appended to the log file. The available levels are, in partial order:OFFERRORWARNINFODEBUGTRACE
Which means: to turn logging off, set maximum_level to OFF. Default is (INFO).
ngl the "partial order" thing is doing a lot of work here but it just means higher levels include all the chattier stuff below them, okay? ๐ซถ
๐ SMTP Connections ๐
SMTP configuration settings
Default values are shown in parentheses. It's giving "let me send this email for you" energy fr fr โจ
hostnameString โ server hostname.portInteger โ server port.envelope_fromString โ (optional) the address to set as sender in SMTP transactions. Default:(none).authSmtpAuth โ SMTP server authentication. Go read the โSmtpAuthโ subsection, she's iconic ๐securitySmtpSecurity โ (optional) gpg binary name or file location to use. (see โSmtpSecurityโ subsection). Yeah, that's literally what the page says, I'm not making this up ๐ no cap.extensionsSmtpExtensions โ (optional) set support for SMTP extensions if they're advertised by the server. (see โSmtpExtensionsโ subsection).
SmtpAuth
type none | auto | xoauth2
For type "auto":
usernameStringpasswordSmtpPasswordrequire_authboolean โ (optional) require authentication in every case. Default(true).
For type "xoauth2":
token_commandString โ Command to evaluate that returns an XOAUTH2 token.require_authboolean โ (optional) require authentication in every case. Default(true).
Examples, copy them exactly bestie, don't freestyle ๐:
auth = { type = "auto", username = "user", password = { type = "raw", value = "hunter2" } }
auth = { type = "auto", username = "user", password = "hunter2" }
auth = { type = "none" }
For Gmail (peep โGmail OAUTH2โ for the details on the authentication token command):
auth = { type = "xoauth2", token_command = "TOKEN=$(python3 oauth2.py --user=xxx@gmail.com --quiet --client_id=1038[...].apps.googleusercontent.com --client_secret=[..] --refresh_token=[..] && python3 oauth2.py --user=xxx@gmail.com --generate_oauth2_string --quiet --access_token=$TOKEN" }
SmtpPassword
type raw | command_evaluation
valueString โ Either a raw password string, or command to execute.
Examples:
password = { type = "raw", value = "hunter2" }
password = { type = "command_eval", value = "gpg2 --no-tty -q -d ~/.passwords/user.gpg" }
๐ฅ pro move honestly, piping your password through gpg2 instead of pasting it everywhere.
SmtpSecurity
Default security type is auto. ๐
type none | auto | starttls | tls
danger_accept_invalid_certsboolean โ Accept invalid SSL / TLS certificates. Default(false).
๐จ bestie the word danger is RIGHT THERE in the option name. Turning this on means accepting certs that did not pass the vibe check. Do it only if you know exactly why, okay? ๐ญ
SmtpExtensions
pipeliningboolean โ RFC2920. Default(true).chunkingboolean โ RFC3030. Default(true).prdrboolean โ draft-hall-prdr-00. Default(true).dsn_notifyString โ RFC3461. Default(FAILURE).
๐ SEE ALSO ๐
๐ STANDARDS ๐
TOML Standard v.0.5.0 https://toml.io/en/v0.5.0
๐ซถ AUTHORS ๐ซถ
Copyright 2017โ2024 Manos Pitsidianakis <manos@pitsidianak.is>
Released under the GPL, version 3 or greater. This software carries no warranty of any kind. (See COPYING for full copyright and warranty notices.)
๐ Links ๐
- Website: https://meli-email.org
- Main git repository and issue tracker: https://git.meli-email.org/meli/meli
- Official read-only git mirror on codeberg.org: https://codeberg.org/meli/meli
- Official read-only git mirror on github.com: https://github.com/meli/meli
- meli crate on crates.io: https://crates.io/crates/meli
And that's a wrap on MELI.CONF(5), bestie!! ๐โจ This page is from the Debian section of the manual, dated May 20, 2024, and it's literally the MELI.CONF(5) man page โ go configure something slay, you got this ๐๐ฆ๐ธ
๐ฆ where this page comes from
- alpine 3.24: meli-doc 0.8.13-r0 ยท GPL-3.0-or-later
- nixos 26.05: meli 0.8.13
- nixpkgs unstable: meli 0.8.13
- ubuntu resolute: meli 0.8.13+dfsg-3 ยท GPL-3.0-or-later
- ubuntu stonking: meli 0.8.13+dfsg-4build1 ยท GPL-3.0-or-later
- Copyright 2017-2019 Manos Pitsidianakis
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms