# My aerc setup Recently I was almost ready to look into installing and setting up [neomutt](https://github.com/neomutt/neomutt) when I randomly discovered [aerc](https://git.sr.ht/~rjarry/aerc) an email client for your terminal whilst browsing the www as you do. After reading up on it I soon realised that several of my online friends also used aerc having once used mutt / neomutt so decided to give it a go first and to be honest I really really love it! I'll try to document how I have set it up on my Arch system but please be warned it's still a **work in progress** and you may well give me a few pointers too. This is an offline setup that I have so I can read and write emails even when I'm offline and they will be queued for sending once I'm back online. **Please note that I use Gmail for my email at the moment so that's what I have configured but you could easily adapt this to suit if you follow the documentation for the various pieces of software** ## First the packages I have installed to setup aerc ### aerc: [aerc-git](https://aur.archlinux.org/packages/aerc-git) [dante](https://archlinux.org/packages/extra/x86_64/dante/) [w3m](https://archlinux.org/packages/extra/x86_64/w3m/) ### SMTP: [msmtp-git](https://aur.archlinux.org/packages/msmtp-git) The scripts `msmtp-enqueue.sh`, `msmtp-runqueue.sh` and `msmtp-listqueue.sh` are located in `/usr/share/doc/msmtp/msmtpqueue/` and can be copied into your `~/.local/bin/` folder. ### IMAP MailDir mailbox sync: [isync-git](https://aur.archlinux.org/packages/isync-git) ### Passwords: [pass](https://archlinux.org/packages/extra/any/pass/) I use pass to securely store and retreive my passwords ## Then the config files which are a WIP You will have to replace `your full name` and obviously your email address where I've used as an example `your@gmail.com` It is also noted that in the `accounts.conf` file below I use aerc to check and send anything in the mail queue every 5 minutes using the line `check-mail-cmd = mbsync -q gmail && msmtp-runqueue.sh`. Although I have thought that maybe I should reverse that so it sends first and then checks for new mail ? `~/.config/aerc/accounts.conf` ``` [gmail] source = maildir://~/.mail outgoing = msmtp-enqueue.sh --read-envelope-from default = INBOX folders-exclude = [Gmail] from = your full name copy-to = gmail/[Gmail]/Sent Mail check-mail-cmd = mbsync -q gmail && msmtp-runqueue.sh check-mail = 5m check-mail-timeout = 10s ``` In the `aerc.conf` file below I have made a few changes for layout and especially the timestamp so that it's in a format suited to myself. I've also changed the theme to my favourite gruvbox which will more than likely get updated from time to time as I improve on my setup. `~/.config/aerc/aerc.conf` ``` # # aerc main configuration [general] # # Used as a default path for save operations if no other path is specified. # ~ is expanded to the current user home dir. # #default-save-path= # If set to "gpg", aerc will use system gpg binary and keystore for all crypto # operations. If set to "internal", the internal openpgp keyring will be used. # If set to "auto", the system gpg will be preferred unless the internal # keyring already exists, in which case the latter will be used. # # Default: auto #pgp-provider=auto # 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 #unsafe-accounts-conf=false # Output log messages to 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-file=~/aerc.log # 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 #log-level=info # Set the $TERM environment variable used for the embedded terminal. # # Default: xterm-256color #term=xterm-256color # Display OSC8 strings in the embedded terminal # # Default: false #enable-osc8=false [ui] # # 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. # # Default: date<20,name<17,flags>4,subject<* #index-columns=date<20,name<17,flags>4,subject<* # # Each name in index-columns must have a corresponding column-$name setting. # All column-$name settings accept golang text/template syntax. See # aerc-templates(7) for available template attributes and functions. # # Default settings #column-date={{.DateAutoFormat .Date.Local}} #column-name={{index (.From | names) 0}} #column-flags={{.Flags | join ""}} #column-subject={{.ThreadPrefix}}{{.Subject}} # # String separator inserted between columns. When the 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 the column contents). # # Default: " " #column-separator=" " # # See time.Time#Format at https://godoc.org/time#Time.Format # # Default: 2006-01-02 03:04 PM (ISO 8601 + 12 hour time) #timestamp-format=2006-01-02 03:04 PM timestamp-format=Mon 2 Jan 15:04 2006 # # Index-only time format for messages that were received/sent today. # If this is not specified, timestamp-format is used instead. # #this-day-time-format= # # Index-only time format for messages that were received/sent within the last # 7 days. If this is not specified, timestamp-format is used instead. # #this-week-time-format= # # Index-only time format for messages that were received/sent this year. # If this is not specified, timestamp-format is used instead. # #this-year-time-format= # # Width of the sidebar, including the border. # # Default: 20 sidebar-width=30 # # Message to display when viewing an empty folder. # # Default: (no messages) #empty-message=(no messages) # Message to display when no folders exists or are all filtered # # Default: (no folders) #empty-dirlist=(no folders) # Enable mouse events in the ui, e.g. clicking and scrolling with the mousewheel # # Default: false #mouse-enabled=false # # Ring the bell when new messages are received # # Default: true #new-message-bell=true # # Template to use for Account tab titles # # Default: {{.Account}} #tab-title-account={{.Account}} # Marker to show before a pinned tab's name. # # Default: ` #pinned-tab-marker='`' # Template for the left side of the directory list. # See aerc-templates(7) for all available fields and functions. # # Default: {{.Folder}} #dirlist-left={{.Folder}} # Template for the right side of the directory list. # See aerc-templates(7) for all available fields and functions. # # Default: {{if .Unread}}{{humanReadable .Unread}}/{{end}}{{if .Exists}}{{humanReadable .Exists}}{{end}} #dirlist-right={{if .Unread}}{{humanReadable .Unread}}/{{end}}{{if .Exists}}{{humanReadable .Exists}}{{end}} # Delay after which the messages are actually listed when entering a directory. # This avoids loading messages when skipping over folders and makes the UI more # responsive. If you do not want that, set it to 0s. # # Default: 200ms #dirlist-delay=200ms # Display the directory list as a foldable tree that allows to collapse and # expand the folders. # # Default: false #dirlist-tree=false # If dirlist-tree is enabled, set level at which folders are collapsed by # default. Set to 0 to disable. # # Default: 0 #dirlist-collapse=0 # List of space-separated criteria to sort the messages by, see *sort* # command in *aerc*(1) for reference. Prefixing a criterion with "-r " # reverses that criterion. # # Example: "from -r date" # #sort= # Moves to next message when the current message is deleted # # Default: true #next-message-on-delete=true # Automatically set the "seen" flag when a message is opened in the message # viewer. # # Default: true #auto-mark-read=true # The directories where the stylesets are stored. It takes a colon-separated # list of directories. If this is unset or if a styleset cannot be found, the # following paths will be used as a fallback in that order: # # ${XDG_CONFIG_HOME:-~/.config}/aerc/stylesets # ${XDG_DATA_HOME:-~/.local/share}/aerc/stylesets # /usr/local/share/aerc/stylesets # /usr/share/aerc/stylesets # #stylesets-dirs= # Uncomment to use box-drawing characters for vertical and horizontal borders. # # Default: " " #border-char-vertical=" " #border-char-horizontal=" " # Sets the styleset to use for the aerc ui elements. # # Default: default styleset-name=gruvbox # Activates fuzzy search in commands and their arguments: the typed string is # searched in the command or option in any position, and need not be # consecutive characters in the command or option. # # Default: false #fuzzy-complete=false # How long to wait after the last input before auto-completion is triggered. # # Default: 250ms #completion-delay=250ms # The minimum required characters to allow auto-completion to be triggered after # completion-delay. # # Default: 1 #completion-min-chars=1 # # Global switch for completion popovers # # Default: true #completion-popovers=true # Uncomment to use UTF-8 symbols to indicate PGP status of messages # # Default: ASCII #icon-unencrypted= #icon-encrypted=✔ #icon-signed=✔ #icon-signed-encrypted=✔ #icon-unknown=✘ #icon-invalid=⚠ # Reverses the order of the message list. By default, the message list is # ordered with the newest (highest UID) message on top. Reversing the order # will put the oldest (lowest UID) message on top. This can be useful in cases # where the backend does not support sorting. # # Default: false #reverse-msglist-order = false # Reverse display of the mesage threads. Default order is the the intial # message is on the top with all the replies being displayed below. The # reverse option will put the initial message at the bottom with the # replies on top. # # Default: false #reverse-thread-order=false # Sort the thread siblings according to the sort criteria for the messages. If # sort-thread-siblings is false, the thread siblings will be sorted based on # the message UID in ascending order. This option is only applicable for # client-side threading with a backend that enables sorting. Note that there's # a performance impact when sorting is activated. # # Default: false #sort-thread-siblings=false #[ui:account=foo] # # Enable a threaded view of messages. If this is not supported by the backend # (IMAP server or notmuch), threads will be built by the client. # # Default: false threading-enabled=true # Force client-side thread building # # Default: false #force-client-threads=false # Debounce client-side thread building # # Default: 50ms #client-threads-delay=50ms [statusline] # # Describes the format for the status line. This is a comma separated list of # column names with an optional align and width suffix. See [ui].index-columns # for more details. To completely mute the status line except for push # notifications, explicitly set status-columns to an empty string. # # Default: left<*,center:=,right>* #status-columns=left<*,center:=,right>* # # Each name in status-columns must have a corresponding column-$name setting. # All column-$name settings accept golang text/template syntax. See # aerc-templates(7) for available template attributes and functions. # # Default settings #column-left=[{{.Account}}] {{.StatusInfo}} #column-center={{.PendingKeys}} #column-right={{.TrayInfo}} # # String separator inserted between columns. # See [ui].column-separator for more details. # #column-separator=" " # Specifies the separator between grouped statusline elements. # # Default: " | " #separator=" | " # Defines the mode for displaying the status elements. # Options: text, icon # # Default: text #display-mode=text [viewer] # # Specifies the pager to use when displaying emails. Note that some filters # may add ANSI codes to add color to rendered emails, so you may want to use a # pager which supports ANSI codes. # # Default: less -R #pager=less -R pager=bat --plain --tabs 4 --paging always --color always # # 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. # # Default: text/plain,text/html alternatives=text/plain,text/html # # Default setting to determine whether to show full headers or only parsed # ones in message viewer. # # Default: false #show-headers=false # # Layout of headers 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. # # Default: From|To,Cc|Bcc,Date,Subject #header-layout=From|To,Cc|Bcc,Date,Subject # Whether to always show the mimetype of an email, even when it is just a single part # # Default: false #always-show-mime=false # Parses and extracts http links when viewing a message. Links can then be # accessed with the open-link command. # # Default: true parse-http-links=true [compose] # # Specifies the command to run the editor with. It will be shown in an embedded # terminal, though it may also launch a graphical window if the environment # supports it. Defaults to $EDITOR, or vi. #editor= # # Default header fields to display when composing a message. To display # multiple headers in the same row, separate them with a pipe, e.g. "To|From". # # Default: To|From,Subject #header-layout=To|From,Subject # # Specifies the command to be used to tab-complete email addresses. Any # occurrence of "%s" in the address-book-cmd will be replaced with what the # user has typed so far. # # The command must output the completions to standard output, one completion # per line. Each line must be tab-delimited, with an email address occurring as # the first field. Only the email address field is required. The second field, # if present, will be treated as the contact name. Additional fields are # ignored. # # This parameter can also be set per account in accounts.conf. #address-book-cmd= # Specifies the command to be used to select attachments. Any occurence of '%s' # in the file-picker-cmd will be replaced the argument to :attach -m # . # # The command must output the selected files to standard output, one file per # line. #file-picker-cmd= # # Allow to address yourself when replying # # Default: true #reply-to-self=true # # Warn before sending an email that matches the specified regexp but does not # have any attachments. Leave empty to disable this feature. # # Uses Go's regexp syntax, documented at https://golang.org/s/re2syntax. The # "(?im)" flags are set by default (case-insensitive and multi-line). # # Example: # no-attachment-warning=^[^>]*attach(ed|ment) # #no-attachment-warning= # # When set, aerc will generate "format=flowed" bodies with a content type of # "text/plain; format=flowed" as described in RFC3676. This format is easier to # handle for some mailing software, and generally just looks like ordinary # text. To actually make use of this format's features, you'll need support in # your editor. # #format-flowed=false [multipart-converters] # # Converters allow to generate multipart/alternative messages by converting the # main text/plain part into any other MIME type. Only exact MIME types are # accepted. The commands are invoked with sh -c and are expected to output # valid UTF-8 text. # # Example (obviously, this requires that you write your main text/plain body # using the markdown syntax): #text/html=pandoc -f markdown -t html --standalone [filters] # # Filters allow you to pipe an email body through a shell command to render # certain emails differently, e.g. highlighting them with ANSI escape codes. # # The commands are invoked with sh -c. The following folders are appended to # the system $PATH to allow referencing filters from their name only: # # ${XDG_CONFIG_HOME:-~/.config}/aerc/filters # ${XDG_DATA_HOME:-~/.local/share}/aerc/filters # $PREFIX/share/aerc/filters # /usr/share/aerc/filters # # 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 # AERC_FILENAME the attachment filename (if any) # AERC_SUBJECT the message Subject header value # AERC_FROM the message From header value # # The first filter which matches the email's mimetype will be used, so order # them from most to least specific. # # You can also match on non-mimetypes, 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. # text/plain=colorize text/calendar=calendar message/delivery-status=colorize message/rfc822=colorize #text/html=pandoc -f html -t plain | colorize #text/html=html | colorize text/html=w3m -T text/html -cols $(tput cols) -dump -o display_image=false -o display_link_number=true #text/*=bat -fP --file-name="$AERC_FILENAME" #application/x-sh=bat -fP -l sh #image/*=catimg -w $(tput cols) - image/*=img2sixel #subject,~Git(hub|lab)=lolcat -f #from,thatguywhodoesnothardwraphismessages=wrap -w 100 | colorize # This special filter is only used to post-process email headers when # [viewer].show-headers=true # By default, headers are piped directly into the pager. # .headers=colorize [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/. # # {} is expanded as the temporary filename to be opened. If it is not # encountered in the command, the temporary filename will be appened to the end # of the command. # # 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. # # Examples: # x-scheme-handler/irc=hexchat # x-scheme-handler/http*=firefox # text/html=surf -dfgms # text/plain=gvim {} +125 # message/rfc822=thunderbird text/html=qutebrowser application/x-pdf=zathura application/pdf=zathura application/octet-stream=zathura image/*=imv image/png=imv image/jpg=imv video/*=mpv audio/*=mpv --no-video text/*=vim [hooks] # # Hooks are triggered whenever the associated event occurs. # # Executed when a new email arrives in the selected folder #mail-received=notify-send "New mail from $AERC_FROM_NAME" "$AERC_SUBJECT" # # Executed when aerc starts #aerc-startup=aerc :terminal calcurse && aerc :next-tab # # Executed when aerc shuts down. #aerc-shutdown= [templates] # Templates are used to populate email bodies automatically. # # The directories where the templates are stored. It takes a colon-separated # list of directories. If this is unset or if a template cannot be found, the # following paths will be used as a fallback in that order: # # ${XDG_CONFIG_HOME:-~/.config}/aerc/templates # ${XDG_DATA_HOME:-~/.local/share}/aerc/templates # /usr/local/share/aerc/templates # /usr/share/aerc/templates # #template-dirs= # The default template to be used for new messages. # # default: new_message #new-message=new_message # The default template to be used for quoted replies. # # default: quoted_reply #quoted-reply=quoted_reply # The default template to be used for forward as body. # # default: forward_as_body #forwards=forward_as_body ``` `~/.config/aerc/binds.conf` ``` # Binds are of the form = # To use '=' in a key sequence, substitute it with "Eq": "" # If you wish to bind #, you can wrap the key sequence in quotes: "#" = quit = :prev-tab = :next-tab = :term ? = :help keys [messages] q = :quit j = :next = :next = :next 50% = :next 100% = :next 100% k = :prev = :prev = :prev 50% = :prev 100% = :prev 100% g = :select 0 G = :select -1 J = :next-folder K = :prev-folder H = :collapse-folder L = :expand-folder v = :mark -t V = :mark -v T = :toggle-threads = :view d = :prompt 'Really delete this message?' 'delete-message' D = :delete A = :archive flat C = :compose rr = :reply -a rq = :reply -aq Rr = :reply Rq = :reply -q c = :cf $ = :term ! = :term | = :pipe / = :search \ = :filter n = :next-result N = :prev-result = :clear [messages:folder=Drafts] = :recall [view] / = :toggle-key-passthrough/ q = :close O = :open S = :save | = :pipe D = :delete A = :archive flat = :open-link f = :forward rr = :reply -a rq = :reply -aq Rr = :reply Rq = :reply -q H = :toggle-headers = :prev-part = :next-part J = :next K = :prev [view::passthrough] $noinherit = true $ex = = :toggle-key-passthrough [compose] # Keybindings used when the embedded terminal is not selected in the compose # view $noinherit = true $ex = = :prev-field = :next-field = :switch-account -p = :switch-account -n = :next-field = :prev-field = :prev-tab = :next-tab [compose::editor] # Keybindings used when the embedded terminal is selected in the compose view $noinherit = true $ex = = :prev-field = :next-field = :prev-tab = :next-tab [compose::review] # Keybindings used when reviewing a message to be sent y = :send n = :abort v = :preview p = :postpone q = :choose -o d discard abort -o p postpone postpone e = :edit a = :attach d = :detach [terminal] $noinherit = true $ex = = :prev-tab = :next-tab [messages:account=gmail] d = :prompt 'Really move this message to the trash?' mv gmail/[Gmail]/Bin D = :mv gmail/[Gmail]/Bin [view:account=gmail] d = :prompt 'Really move this message to the trash?' mv gmail/[Gmail]/Bin D = :mv gmail/[Gmail]/Bin ``` `~/.config/aerc/stylesets/gruvbox` ``` # should work with any terminal colorscheme, but was designed for gruvbox # terminal colors are preferred, but hex is used for grayscale *.default=true # present in 'Send this email?' dialog title.fg=yellow title.bg=#303030 title.bold=true # used in setup and in 'From:' etc header.bold=true header.fg=purple # decorative lines border.fg=blue # requires attention *error.bold=true *error.fg=red *error.blink=true *warning.fg=yellow *warning.blink=true *success.fg=green # statusline statusline_default.fg=gray statusline_*.bg=#303030 # message list colors msglist_deleted.fg=gray msglist_unread.fg=#98971a msglist_unread.bold=true msglist_default.fg=#dedede msglist_marked.fg=yellow msglist_marked.reverse=true msglist_flagged.fg=white # msglist_flagged.bg=red msglist_flagged.bold=true # inbox etc dirlist_default.fg=#dedede dirlist_unread.fg=white dirlist_unread.bold=true # highlight selected item *.selected.bg=#303030 *.selected.fg=#fabd2f *.selected.bold=true # primarily used in account setup selector_default.fg=gray selector_chooser.bold=true selector_focused.bg=green selector_focused.bold=true # command completion completion_default.bg=#303030 completion_gutter.bg=#303030 completion_pill.bg=aqua #dynamic *msglist_answered.fg = #21771f [viewer] header.fg=#d845c5 header.bold=true signature.fg=3 signature.dim=true diff_meta.fg=#ff0000 diff_meta.bold=true diff_chunk.dim=true diff_add.fg=#00ff00 diff_del.fg=#ff0000 quote_1.fg=6 quote_2.fg=7 quote_3.fg=6 quote_4.fg=7 quote_3.dim=true quote_4.dim=true quote_x.fg=gray quote_x.dim=true ``` `~/.msmtprc` ``` IMAPStore gmail-remote Host imap.gmail.com AuthMechs LOGIN User youremail@gmail.com PassCmd "pass Email/your@gmail.com/app-password" TLSType IMAPS MaildirStore gmail-local Path ~/.mail/gmail/ Inbox ~/.mail/gmail/INBOX Subfolders Verbatim Channel gmail Far :gmail-remote: Near :gmail-local: Expunge Both Create Both Remove Both Patterns * !"[Gmail]/All Mail" !"[Gmail]/Important" !"[Gmail]/Starred" SyncState * ``` `~/.msmtprc` ``` defaults tls on account gmail auth on host smtp.gmail.com port 587 user your@gmail.com from your@gmail.com passwordeval "pass Email/your@gmail.com/app-password" account default: gmail ```