Welcome to Himalaya CLI, the Command-Line Interface to manage emails based on email-lib.
Disclaimer: the project is under active development, do not use in production before the final v1.0.0
.
Features
- Folder (aka mailbox) management
- Envelopes listing
- Message composition based on
$EDITOR
- Message manipulation (copy/move/delete)
- Multi-accounting
- Account synchronization for offline usage
- Support multiple backends: IMAP, Maildir, Notmuch, SMTP, Sendmail.
- PGP end-to-end encryption
- Generate man pages
- Generate completion scripts for various shells
- JSON output
- …and more! Get started now
Installation
# Arch Linux (official)
$ pacman -S himalaya
# Arch Linux (from sources)
$ yay -S himalaya-git
# Homebrew
$ brew install himalaya
# Scoop
$ scoop install himalaya
# Cargo
$ cargo install himalaya
# Nix
$ nix-env -i himalaya
# Fedora/CentOS
$ dnf copr enable atim/himalaya
$ dnf install himalaya
See the documentation for other installation methods.
Configuration
Please read the documentation.
Contributing
Please read the contributing guide for more detailed information.
A bug tracker is available on SourceHut. [send an email]
A mailing list is available on SourceHut. [send an email] [subscribe] [unsubscribe]
If you want to report a bug, please send an email at ~soywod/pimalaya@todo.sr.ht.
If you want to propose a feature or fix a bug, please send a patch at ~soywod/pimalaya@lists.sr.ht. The simplest way to send a patch is to use git send-email, follow this guide to configure git properly.
If you just want to discuss about the project, feel free to join the Matrix workspace #pimalaya.himalaya or contact me directly @soywod. You can also use the mailing list.
Sponsoring
Special thanks to the NLnet foundation and the European Commission that helped the project to receive financial support from:
- NGI Assure in 2022
- NGI Zero Entrust in 2023
If you appreciate the project, feel free to donate using one of the following providers:
GitHub Sponsors, PayPal, Ko-fi, Buy Me a Coffee, Liberapay
Quickstart
Installation
The fastest way to get started is to install the pre-built binary matching your system. You can manually download it from the GitHub releases section or let this script do the job for you:
$ curl -sSL https://pimalaya.org/himalaya/cli/install.sh | PREFIX=~/.local sh
See other installation methods.
Configuration
The wizard will create a configuration file for you, just follow the steps:
$ himalaya
Cannot find existing configuration at "~/.config/himalaya/config.toml".
Would you like to create one with the wizard? [Y/n]
See other configuration methods.
Basic usage
- An account is a set of options allowing users to connect to folders.
- A folder (aka mailbox) is an email container.
- An email is composed of an envelope and a message
- An envelope is a set of properties identifying a message.
- A message is composed of headers and a body, including attachments.
- An attachment is (usually) a binary content like an image, a PDF etc.
To get a better overview of the Himalaya CLI features, try this actions:
- List folders
- List envelopes
- Read a message
- Write & send a message
- Download attachments
- Watch for envelopes changes
- Sync an account for offline usage
Advanced usage
Once familiar with the core concept of the tool, have a look at the advanced usage section: you will find a complete usage API categorized by domain. You can also use the -h
flag to get information about the current command, or the --help
argument for more detailed information.
Troubleshooting
If you have any problem, have a look at the FAQ section or the bug tracker. If nothing helped you:
- Report any bug by sending an email at ~soywod/pimalaya@todo.sr.ht.
- Propose a feature or fix a bug by opening a pull request on GitHub.
- Discuss with us by joining the Matrix workspace #pimalaya.himalaya or by contacting me directly @soywod. You can also use the mailing list [send an email|subscribe|unsubscribe].
Installation
Arch Linux
Himalaya CLI can be installed on Arch Linux with either the community repository:
$ pacman -S himalaya
or the user repository:
$ git clone https://aur.archlinux.org/himalaya-git.git
$ cd himalaya-git
$ makepkg -isc
If you use yay, it is even simplier:
$ yay -S himalaya-git
Homebrew
Himalaya CLI can be installed with Homebrew:
$ brew install himalaya
Scoop
Himalaya CLI can be installed with Scoop:
$ scoop install himalaya
Cargo
Himalaya CLI can be installed with cargo:
$ cargo install himalaya
You can also use the git repository for a more up-to-date (but less stable) version:
$ cargo install --git https://github.com/soywod/himalaya himalaya
Himalaya CLI comes with few default features:
imap
: enables IMAP backend featuresmaildir
: enables Maildir backend featuressmtp
: enables SMTP backend featuressendmail
: enables sendmail backend featuresaccount-sync
: enables account synchronization (including folders and emails)account-discovery
: enables account auto discovery for the wizard
There is also other optional features:
notmuch
: enables notmuch backend features (requires the notmuch lib to be installed on the system)pgp-commands
enables the PGP shell commands backendpgp-gpg
enables the GPG PGP backend (requires the gpgme lib to be installed on the system)pgp-native
enables the native PGP backend
Nix
Himalaya CLI can be installed with Nix:
$ nix-env -i himalaya
You can also use the git repository for a more up-to-date (but less stable) version:
$ nix-env -if https://github.com/soywod/himalaya/archive/master.tar.gz
# or, from within the source tree checkout
$ nix-env -if .
If you have the Flakes feature enabled:
$ nix profile install himalaya
# or, from within the source tree checkout
$ nix profile install
# you can also run Himalaya directly without installing it:
$ nix run himalaya
Development
To enter a development shell:
$ nix-shell
# or, with the Flakes feature enabled
$ nix develop
From here, you have access to all the development tools (Rust compiler, cargo, rust language server, code formatter…) necessary to hack on Himalaya.
If you use VSCode, simply open this project folder and accept the workspace extension recommendations.
Troubleshooting
- See this discussion if you get the
hash mismatch in fixed-output derivation
error.
Fedora Linux/CentOS/RHEL
Himalaya CLI can be installed on Fedora Linux/CentOS/RHEL via COPR repo:
$ dnf copr enable atim/himalaya
$ dnf install himalaya
Binary
Himalaya CLI can be installed with a prebuilt binary:
# As root:
$ curl -sSL https://pimalaya.org/himalaya/cli/install.sh | sudo sh
# As a regular user:
$ curl -sSL https://pimalaya.org/himalaya/cli/install.sh | PREFIX=~/.local sh
Those commands install the latest binary from the GitHub releases section.
Note: Linux, macOS and Windows are supported. Note that some features may not work as expected on Windows.
Sources
Himalaya CLI can be installed from sources.
First you need to install the Rust development environment (see the rust installation documentation):
$ curl https://sh.rustup.rs -sSf | sh
Then, you need to clone the repository and install dependencies:
$ git clone https://github.com/soywod/himalaya.git
$ cd himalaya
$ cargo check
Now, you can build Himalaya:
$ cargo build --release
Note: binaries are available in the target/release
folder.
Troubleshooting
Could not compile autocfg
On aarch64, compiling autocfg will exhaust all available memory and rustcc will be killed by OS. You need to update llvm-libs
to the latest version to solve this problem. This is a llvm bug.
Configuration
Himalaya CLI takes its TOML configuration from one of those paths:
$XDG_CONFIG_HOME/himalaya/config.toml
$HOME/.config/himalaya/config.toml
$HOME/.himalayarc
There is 2 ways to configure Himalaya CLI:
Automatically, using the wizard
You just need to run himalaya
. You can configure separated files using the -c|--config
argument, for example: himalaya -c /tmp/config.toml
.
Note: actually you can only create new configurations with the wizard. There is an opened issue #42 to edit existing configurations using the wizard.
Manually, by editing the TOML file
The file should first contain your global configuration, followed by your accounts configurations. Each account configuration should be located inside a TOML section (table). The table name should be unique, as it is used to identify an account:
# global config
[accounts.example1]
# account config
[accounts.example2]
# account config
# …
Global configuration
The global configuration is the configuration that is applied by default to all your accounts.
display-name
The display name of the user.
It usually corresponds to the full name of the user.
display-name = "Clément DOUIN"
signature
The email signature of the user.
It can be either a path to a file (usually ~/.signature
) or a raw string. The signature supports TOML multiline.
signature = "~/.signature"
signature = "Regards,"
signature = """
Thank you,
Regards,
"""
signature-delim
The email signature delimiter of the user signature. Defaults to -- \n
.
signature-delim = "~~ \n"
downloads-dir
The downloads directory.
It is mostly used for downloading messages attachments. Defaults to the system temporary directory (usually /tmp
).
downloads-dir = "~/Downloads"
Account configuration
See the advanced usage section for the complete settings API.
Example
Here a complete and documented config.sample.toml
that you can actually test yourself with the following commands:
# save the sample config locally
curl https://raw.githubusercontent.com/soywod/himalaya/master/config.sample.toml > config.sample.toml
# spawn a testing IMAP/SMTP server using docker
docker run -it --rm -p 3025:3025 -p 3110:3110 -p 3143:3143 -p 3465:3465 -p 3993:3993 -p 3995:3995 -e GREENMAIL_OPTS='-Dgreenmail.setup.test.all -Dgreenmail.hostname=0.0.0.0 -Dgreenmail.auth.disabled -Dgreenmail.verbose' greenmail/standalone:latest
# test the CLI using the sample config
himalaya -c ./config.sample.toml envelope list
# The account name.
[accounts.example]
# The current account will be used by default for all other commands.
default = true
# The display-name and the email are used to build the full email
# address: "My example account" <example@localhost>
display-name = "My example account"
email = "example@localhost"
# The signature can be a string or a path to a file.
signature = "Regards,"
signature-delim = "-- \n"
# Enable the synchronization for this account. Running the command
# `account sync example` will synchronize all folders and all emails
# to a local Maildir at `$XDG_DATA_HOME/himalaya/example`.
sync.enable = false
# Override the default Maildir path for synchronization.
sync.dir = "/tmp/himalaya-sync-example"
# Filter folders to sync
folder.sync.filter.include = ["INBOX"]
# folder.sync.filter.exclude = ["All mails"]
# folder.sync.filter = "all"
# Define main folder aliases
folder.alias.inbox = "INBOX"
folder.alias.sent = "Sent"
folder.alias.drafts = "Drafts"
folder.alias.trash = "Trash"
# Also define custom folder aliases
folder.alias.prev-year = "Archives/2023"
# Default backend used for all the features like adding folders,
# listing envelopes or copying messages.
backend = "imap"
envelope.list.page-size = 10
envelope.list.datetime-fmt = "%F %R%:z"
# Date are converted to the user's local timezone.
envelope.list.datetime-local-tz = true
# Override the backend used for listing envelopes.
# envelope.list.backend = "imap"
# Send notification on receiving new envelopes
envelope.watch.received.notify.summary = "📬 New message from {sender}"
# Available placeholders: id, subject, sender, sender.name,
# sender.address, recipient, recipient.name, recipient.address.
envelope.watch.received.notify.body = "{subject}"
# Shell commands can also be executed when envelopes change
# envelope.watch.any.cmd = "mbsync -a"
# Override the backend used for sending messages.
message.send.backend = "smtp"
# Save a copy of sent messages to the sent folder.
message.send.save-copy = false
# IMAP config
imap.host = "localhost"
imap.port = 3143
imap.login = "example@localhost"
# Encryption can be either "tls" (or true), "start-tls" or "none" (or false).
imap.encryption = "none"
# Get password from a raw string (not safe)
imap.passwd.raw = "password"
# Get password from a shell command
# imap.passwd.cmd = "echo password"
# Get password from your global system keyring using secret service
# Keyring secrets can be (re)set with the command `account configure example`
# imap.passwd.keyring = "example-imap-password"
# Customize at which period, in seconds, the IMAP IDLE mode should refresh.
# Defaults to 1740 (29 min), as defined in the RFC.
# imap.watch.timeout = 25
# SMTP config
smtp.host = "localhost"
smtp.port = 3025
smtp.login = "example@localhost"
smtp.encryption = false
smtp.passwd.raw = "password"
# PGP needs to be enabled with one of those cargo feature:
# pgp-commands, pgp-gpg or pgp-native
# pgp.backend = "gpg"
Proton Bridge configuration
When using Proton Bridge, emails are synchronized locally and exposed via a local IMAP/SMTP server. This implies 2 things:
- Id order may be reversed or shuffled, but envelopes will still be sorted by date
- SSL/TLS needs to be deactivated manually
display-name = "Clément DOUIN"
downloads-dir = "~/downloads"
signature = "Cordialement,\nClément DOUIN"
[accounts.proton]
default = true
email = "clement.douin@proton.me"
backend = "imap"
imap.host = "127.0.0.1"
imap.port = 1143
imap.encryption = false
imap.login = "clement.douin@proton.me"
imap.passwd.cmd = "pass show proton"
message.send.backend = "smtp"
smtp.host = "127.0.0.1"
smtp.port = 1025
smtp.encryption = false
smtp.login = "clement.douin@proton.me"
smtp.passwd.cmd = "pass show proton"
Gmail configuration
Google passwords cannot be used directly. There is two ways to authenticate yourself:
Using App Passwords
This option is the simplest and the fastest. First, be sure that:
- IMAP is enabled
- Two-step authentication is enabled
- Less secure app access is enabled
Then you can create a dedicated password for Himalaya at https://myaccount.google.com/apppasswords. See the imap-auth
section on how to use it.
display-name = "Clément DOUIN"
downloads-dir = "~/Downloads"
signature = "Cordialement,\nClément DOUIN"
[accounts.gmail]
default = true
email = "clement.douin@gmail.com"
folder.alias.inbox = "INBOX"
folder.alias.sent = "[Gmail]/Sent Mail"
folder.alias.drafts = "[Gmail]/Drafts"
folder.alias.trash = "[Gmail]/Trash"
backend = "imap"
imap.host = "imap.gmail.com"
imap.port = 993
imap.login = "clement.douin@gmail.com"
imap.passwd.cmd = "pass show gmail"
message.send.backend = "smtp"
smtp.host = "smtp.gmail.com"
smtp.port = 465
smtp.login = "clement.douin@gmail.com"
smtp.passwd.cmd = "pass show gmail"
Note: passwords are prompted when running the command himalaya accounts configure
.
Using OAuth 2.0
This option is the most secure but the hardest to configure. First, you need to get your OAuth 2.0 credentials by following this guide. Once you get your client id and your client secret, you can configure your Himalaya account this way:
display-name = "Clément DOUIN"
downloads-dir = "~/Downloads"
signature = "Cordialement,\nClément DOUIN"
[accounts.gmail]
default = true
email = "clement.douin@gmail.com"
folder.alias.inbox = "INBOX"
folder.alias.sent = "[Gmail]/Sent Mail"
folder.alias.drafts = "[Gmail]/Drafts"
folder.alias.trash = "[Gmail]/Trash"
backend = "imap"
imap.host = "imap.gmail.com"
imap.port = 993
imap.login = "clement.douin@gmail.com"
imap.oauth2.client-id = "<imap.client-id>"
imap.oauth2.auth-url = "https://accounts.google.com/o/oauth2/v2/auth"
imap.oauth2.token-url = "https://www.googleapis.com/oauth2/v3/token"
imap.oauth2.pkce = true
imap.oauth2.scope = "https://mail.google.com/"
message.send.backend = "smtp"
smtp.host = "smtp.gmail.com"
smtp.port = 465
smtp.login = "clement.douin@gmail.com"
smtp.oauth2.client-id = "<smtp.client-id>"
smtp.oauth2.auth-url = "https://accounts.google.com/o/oauth2/v2/auth"
smtp.oauth2.token-url = "https://www.googleapis.com/oauth2/v3/token"
smtp.oauth2.pkce = true
smtp.oauth2.scope = "https://mail.google.com/"
# If you want your SMTP to share the same client id (and so the same access token)
# as your IMAP config, you can add the following:
# smtp.oauth2.client-id = "<imap-client-id>"
# smtp.oauth2.client-secret.keyring = "gmail-imap-oauth2-client-secret"
# smtp.oauth2.access-token.keyring = "gmail-imap-oauth2-access-token"
# smtp.oauth2.refresh-token.keyring = "gmail-imap-oauth2-refresh-token"
Note: client secrets are prompted when running the command himalaya accounts configure
.
Outlook configuration
display-name = "Clément DOUIN"
downloads-dir = "~/Downloads"
signature = "Cordialement,\nClément DOUIN"
[accounts.outlook]
default = true
email = "clement.douin@outlook.com"
backend = "imap"
imap.host = "outlook.office365.com"
imap.port = 993
imap.login = "clement.douin@outlook.com"
imap.passwd.cmd = "pass show outlook"
message.send.backend = "smtp"
smtp.host = "smtp.mail.outlook.com"
smtp.port = 587
smtp.encryption = "start-tls"
smtp.login = "clement.douin@outlook.com"
smtp.passwd.cmd = "pass show outlook"
Note: passwords are prompted when running the command himalaya accounts configure
.
Using OAuth 2.0
This option is the most secure but the hardest to configure. First, you need to get your OAuth 2.0 credentials by following this guide. Once you get your client id and your client secret, you can configure your Himalaya account this way:
display-name = "Clément DOUIN"
downloads-dir = "~/Downloads"
signature = "Cordialement,\nClément DOUIN"
[accounts.outlook]
default = true
email = "clement.douin@outlook.com"
backend = "imap"
imap.host = "outlook.office365.com"
imap.port = 993
imap.login = "clement.douin@outlook.com"
imap.oauth2.client-id = "<imap.client-id>"
imap.oauth2.auth-url = "https://login.microsoftonline.com/common/oauth2/v2.0/authorize"
imap.oauth2.token-url = "https://login.microsoftonline.com/common/oauth2/v2.0/token"
imap.oauth2.pkce = true
imap.oauth2.scopes = [
"offline_access",
"https://outlook.office.com/IMAP.AccessAsUser.All",
]
message.send.backend = "smtp"
smtp.host = "smtp.mail.outlook.com"
smtp.port = 587
smtp.starttls = true
smtp.login = "clement.douin@outlook.com"
smtp.oauth2.client-id = "<smtp.client-id>"
smtp.oauth2.auth-url = "https://login.microsoftonline.com/common/oauth2/v2.0/authorize"
smtp.oauth2.token-url = "https://login.microsoftonline.com/common/oauth2/v2.0/token"
smtp.oauth2.pkce = true
smtp.oauth2.scope = "https://outlook.office.com/SMTP.Send"
Note: client secrets are prompted when running the command himalaya accounts configure
.
iCloud Mail configuration
From the iCloud Mail support page:
- IMAP port =
993
. - IMAP login = name of your iCloud Mail email address (for example,
johnappleseed
, notjohnappleseed@icloud.com
) - SMTP port =
587
withSTARTTLS
- SMTP login = full iCloud Mail email address (for example,
johnappleseed@icloud.com
, notjohnappleseed
)
[accounts.icloud]
display-name = "John APPLESEED"
email = "johnappleseed@icloud.com"
signature = """
Regards,
John AppleSeed
Sent from iCloud
"""
backend = "imap"
imap.host = "imap.mail.me.com"
imap.port = 993
imap.login = "johnappleseed"
imap.passwd.cmd = "pass show icloud"
message.send.backend = "smtp"
smtp.host = "smtp.mail.me.com"
smtp.port = 587
smtp.encryption = "start-tls"
smtp.login = "johnappleseed@icloud.com"
smtp.passwd.cmd = "pass show icloud"
Note: passwords are prompted when running the command himalaya accounts configure
.
Basic usage
- An account is a set of options allowing users to connect to folders.
- A folder (aka mailbox) is an email container.
- An email is composed of an envelope and a message
- An envelope is a set of properties identifying a message.
- A message is composed of headers and a body, including attachments.
- An attachment is (usually) a binary content like an image, a PDF etc.
To get a good overview of the Himalaya CLI features, try these actions:
- List folders
- List envelopes
- Read a message
- Write & send a message
- Download attachments
- Watch for envelopes changes
- Sync an account for offline usage
List folders
$ himalaya folder list
Lists all folders of the current account. 2 properties are displayed:
name
: the name of the folderdesc
: the description of the folder
See the advanced version for more details.
Example
$ himalaya folder list
NAME │DESC
Junk │\HasNoChildren, Junk
Archives │\HasChildren
Archives.FOSS │\HasNoChildren
Trash │\HasNoChildren
Notes │\HasNoChildren
Drafts │\HasNoChildren
Sent │\HasNoChildren
INBOX │\HasNoChildren
List envelopes
$ himalaya envelope list
Lists all envelopes of the current folder. 5 properties are displayed:
id
: the identifier of the envelopeflags
: the flags associated to the envelopesubject
: the subject from the message headersfrom
: the first sender from the message headersto
: the first recipient from the message headersdate
: the date from the message headers
See the advanced version for more details.
Example
$ himalaya envelope list
ID │FLAGS │SUBJECT │FROM │DATE
937 │ │~soywod/pimalaya#161: TOML parse error: m… │~Phil Crockett │2023-12-22 15:12+00:00
938 │ │Re: [dantecatalfamo/himalaya-emacs] Prepa… │Dante Catalfamo │2023-12-20 23:21-08:00
939 │ │Re: Short question │michiel@nlnet.nl │2023-12-20 17:39+01:00
940 │ │Update and important request: EC evaluati… │Michiel Leenaars │2023-12-20 12:44+00:00
941 │ │Re: Short question │michiel@nlnet.nl │2023-12-20 12:23+01:00
942 │ │Short question │michiel@nlnet.nl │2023-12-20 09:40+01:00
943 │ │Request for payment for 2023-04-034: Pima… │dashboard@nlnet.nl │2023-12-18 13:20+00:00
944 │ │Re: [TornaxO7/rfc2047-decoder] InvalidByt… │TornaxO7 │2023-12-17 05:55-08:00
945 │ │Re: [TornaxO7/rfc2047-decoder] InvalidByt… │TornaxO7 │2023-12-17 05:55-08:00
946 │ │Please confirm the RfP for 2023-04-034: P… │dashboard@nlnet.nl │2023-12-14 23:24+00:00
Read a message
$ himalaya message read <ID>
Reads message matching the given envelope id.
See the advanced version for more details.
Example
$ himalaya message read 944
From: ~matf <outgoing@sr.ht>
To: soywod <clement.douin@posteo.net>
Subject: ~soywod/pimalaya#154: Configuration wizard: cannot canonicalize path
I built `himalaya` from sources using the `cargo` instructions in the documentation, then followed the configuration wizard (it's nice), but unfortunately it seems unable to save the `config.toml`:
✘ cannot canonicalize path "/home/droidian/.config/himalaya/config.toml"
? Where would you like to save your configuration? (/home/droidian/.config/himalaya/config.toml) ›
The same happens whether I `mkdir -p ~/.config/himalaya` or not.
Any ideas? This is on aarch64.
--
View on the web: https://todo.sr.ht/~soywod/pimalaya/154
Write & send a message
There are multiple ways to send a message:
Compose a message interactively
$ himalaya message write
Opens your editor (the one specified in the $EDITOR
environment variable) to edit a new message, then sends it. The edition stops when you exit your editor.
You can customize the editor for a given command by prefixing it with a custom $EDITOR
environment variable:
$ EDITOR=nano himalaya message write
See the advanced version for more details.
Reply to a message interactively
$ himalaya message reply <ID>
Similar to write a new message: finds the message matching the given envelope identifier, opens your editor to edit a reply message then sends it.
Note: you can reply to all recipients with the flag -A|--all
.
See the advanced version for more details.
Forward a message interactively
$ himalaya message forward <ID>
Similar to write a new message: finds the message matching the given envelope identifier, opens your editor to edit a forward message then sends it.
See the advanced version for more details.
Send a message
$ himalaya message send [MESSAGE]...
Sends the given message. The message can come from arguments or from the standard input (if the terminal is not interactive).
See the advanced version for more details.
Example
$ cat /tmp/email.eml | himalaya message send
$ himalaya message send < /tmp/email.eml
$ himalaya message send 'From: alice@localhost
To: bob@localhost
Subject: Hello
Hello, world!'
Download attachments
$ himalaya attachment download <ID>
Downloads all attachments found in the message matching the given envelope id to your downloads directory.
See the advanced version for more details.
Example
$ himalaya attachment download 3384
2 attachment(s) found for message 3384!
Downloading "~/downloads/document.pdf"…
Downloading "~/downloads/screenshot.png"…
Downloaded 2 attachments!
Watch for envelopes changes
$ himalaya envelope watch
Watches the current folder and executes hooks when changes occur on envelopes.
If synchronization is enabled, the command will watch local cached folders. To force the command to watch remote folders, you can either:
-
Force the remote backend for the watch envelopes feature, for example:
# ~/.config/himalaya/config.toml envelope.watch.backend = "imap"
-
Disable the cache with the
--disable-cache
flag:$ himalaya envelope watch --disable-cache
See the advanced version for more details.
Examples
Get notified on new emails
To receive system notifications when new emails arrive in the INBOX
:
# ~/.config/himalaya/config.toml
# Available placeholders:
# id, subject, sender, sender.name, sender.address, recipient, recipient.name, recipient.address.
envelope.watch.received.notify.summary = "📬 New message from {sender}"
envelope.watch.received.notify.body = "{subject}"
$ himalaya envelope watch
Synchronize account on new emails
To run commands when new emails arrive in the INBOX
:
# ~/.config/himalaya/config.toml
envelope.watch.received.cmd = "himalaya account sync"
$ himalaya envelope watch
Synchronize an account for offline usage
$ himalaya account sync
Synchronizes current account’s folders and emails locally, for an offline usage of the CLI.
Before using this feature, be sure that you enabled it (either by using the wizard or by manually editing the configuration file):
[accounts.example]
sync.enable = true
See the advanced version for more details.
Examples
Dry run
Run the synchronization without applying any changes. Instead, a report will be printed to stdout containing all the changes the synchronization plans to do.
$ himalaya account sync --dry-run
Envelopes patch:
- Updating flags seen of right cached envelope 14031 (INBOX)
- Copying right envelope 14047 to left folder INBOX
- Updating flags seen of left cached envelope 1704194588.#7M923748111P3344451V65024I15206527.soywod,S=7401 (INBOX)
- Setting flags seen of right envelope 14030 (INBOX)
- Setting flags seen of right envelope 14031 (INBOX)
- Updating flags seen of right cached envelope 14030 (INBOX)
- Updating flags seen of left cached envelope 1704194588.#9M963882549P3344451V65024I15206530.soywod,S=6999 (INBOX)
Estimated patch length for account example to be synchronized: 7
Synchronize only one folder
$ himalaya account sync --include-folder INBOX
Exclude a folder from the sync
$ himalaya account sync --exclude-folder All
Advanced usage
$ himalaya [OPTIONS] <COMMAND>
Commands
Names in yellow correspond to domains covered by Himalaya CLI. Every domain has its own dedicated command: account, folder, envelope, flag, message, attachment, template.
Options
These options are global, which means they can be used in all commands and subcommands.
-c|--config
Override the default configuration file path.
The given path is shell-expanded then canonicalized (if applicable). If the path does not point to a valid file, the wizard will propose to assist you in the creation of the configuration file.
-o|--output
Customize the output format
The output format determine how to display commands output to the terminal. The possible values are:
json
: output will be in a form of a JSON-compatible objectplain
: output will be in a form of either a plain text or table, depending on the command
-C|--color
Control when to use colors
The default setting is ‘auto’, which means himalaya will try to guess when to use colors. For example, if himalaya is printing to a terminal, then it will use colors, but if it is redirected to a file or a pipe, then it will suppress color output. himalaya will suppress color output in some other circumstances as well. For example, if the $TERM
environment variable is not set or set to dumb
, then himalaya will not use colors.
The possible values are:
never
: colors will never be usedalways
: colors will always be used regardless of where output is sentansi
: like ‘always’, but emits ANSI escapes (even in a Windows console)auto
: himalaya tries to be smart
--debug
Enable logs with spantrace.
This is the same as running the command with RUST_LOG=debug
environment variable.
--trace
Enable verbose logs with backtrace.
This is the same as running the command with RUST_LOG=trace
and RUST_BACKTRACE=1
environment variables.
Settings
imap
Configuration related to IMAP. See the documentation.
maildir
Configuration related to Maildir. See the documentation.
notmuch
Configuration related to notmuch. See the documentation.
smtp
Configuration related to SMTP. See the documentation.
sendmail
Configuration related to sendmail. See the documentation.
pgp
Configuration related end-to-end PGP encryption. See the documentation.
API by domain
Names in yellow correspond to domains covered by Himalaya CLI. Every domain has its own dedicated command: account, folder, envelope, flag, message, attachment, template.
Accounts
An account is a group of settings, identified by an account name. Settings are directly taken from your TOML configuration file. Accounts can be managed with those commands:
Settings
email
(required)
The email address of the user account.
email = "clement.douin@posteo.net"
default
The current account will be used by default for all other commands.
default = true
display-name
The display name of the user.
It usually corresponds to the full name of the user.
display-name = "Clément DOUIN"
signature
The email signature of the user.
It can be either a path to a file (usually ~/.signature
) or a raw string. The signature supports TOML multiline.
signature = "~/.signature"
signature = "Regards,"
signature = """
Thank you,
Regards,
"""
signature-delim
The email signature delimiter of the user signature. Defaults to -- \n
.
signature-delim = "~~ \n"
backend
Default backend used for all the features like adding folders, listing envelopes or copying messages.
# valid backends: maildir, imap, notmuch
backend = "imap"
Check up account
$ himalaya account check-up [OPTIONS] [ACCOUNT]
Check up the given account (or the default one if omitted).
This command performs a checkup of the given account. It checks if the configuration is valid, if backend can be created and if sessions work as expected.
Configure account
$ himalaya account configure [OPTIONS] <ACCOUNT>
Configure interactively the current selected account. For example, it can prompt the IMAP password, the IMAP OAuth 2.0 client secret etc.
Options
-r|--reset
Reset the configuration, which means you may be prompted again for passwords or secrets.
List accounts
$ himalaya account list [OPTIONS]
Lists all accounts defined in your configuration file. 3 properties are displayed:
name
: the name of the account (the TOML table section)backends
: the list of all backend used for all featuresdefault
: represents the defaultness of the account (“yes” if the optiondefault = true
is set, “no” otherwise)
Options
-w|--max-width
The maximum width the table should not exceed.
This argument will force the table not to exceed the given width in pixels. Columns may shrink with ellipsis in order to fit the width.
Synchronize an account
$ himalaya account sync [OPTIONS] [ACCOUNT]
Synchronizes folders and emails of the given account (or the default one if omitted) locally, on your filesystem, for an offline usage of the CLI.
Disclaimer: this feature is still in beta, we recommand you to backup your emails before using it. Do not use in production before the final v1.0.0
.
Since the v0.7.0
, you can synchronize your folders and your emails locally. To enable this feature, add the following entry in the configuration of the account you want to synchronize:
[accounts.example]
sync.enable = true
By default, Himalaya stores your emails at $XDG_DATA_HOME/pimalaya/email/sync/<account-name>-cache
using the Maildir++ format. The location can be customized with the sync.dir
option:
[accounts.example]
sync.enable = true
sync.dir = "~/.Mail/my-account-name"
Himalaya also stores 2 lightweight Maildir at $XDG_CACHE_HOME/pimalaya/email/sync/<hash>
which contains the previous state of every local and remote envelopes. This way Himalaya tries to guess which side (local or remote) needs to be updated. In case of conflict, Himalaya takes the solution that does not loose any data. For instance: if an envelope exists in the local Maildir and in the local cache, but not remotely nor in the remote cache, we cannot determine if an email has been added locally or removed remotely. In this case, Himalaya will consider that the email has been added locally in order not to loose data.
Warning: if you want to restart the synchronization from scratch, make sure to delete all data and cache folders, otherwise Himalaya may consider that emails have been removed locally and needs to be removed remotely, which would lead to a complete wipeout of your data!.
Options
-d|--dry-run
Run the synchronization without applying any changes.
Instead, a report will be printed to stdout containing all the changes the synchronization plan to do.
-F|--include-folder
Synchronize only specific folders (can be repeated).
Only the given folders will be synchronized (including associated envelopes and messages). Useful when you need to speed up the synchronization process. A good usecase is to synchronize only the INBOX in order to quickly check for new messages.
Overrides the config option sync.strategy
.
-x|--exclude-folder
Omit specific folders from the synchronization.
The given folders will be excluded from the synchronization (including associated envelopes and messages). Useful when you have heavy folders that you do not want to take care of, or to speed up the synchronization process.
Overrides the config option sync.strategy
.
-A|--all-folders
Synchronizes all existing folders.
Settings
sync.enable
Enable the synchronization for the current account.
Enabling the synchronization allows you to run the command account sync <account-name>
, which synchronizes all folders and its associated emails to a local Maildir. All other commands also operate on this Maildir backend rather than the default one, which makes your account usable even offline.
sync.enable = true
sync.dir
Customize the root directory where the Maildir cache is saved.
Defaults to $XDG_DATA_HOME/pimalaya/email/sync/<account-name>
.
sync.dir = "~/.local/share/himalaya/custom"
folder.sync.filter
Use the given strategy to synchronize folders:
-
folder.sync.filter = "all"
(default): Synchronizes all folders. -
folder.sync.filter.include = ["INBOX", "Sent"]
: Synchronizes only folders matching the given names. -
folder.sync.filter.exclude = ["Trash"]
: Synchronizes all folders except the ones matching the given names.
Folders
A folder (as known as mailbox, or directory) contains one or more emails. Folders can be managed with those commands:
Settings
folder.alias(es)
Define custom folder aliases.
Aliases are resolved when calling backend features. There are 4 special aliases that can be used by the lib, for example when saving a copy of a sent message to the sent
folder:
-
inbox
: main folder containing incoming messages -
draft(s)
: folder containing draft messages -
sent
: folder containing sent messages -
trash
: folder containing trashed messages
folder.alias.inbox = "INBOX"
folder.alias.drafts = "[Gmail]/Drafts"
folder.alias.sent = "Envoyés"
folder.alias.trash = "Deleted"
folder.alias.work = "Archives.Work"
Create a folder
$ himalaya folder create [OPTIONS] <FOLDER>
This command allows you to create a new folder using the given name.
Options
--disable-cache
Disable any sort of cache.
The action depends on commands it apply on. For example, when listing envelopes using the IMAP backend, this flag will ensure that envelopes are fetched from the IMAP server rather than the synchronized local Maildir.
-a|--account
Override the default account.
An account name corresponds to an entry in the table at the root level of your TOML configuration file.
Settings
folder.create.backend
Override the backend used for creating folders.
# valid backends: maildir, imap, notmuch
folder.create.backend = "imap"
List folders
$ himalaya folder list [OPTIONS]
Lists all folders of the given account (via the global option -a|--account
, or the default one if omitted). 2 properties are displayed:
name
: the name of the folderdesc
: the description of the folder
Options
-w|--max-width
The maximum width the table should not exceed.
This argument will force the table not to exceed the given width in pixels. Columns may shrink with ellipsis in order to fit the width.
--disable-cache
Disable any sort of cache.
The action depends on commands it apply on. For example, when listing envelopes using the IMAP backend, this flag will ensure that envelopes are fetched from the IMAP server rather than the synchronized local Maildir.
-a|--account
Override the default account.
An account name corresponds to an entry in the table at the root level of your TOML configuration file.
Settings
folder.list.backend
Override the backend used for listing folders.
# valid backends: maildir, imap, notmuch
folder.list.backend = "imap"
Example
$ himalaya folder list --disable-cache --account posteo
NAME │DESC
Junk │\HasNoChildren, Junk
Archives │\HasChildren
Archives.FOSS │\HasNoChildren
Trash │\HasNoChildren
Notes │\HasNoChildren
Drafts │\HasNoChildren
Sent │\HasNoChildren
INBOX │\HasNoChildren
Expunge a folder
$ himalaya folder expunge [OPTIONS] <FOLDER>
The concept of expunging is similar to the IMAP one: it definitely deletes emails from the given folder that contain the “deleted” flag.
Options
--disable-cache
Disable any sort of cache.
The action depends on commands it apply on. For example, when listing envelopes using the IMAP backend, this flag will ensure that envelopes are fetched from the IMAP server rather than the synchronized local Maildir.
-a|--account
Override the default account.
An account name corresponds to an entry in the table at the root level of your TOML configuration file.
Settings
folder.expunge.backend
Override the backend used for expunging folders.
# valid backends: maildir, imap, notmuch
folder.expunge.backend = "imap"
Purge a folder
$ himalaya folder purge [OPTIONS] <FOLDER>
All emails from the given folder are definitely deleted. The purged folder will remain empty after execution of the command.
Options
--disable-cache
Disable any sort of cache.
The action depends on commands it apply on. For example, when listing envelopes using the IMAP backend, this flag will ensure that envelopes are fetched from the IMAP server rather than the synchronized local Maildir.
-a|--account
Override the default account.
An account name corresponds to an entry in the table at the root level of your TOML configuration file.
Settings
folder.purge.backend
Override the backend used for purging folders.
# valid backends: maildir, imap, notmuch
folder.purge.backend = "imap"
Delete a folder
$ himalaya folder delete [OPTIONS] <FOLDER>
All emails from the given folder are definitely deleted. The folder is also deleted after execution of the command.
Options
--disable-cache
Disable any sort of cache.
The action depends on commands it apply on. For example, when listing envelopes using the IMAP backend, this flag will ensure that envelopes are fetched from the IMAP server rather than the synchronized local Maildir.
-a|--account
Override the default account.
An account name corresponds to an entry in the table at the root level of your TOML configuration file.
Settings
folder.delete.backend
Override the backend used for deleting folders.
# valid backends: maildir, imap, notmuch
folder.delete.backend = "imap"
Envelopes
An envelope is a small representation of a message. It contains an identifier (given by the backend), some flags as well as few headers from the message itself. Folders can be managed with those commands:
List, filter and sort envelopes
$ himalaya envelope list [OPTIONS] [QUERY]...
Lists envelopes included in the given folder (defaults to INBOX
), and filter/sort them according to the given query. 5 properties are displayed:
id
: the identifier of the envelopeflags
: the flags associated to the envelopesubject
: the subject from the message headersfrom
: the first sender from the message headersto
: the first recipient from the message headersdate
: the date from the message headers
Query
The query allows you to filter and/or sort envelopes. It can be composed of a filter query, a sort query or both at the same time.
See the ABNF grammar for more detailed information (advanced).
Filter query
A filter query is composed of operators and conditions.
There is 3 operators:
not <condition>
: filter envelopes that do not match the condition<condition> and <condition>
: filter envelopes that match both conditions<condition> or <condition>
: filter envelopes that match one of the conditions
And there is 8 conditions:
date <yyyy-mm-dd>
: filter envelopes that match the given datebefore <yyyy-mm-dd>
: filter envelopes with date strictly before the given oneafter <yyyy-mm-dd>
: filter envelopes with date stricly after the given onefrom <pattern>
: filter envelopes with senders matching the given patternto <pattern>
: filter envelopes with recipients matching the given patternsubject <pattern>
: filter envelopes with subject matching the given patternbody <pattern>
: filter envelopes with text bodies matching the given patternflag <flag>
: filter envelopes matching the given flag
Sort query
A sort query starts by order by
, and is composed of kinds and orders.
There is 4 kinds:
date [order]
: sort envelopes by datefrom [order]
: sort envelopes by senderto [order]
: sort envelopes by recipientsubject [order]
: sort envelopes by subject
Note: the order can be omitted. If so, the ascending order is used by default.
And there is 2 orders:
<kind> asc
: sort envelopes by the given kind in ascending order<kind> desc
: sort envelopes by the given kind in descending order
Options
-f|--folder
The folder name.
Defaults to INBOX
.
-p|--page
The page number.
The page number starts from 1 (which is the default). Giving a page number to big will result in a out of bound error.
-s|--page-size
The page size.
Determine the amount of envelopes a page should contain.
Note: a page size at 0
means no pagination.
-w|--max-width
The maximum width the table should not exceed.
This argument will force the table not to exceed the given width in pixels. Columns may shrink with ellipsis in order to fit the width.
--disable-cache
Disable any sort of cache.
The action depends on commands it apply on. For example, when listing envelopes using the IMAP backend, this flag will ensure that envelopes are fetched from the IMAP server rather than the synchronized local Maildir.
-a|--account
Override the default account.
An account name corresponds to an entry in the table at the root level of your TOML configuration file.
Settings
envelope.list.backend
Override the backend used for listing envelopes.
# valid backends: maildir, imap, notmuch
envelope.list.backend = "imap"
envelope.list.page-size
Define the size of a page when listing envelopes.
A page size of 0 disables the pagination and shows all available envelopes.
envelope.list.page-size = 10
envelope.list.datetime-fmt
Customize the format for displaying envelopes date.
See chrono::format::strftime
for supported formats. Defaults to "%F %R%:z"
(eg: 2023-05-04 07:49-07:00
).
envelope.list.datetime-fmt = "%d-%m-%Y, %R"
envelope.list.datetime-local-tz
Transform envelopes date timezone into the user’s local one.
For example, if the user’s local timezone is UTC, the envelope date 2023-06-15T09:00:00+02:00
becomes 2023-06-15T07:00:00-00:00
.
envelope.list.datetime-local-tz = true
Examples
$ himalaya envelope list --disable-cache --account posteo Archives.FOSS
ID │FLAGS │SUBJECT │FROM │DATE
937 │ │~soywod/pimalaya#161: TOML parse error: m… │~Phil Crockett │2023-12-22 15:12+00:00
938 │ │Re: [dantecatalfamo/himalaya-emacs] Prepa… │Dante Catalfamo │2023-12-20 23:21-08:00
939 │ │Re: Short question │michiel@nlnet.nl │2023-12-20 17:39+01:00
940 │ │Update and important request: EC evaluati… │Michiel Leenaars │2023-12-20 12:44+00:00
941 │ │Re: Short question │michiel@nlnet.nl │2023-12-20 12:23+01:00
942 │ │Short question │michiel@nlnet.nl │2023-12-20 09:40+01:00
943 │ │Request for payment for 2023-04-034: Pima… │dashboard@nlnet.nl │2023-12-18 13:20+00:00
944 │ │Re: [TornaxO7/rfc2047-decoder] InvalidByt… │TornaxO7 │2023-12-17 05:55-08:00
945 │ │Re: [TornaxO7/rfc2047-decoder] InvalidByt… │TornaxO7 │2023-12-17 05:55-08:00
946 │ │Please confirm the RfP for 2023-04-034: P… │dashboard@nlnet.nl │2023-12-14 23:24+00:00
$ himalaya envelope list from michiel or from nlnet order by date desc
ID │FLAGS │SUBJECT │FROM │DATE
939 │ │Re: Short question │michiel@nlnet.nl │2023-12-20 17:39+01:00
940 │ │Update and important request: EC evaluati… │Michiel Leenaars │2023-12-20 12:44+00:00
941 │ │Re: Short question │michiel@nlnet.nl │2023-12-20 12:23+01:00
942 │ │Short question │michiel@nlnet.nl │2023-12-20 09:40+01:00
943 │ │Request for payment for 2023-04-034: Pima… │dashboard@nlnet.nl │2023-12-18 13:20+00:00
946 │ │Please confirm the RfP for 2023-04-034: P… │dashboard@nlnet.nl │2023-12-14 23:24+00:00
Watch for envelopes changes
$ himalaya envelope watch [OPTIONS] [FOLDER]
Watches the given folder (defaults to INBOX
) and executes hooks when changes occur on envelopes.
If synchronization is enabled, the command will watch local cached folders. To force the command to watch remote folders, you can either:
-
Force the remote backend for the watch envelopes feature, for example:
envelope.watch.backend = "imap"
-
Disable the cache with the
--disable-cache
flag:$ himalaya envelope watch --disable-cache
Options
-f|--folder
The name of the folder. Defaults to INBOX
.
--disable-cache
Disable any sort of cache.
The action depends on commands it apply on. For example, when listing envelopes using the IMAP backend, this flag will ensure that envelopes are fetched from the IMAP server rather than the synchronized local Maildir.
-a|--account
Override the default account.
An account name corresponds to an entry in the table at the root level of your TOML configuration file.
Settings
envelope.watch.{event}.{hook}
Configure the hook to execute when receiving a specific watch event.
Possible values of event:
-
envelope.watch.received.{hook}
: trigger the hook when receiving a new envelope -
envelope.watch.any.{hook}
: trigger the hook for any other event
Possible values of hook:
-
envelope.watch.{event}.cmd
: trigger the given shell command -
envelope.watch.{event}.notify
: send a system notification-
envelope.watch.{event}.notify.summary
: customize the summary (title) of the notification -
envelope.watch.{event}.notify.body
: customize the body (content) of the notification
Both
summary
andbody
accept placeholders that will be replaced at runtime:-
{id}
: the envelope id -
{subject}
: the envelope subject -
{sender}
: the sender name or his email address -
{sender.name}
: the sender name orunknown
-
{sender.address}
: the sender email address -
{recipient}
: the recipient name or his email address -
{recipient.name}
: the recipient name orunknown
-
{recipient.address}
: the recipient email address
-
envelope.watch.received.notify.summary = "📬 New message from {sender}"
envelope.watch.received.notify.body = "{subject}"
envelope.watch.any.cmd = "mbsync -a"
Note: it is possible to cumulate hooks for a same event. For example it is possible to send a system notification and execute a command when receiving a new envelope.
Flags
A flag is a tag associated to an envelope. Existing flags are seen, answered, flagged, deleted, draft. Other flags are considered custom, which are not always supported (the synchronization does not take care of them yet). Flags can be managed with those commands:
Add flags
$ himalaya flag add [OPTIONS] <ID-OR-FLAG>...
This command allows you to attach the given flag(s) to the given envelope(s).
Options
-f|--folder
The name of the folder.
--disable-cache
Disable any sort of cache.
The action depends on commands it apply on. For example, when listing envelopes using the IMAP backend, this flag will ensure that envelopes are fetched from the IMAP server rather than the synchronized local Maildir.
-a|--account
Override the default account.
An account name corresponds to an entry in the table at the root level of your TOML configuration file.
Settings
flag.add.backend
Override the backend used for adding flags.
# valid backends: maildir, imap, notmuch
flag.add.backend = "imap"
Set flags
$ himalaya flag set [OPTIONS] <ID-OR-FLAG>...
This command allows you to replace existing flags of the given envelope(s) with the given flag(s).
Options
-f|--folder
The name of the folder.
--disable-cache
Disable any sort of cache.
The action depends on commands it apply on. For example, when listing envelopes using the IMAP backend, this flag will ensure that envelopes are fetched from the IMAP server rather than the synchronized local Maildir.
-a|--account
Override the default account.
An account name corresponds to an entry in the table at the root level of your TOML configuration file.
Settings
flag.set.backend
Override the backend used for setting flags.
# valid backends: maildir, imap, notmuch
flag.set.backend = "imap"
Remove flags
$ himalaya flag remove [OPTIONS] <ID-OR-FLAG>...
This command allows you to remove the given flag(s) from the given envelope(s).
Options
-f|--folder
The name of the folder.
--disable-cache
Disable any sort of cache.
The action depends on commands it apply on. For example, when listing envelopes using the IMAP backend, this flag will ensure that envelopes are fetched from the IMAP server rather than the synchronized local Maildir.
-a|--account
Override the default account.
An account name corresponds to an entry in the table at the root level of your TOML configuration file.
Settings
flag.remove.backend
Override the backend used for removing flags.
# valid backends: maildir, imap, notmuch
flag.remove.backend = "imap"
Messages
A message is the content of an email. It is composed of headers (located at the top of the message) and a body (located at the bottom of the message). Both are separated by two new lines. Messages can be managed with those commands:
- Read messages
- Write new messages
- Reply to messages
- Forward messages
- Save messages
- Send messages
- Copy messages
- Move messages
- Delete messages
Read a message
$ himalaya message read [OPTIONS] <ID>...
Reads message(s) matching the given envelope id(s).
Note: when reading message(s), the seen
flag is automatically applied to the corresponding envelope(s). To prevent this behaviour, use the --preview
flag instead.
Options
-f|--folder
The name of the folder.
-p|--preview
Read the message without applying the “seen” flag to its corresponding envelope.
-r|--raw
Read only body of text/html parts.
This argument is useful when you need to read the HTML version of a message. Combined with --no-headers
, you can write it to a .html
file and open it with your favourite browser.
--no-headers
Read only the body of the message.
All headers will be removed from the message.
-H|--header
Prefill the template with custom headers (can be repeated).
A raw header should follow the pattern KEY:VAL
.
--disable-cache
Disable any sort of cache.
The action depends on commands it apply on. For example, when listing envelopes using the IMAP backend, this flag will ensure that envelopes are fetched from the IMAP server rather than the synchronized local Maildir.
-a|--account
Override the default account.
An account name corresponds to an entry in the table at the root level of your TOML configuration file.
Settings
message.read.backend
Override the backend used for reading messages.
# valid backends: maildir, imap, notmuch
message.read.backend = "imap"
message.read.headers
Define visible headers at the top of messages when reading them.
message.read.headers = ["Date", "From", "To", "Subject"]
message.read.format
Define the text/plain format as defined in the RFC 2646.
# The content should fit its container (default).
message.read.format = "auto"
# The content should not be restricted.
message.read.format = "flowed"
# The content should fit in a fixed amount of pixels.
message.read.format.fixed = 80
Example
$ himalaya message read --disable-cache --account posteo --folder Archives.FOSS 944
From: ~matf <outgoing@sr.ht>
To: soywod <clement.douin@posteo.net>
Subject: ~soywod/pimalaya#154: Configuration wizard: cannot canonicalize path
I built `himalaya` from sources using the `cargo` instructions in the documentation, then followed the configuration wizard (it's nice), but unfortunately it seems unable to save the `config.toml`:
✘ cannot canonicalize path "/home/droidian/.config/himalaya/config.toml"
? Where would you like to save your configuration? (/home/droidian/.config/himalaya/config.toml) ›
The same happens whether I `mkdir -p ~/.config/himalaya` or not.
Any ideas? This is on aarch64.
--
View on the web: https://todo.sr.ht/~soywod/pimalaya/154
Write a new message
$ himalaya message write [OPTIONS] [BODY]...
Writes a new message by editing a MML template. A template is a pseudo-message following this format:
Header1: val1
Header2: val2
Header3: val3
…
Body
Headers are located at the top of the template, whereas the body is located at the bottom of the template. Headers and body need to be separated by an empty new line.
Headers
Templates accept 8 headers:
Message-ID
: represents the message identifier (you usually do not need to set up it manually)In-Reply-To
: represents the identifier of the replied messageSubject
: represents the subject of the messageFrom
: represents the address of the senderTo
: represents the addresses of the receiversReply-To
: represents the address the receiver should reply to instead of theFrom
headerCc
: represents the addresses of the other receivers (carbon copy)Bcc
: represents the addresses of the other hidden receivers (blind carbon copy)
An address can be:
- a single email address
user@domain
- a named address
Name <user@domain>
- a quoted named address
"Name" <user@domain>
Multiple address are separated by a coma ,
: user@domain, Name <user@domain>, "Name" <user@domain>
.
Body
Templates bodies can be simple strings. During the compilation they are transformed into text/plain
parts. So writing a template can be as simple as:
From: alice@localhost
To: Bob <bob@localhost>
Subject: Hello from Himalaya
Hello, world!
Templates bodies can also be written in MIME Meta Language, see the templates section for more information about the syntax.
Edition
Templates are edited using your default editor (the one specified in the $EDITOR
environment variable).
Once the editor exited, the following actions will be prompted:
(s)end, (e)dit, (l)ocal/(r)emote draft or (d)iscard?
s
compiles the template then sends the messagee
reopens your editor with the templatel
saves the template locallyr
saves the template remotely (in the draft folder)d
discards the template
Options
-H|--header
Prefill the template with custom headers (can be repeated).
A raw header should follow the pattern KEY:VAL
.
--disable-cache
Disable any sort of cache.
The action depends on commands it apply on. For example, when listing envelopes using the IMAP backend, this flag will ensure that envelopes are fetched from the IMAP server rather than the synchronized local Maildir.
-a|--account
Override the default account.
An account name corresponds to an entry in the table at the root level of your TOML configuration file.
Settings
message.write.backend
Override the backend used for writing messages.
# valid backends: maildir, imap, notmuch
message.write.backend = "imap"
message.write.headers
Define visible headers at the top of messages when writing them (new/reply/forward).
message.write.headers = ["Date", "From", "To", "Subject"]
Reply to a message
$ himalaya message reply [OPTIONS] <ID> [BODY]...
This command allows you to reply to the given message using the editor defined in your environment variable $EDITOR
. When the edition process finishes, you can choose between saving or sending the final message.
Options
-f|--folder
The name of the folder.
-A|--all
Reply to all recipients.
This argument will add all recipients for the To
and Cc
headers.
-H|--header
Prefill the template with custom headers (can be repeated).
A raw header should follow the pattern KEY:VAL
.
--disable-cache
Disable any sort of cache.
The action depends on commands it apply on. For example, when listing envelopes using the IMAP backend, this flag will ensure that envelopes are fetched from the IMAP server rather than the synchronized local Maildir.
-a|--account
Override the default account.
An account name corresponds to an entry in the table at the root level of your TOML configuration file.
Settings
message.write.backend
Override the backend used for writing messages.
# valid backends: maildir, imap, notmuch
message.write.backend = "imap"
message.write.headers
Define visible headers at the top of messages when writing them (new/reply/forward).
message.write.headers = ["Date", "From", "To", "Subject"]
Forward a message
$ himalaya message forward [OPTIONS] <ID> [BODY]...
This command allows you to forward the given message using the editor defined in your environment variable $EDITOR
. When the edition process finishes, you can choose between saving or sending the final message.
Options
-f|--folder
The name of the folder.
-H|--header
Prefill the template with custom headers.
A raw header should follow the pattern KEY:VAL
.
--disable-cache
Disable any sort of cache.
The action depends on commands it apply on. For example, when listing envelopes using the IMAP backend, this flag will ensure that envelopes are fetched from the IMAP server rather than the synchronized local Maildir.
-a|--account
Override the default account.
An account name corresponds to an entry in the table at the root level of your TOML configuration file.
Settings
message.write.backend
Override the backend used for writing messages.
# valid backends: maildir, imap, notmuch
message.write.backend = "imap"
message.write.headers
Define visible headers at the top of messages when writing them (new/reply/forward).
message.write.headers = ["Date", "From", "To", "Subject"]
Mailto
$ himalaya message mailto [OPTIONS] <URL>
Parse and edit a message from a mailto URL string.
This command allows you to edit a message from the mailto format using the editor defined in your environment variable $EDITOR
. When the edition process finishes, you can choose between saving or sending the final message.
Options
--disable-cache
Disable any sort of cache.
The action depends on commands it apply on. For example, when listing envelopes using the IMAP backend, this flag will ensure that envelopes are fetched from the IMAP server rather than the synchronized local Maildir.
-a|--account
Override the default account.
An account name corresponds to an entry in the table at the root level of your TOML configuration file.
Save a message
$ himalaya message save [OPTIONS] [MESSAGE]...
This command allows you to add a raw message to the given folder.
Options
-f|--folder
The name of the folder.
--disable-cache
Disable any sort of cache.
The action depends on commands it apply on. For example, when listing envelopes using the IMAP backend, this flag will ensure that envelopes are fetched from the IMAP server rather than the synchronized local Maildir.
-a|--account
Override the default account.
An account name corresponds to an entry in the table at the root level of your TOML configuration file.
Examples
$ cat /tmp/email.eml | himalaya message save
$ himalaya message save < /tmp/email.eml
$ himalaya message save 'From: alice@localhost
To: bob@localhost
Subject: Hello
Hello, world!'
Send a message
$ himalaya message send [OPTIONS] [MESSAGE]...
This command allows you to send a raw message and to save a copy to your send folder.
The raw message can be send either as a regular argument or using standard input (pipe or redirection).
Options
--disable-cache
Disable any sort of cache.
The action depends on commands it apply on. For example, when listing envelopes using the IMAP backend, this flag will ensure that envelopes are fetched from the IMAP server rather than the synchronized local Maildir.
-a|--account
Override the default account.
An account name corresponds to an entry in the table at the root level of your TOML configuration file.
Settings
message.send.backend
Override the backend used for sending messages.
# valid backends: smtp, sendmail
message.send.backend = "smtp"
message.send.save-copy
Should save a copy to the sent folder of the message being sent.
message.send.save-copy = true
message.send.pre-hook
The hook called just before sending a message.
The command should take a raw message as standard input (stdin) and returns the modified raw message to the standard output (stdout).
message.send.pre-hook = "process-markdown.sh"
Example
$ cat /tmp/email.eml | himalaya message send
$ himalaya message send < /tmp/email.eml
$ himalaya message send 'From: alice@localhost
To: bob@localhost
Subject: Hello
Hello, world!'
Copy a message
$ himalaya message copy [OPTIONS] <FROM> <TO> <ID>...
Copy a message from a source folder to a target folder.
Options
--disable-cache
Disable any sort of cache.
The action depends on commands it apply on. For example, when listing envelopes using the IMAP backend, this flag will ensure that envelopes are fetched from the IMAP server rather than the synchronized local Maildir.
-a|--account
Override the default account.
An account name corresponds to an entry in the table at the root level of your TOML configuration file.
Settings
message.copy.backend
Override the backend used for copying messages.
# valid backends: maildir, imap, notmuch
message.copy.backend = "imap"
Move a message
$ himalaya message move [OPTIONS] <FROM> <TO> <ID>...
Move a message from a source folder to a target folder.
Options
--disable-cache
Disable any sort of cache.
The action depends on commands it apply on. For example, when listing envelopes using the IMAP backend, this flag will ensure that envelopes are fetched from the IMAP server rather than the synchronized local Maildir.
-a|--account
Override the default account.
An account name corresponds to an entry in the table at the root level of your TOML configuration file.
Settings
message.move.backend
Override the backend used for moving messages.
# valid backends: maildir, imap, notmuch
message.move.backend = "imap"
Delete a message
$ himalaya message delete [OPTIONS] <ID>...
Mark as deleted a message from a folder.
This command does not really delete the message: if the given folder points to the trash folder, it adds the “deleted” flag to its envelope, otherwise it moves it to the trash folder. Only the expunge folder command truly deletes messages.
Options
-f|--folder
The name of the folder.
--disable-cache
Disable any sort of cache.
The action depends on commands it apply on. For example, when listing envelopes using the IMAP backend, this flag will ensure that envelopes are fetched from the IMAP server rather than the synchronized local Maildir.
-a|--account
Override the default account.
An account name corresponds to an entry in the table at the root level of your TOML configuration file.
Settings
message.delete.style
Override the message deletion style.
Message deletion can be performed either by moving messages to the Trash folder or by adding the Deleted flag to their respective envelopes.
# valid style: folder, flag
message.delete.style = "folder"
Attachments
An attachment is a MIME part where either:
- The
Content-Disposition
header isattachment
- The
Content-Disposition
header isinline
with afilename
parameter defined.
All other parts (inline without filename, form data, extensions etc) are not considered attachments.
Attachments can be managed with those commands:
Download attachments
$ himalaya attachment download [OPTIONS] <ID>...
Downloads all attachments found in message(s) matching the given envelope id(s) to your downloads directory.
Options
-f|--folder
The name of the folder.
--disable-cache
Disable any sort of cache.
The action depends on commands it apply on. For example, when listing envelopes using the IMAP backend, this flag will ensure that envelopes are fetched from the IMAP server rather than the synchronized local Maildir.
-a|--account
Override the default account.
An account name corresponds to an entry in the table at the root level of your TOML configuration file.
Settings
downloads-dir
The downloads directory.
It is mostly used for downloading messages attachments. Defaults to the system temporary directory (usually /tmp
).
downloads-dir = "~/Downloads"
Templates
A template is a simplified representation of a message based on the MIME Meta Language. Templates allow you to add multiple parts to a message (including binary attachments like images or PDFs) from the body itself, using a simple XML-based language. A template looks like this:
From: alice@localhost
To: bob@localhost
Subject: MML simple
<#multipart type=alternative>
This is a plain text part.
<#part type=text/enriched>
<center>This is a centered enriched part</center>
<#/multipart>
and is compiled into a valid MIME Message:
Subject: MML simple
To: bob@localhost
From: alice@localhost
MIME-Version: 1.0
Date: Tue, 29 Nov 2022 13:07:01 +0000
Content-Type: multipart/alternative;
boundary="4CV1Cnp7mXkDyvb55i77DcNSkKzB8HJzaIT84qZe"
--4CV1Cnp7mXkDyvb55i77DcNSkKzB8HJzaIT84qZe
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 7bit
This is a plain text part.
--4CV1Cnp7mXkDyvb55i77DcNSkKzB8HJzaIT84qZe
Content-Type: text/enriched
Content-Transfer-Encoding: 7bit
<center>This is a centered enriched part</center>
--4CV1Cnp7mXkDyvb55i77DcNSkKzB8HJzaIT84qZe--
See more examples here.
Templates can be managed with those commands:
- Generate write templates
- Generate reply templates
- Generate forward templates
- Save templates
- Send templates
Generate a new template
$ himalaya template write [OPTIONS] [BODY]...
Generate a template for writing a new message from scratch.
The generated template is prefilled with your email address in a From header as well as your signature.
Options
-H|--header
Prefill the template with custom headers (can be repeated).
A raw header should follow the pattern KEY:VAL
.
--disable-cache
Disable any sort of cache.
The action depends on commands it apply on. For example, when listing envelopes using the IMAP backend, this flag will ensure that envelopes are fetched from the IMAP server rather than the synchronized local Maildir.
-a|--account
Override the default account.
An account name corresponds to an entry in the table at the root level of your TOML configuration file.
Generate a reply template
$ himalaya template reply [OPTIONS] <ID> [BODY]...
Generate a template for replying to a message.
The generated template is prefilled with your email in a From header as well as your signature. The replied message is also prefilled in the body of the template, with all lines prefixed by the symbol greater than “>”.
Options
-f|--folder
The name of the folder.
-A|--all
Reply to all recipients.
This argument will add all recipients for the To
and Cc
headers.
-H|--header
Prefill the template with custom headers (can be repeated).
A raw header should follow the pattern KEY:VAL
.
--disable-cache
Disable any sort of cache.
The action depends on commands it apply on. For example, when listing envelopes using the IMAP backend, this flag will ensure that envelopes are fetched from the IMAP server rather than the synchronized local Maildir.
-a|--account
Override the default account.
An account name corresponds to an entry in the table at the root level of your TOML configuration file.
Generate a forward template
$ himalaya template forward [OPTIONS] <ID> [BODY]...
Generate a template for forwarding a message.
The generated template is prefilled with your email in a From header as well as your signature. The forwarded message is also prefilled in the body of the template, prefixed by a separator.
Options
-f|--folder
The name of the folder.
-H|--header
Prefill the template with custom headers (can be repeated).
A raw header should follow the pattern KEY:VAL
.
--disable-cache
Disable any sort of cache.
The action depends on commands it apply on. For example, when listing envelopes using the IMAP backend, this flag will ensure that envelopes are fetched from the IMAP server rather than the synchronized local Maildir.
-a|--account
Override the default account.
An account name corresponds to an entry in the table at the root level of your TOML configuration file.
Save a template
$ himalaya template save [OPTIONS] [TEMPLATE]...
Save a template to a folder.
This command allows you to save a template to the given folder. The template is compiled into a MIME message before being saved to the folder. If you want to save a raw message, use the message save command instead.
Options
-f|--folder
The name of the folder.
--disable-cache
Disable any sort of cache.
The action depends on commands it apply on. For example, when listing envelopes using the IMAP backend, this flag will ensure that envelopes are fetched from the IMAP server rather than the synchronized local Maildir.
-a|--account
Override the default account.
An account name corresponds to an entry in the table at the root level of your TOML configuration file.
Examples
$ cat ~/email.eml | himalaya template save --folder Archives
$ himalaya template save --folder Archives < ~/email.eml
Send a template
$ himalaya template send [OPTIONS] [TEMPLATE]...
This command allows you to send a template and save a copy to the sent folder. The template is compiled into a MIME message before being sent. If you want to send a raw message, use the message send command instead.
Options
--disable-cache
Disable any sort of cache.
The action depends on commands it apply on. For example, when listing envelopes using the IMAP backend, this flag will ensure that envelopes are fetched from the IMAP server rather than the synchronized local Maildir.
-a|--account
Override the default account.
An account name corresponds to an entry in the table at the root level of your TOML configuration file.
Examples
$ cat ~/email.eml | himalaya template send
$ himalaya template send < ~/email.eml
IMAP configuration
imap.host
(required)
Represents the IMAP server hostname.
imap.port
(required)
Represents the IMAP server port.
imap.login
(required)
Represents the IMAP account login.
imap.passwd/oauth2
(required)
The IMAP account authentication mechanism:
-
imap.passwd
: Regular password authentication.-
imap.passwd.raw
: Raw password (unsafe, not recommanded). [string] -
imap.passwd.cmd
: Password retrieved from the given shell command. [string] -
imap.passwd.keyring
: Password retrieved from your system’s default password manager at the given entry. [string]
-
-
imap.oauth2
: OAuth 2.0 authorization mechanism. This mechanism requires additional options:-
imap.oauth2.client-id
(required): Client identifier issued to the client during the registration process described by Section 2.2. [string] -
imap.oauth2.auth-url
(required): URL of the authorization server’s authorization endpoint. [string] -
imap.oauth2.token-url
(required): URL of the authorization server’s token endpoint. [string] -
imap.oauth2.method
: OAuth 2.0 authentication method. Default:XOAUTH
. [XOAUTH|OAUTHBEARER] -
imap.oauth2.client-secret
: Override how the client secret is retrieved:-
imap.oauth2.client-secret.raw
: Raw client secret (unsafe, not recommanded). [string] -
imap.oauth2.client-secret.cmd
: Client secret retrieved from the given shell command. [string] -
imap.oauth2.client-secret.keyring
: Client secret retrieved from your system’s default password manager at the given entry. [string]
If omitted, the client secret is retrieves from your system’s default password manager at the entry
<account-name>-imap.oauth2-client-secret
. -
-
imap.oauth2.access-token
: Override how the access token is retrieved:-
imap.oauth2.access-token.raw
: Raw access token (for debugging purpose). [string] -
imap.oauth2.access-token.cmd
: Access token retrieved from the given shell command. [string] -
imap.oauth2.access-token.keyring
: Access token retrieved from your system’s default password manager at the given entry. [string]
If omitted, the access token is retrieves from your system’s default password manager at the entry
<account-name>-imap.oauth2-access-token
. -
-
imap.oauth2.refresh-token
: Override how the refresh token is retrieved:-
imap.oauth2.refresh-token.raw
: Raw refresh token (for debugging purpose). [string] -
imap.oauth2.refresh-token.cmd
: Refresh token retrieved from the given shell command. [string] -
imap.oauth2.refresh-token.keyring
: Refresh token retrieved from your system’s default password manager at the given entry. [string]
If omitted, the refresh token is retrieves from your system’s default password manager at the entry
<account-name>-imap.oauth2-refresh-token
. -
-
imap.oauth2.pkce
: Enable the Proof Key of Code Exchange. [bool] -
imap.oauth2.scope
: Access token scope, as defined by the authorization server. Variants possible:-
imap.oauth2.scope
: One scope. [string] -
imap.oauth2.scopes
: One or more scopes. [list[string]]
-
-
imap.encryption
The IMAP encryption protocol to use.
-
imap.encryption = "tls" | true
(default): use required encryption (SSL/TLS). -
imap.encryption = "start-tls"
: use opportunistic encryption (StartTLS). -
imap.encryption = "none" | false
: do not use any encryption.
imap.watch.timeout
Customize the timeout used to refresh the IMAP IDLE command in background.
Defaults to 29 min as defined in the RFC.
Examples
backend = "imap"
imap.host = "imap.localhost"
imap.port = 993
imap.login = "test@localhost"
imap.encryption = "tls"
imap.auth = "passwd"
# you can use directly your password from the config (unsafe, not recommanded):
imap.passwd.raw = "<your-password>"
# you can retrieve your app password via a shell command:
imap.passwd.cmd = "pass show my-account"
# supports pipelines:
imap.passwd.cmd = ["pass show my-account", "head -1"]
# you can also use the keyring system and override the entry name:
imap.passwd.keyring = "my-account-imap.passwd"
backend = "imap"
imap.host = "imap.localhost"
imap.port = 993
imap.login = "test@localhost"
imap.auth = "oauth2"
imap.oauth2.client-id = "my-oauth2-client-id"
imap.oauth2.auth-url = "http://localhost/oauth2/auth"
imap.oauth2.token-url = "http://localhost/oauth2/token"
imap.oauth2.pkce = true
imap.oauth2.scope = "all"
imap.encryption = true
Maildir configuration
maildir.root-dir
(required)
The Maildir root directory.
The path should point to the root level of the Maildir directory (the one containing the cur
, new
and tmp
folders). Path is shell-expanded, which means environment variables and tilde ~
are replaced by their values.
Note: with the Maildir backend, the folder.alias
option can contain path to other Maildir folders. For example, if your inbox is located at /my/maildir
and your sent folder at /my/maildir/sent
, then you can set up this kind of alias:
maildir.root-dir = "/my/maildir"
folder.alias.inbox = "/my/maildir"
folder.alias.sent = "/my/maildir/sent"
Notmuch configuration
To activate this backend, you need to:
- Compile himalaya from sources with the notmuch feature enabled:
$ cargo install --features notmuch himalaya
- Have the
libnotmuch
available on your system.
notmuch.database-path
The path to the Notmuch database.
The path should point to the root directory containing the Notmuch database (usually the root Maildir directory). Path is shell-expanded, which means environment variables and tilde ~
are replaced by their values. Defaults to the default Notmuch database location if omitted.
notmuch.maildir-path
Override the default path to the Maildir folder.
Path is shell-expanded, which means environment variables and tilde ~
are replaced by their values. Defaults to database_path
if omitted.
notmuch.config-path
Override the default Notmuch configuration file path.
Path is shell-expanded, which means environment variables and tilde ~
are replaced by their values.
notmuch.profile
Override the default Notmuch profile name.
SMTP configuration
smtp.host
(required)
Represents the SMTP server hostname.
smtp.port
(required)
Represents the SMTP server port.
smtp.login
(required)
Represents the SMTP account login.
smtp.passwd/oauth2
(required)
The SMTP account authentication mechanism:
-
smtp.passwd
: Regular password authentication.-
smtp.passwd.raw
: Raw password (unsafe, not recommanded). [string] -
smtp.passwd.cmd
: Password retrieved from the given shell command. [string] -
smtp.passwd.keyring
: Password retrieved from your system’s default password manager at the given entry. [string]
-
-
smtp.oauth2
: OAuth 2.0 authorization mechanism. This mechanism requires additional options:-
smtp.oauth2.client-id
(required): Client identifier issued to the client during the registration process described by [Section 2.2]. [string] -
smtp.oauth2.auth-url
(required): URL of the authorization server’s authorization endpoint. [string] -
smtp.oauth2.token-url
(required): URL of the authorization server’s token endpoint. [string] -
smtp.oauth2.method
: OAuth 2.0 authentication method. Default:XOAUTH
. [XOAUTH|OAUTHBEARER] -
smtp.oauth2.client-secret
: Override how the client secret is retrieved:-
smtp.oauth2.client-secret.raw
: Raw client secret (unsafe, not recommanded). [string] -
smtp.oauth2.client-secret.cmd
: Client secret retrieved from the given shell command. [string] -
smtp.oauth2.client-secret.keyring
: Client secret retrieved from your system’s default password manager at the given entry. [string]
If omitted, the client secret is retrieves from your system’s default password manager at the entry
<account-name>-smtp.oauth2-client-secret
. -
-
smtp.oauth2.access-token
: Override how the access token is retrieved:-
smtp.oauth2.access-token.raw
: Raw access token (for debugging purpose). [string] -
smtp.oauth2.access-token.cmd
: Access token retrieved from the given shell command. [string] -
smtp.oauth2.access-token.keyring
: Access token retrieved from your system’s default password manager at the given entry. [string]
If omitted, the access token is retrieves from your system’s default password manager at the entry
<account-name>-smtp.oauth2-access-token
. -
-
smtp.oauth2.refresh-token
: Override how the refresh token is retrieved:-
smtp.oauth2.refresh-token.raw
: Raw refresh token (for debugging purpose). [string] -
smtp.oauth2.refresh-token.cmd
: Refresh token retrieved from the given shell command. [string] -
smtp.oauth2.refresh-token.keyring
: Refresh token retrieved from your system’s default password manager at the given entry. [string]
If omitted, the refresh token is retrieves from your system’s default password manager at the entry
<account-name>-smtp.oauth2-refresh-token
. -
-
smtp.oauth2.pkce
: Enable the Proof Key of Code Exchange. [bool] -
smtp.oauth2.scope
: Access token scope, as defined by the authorization server. Variants possible:-
smtp.oauth2.scope
: One scope. [string] -
smtp.oauth2.scopes
: One or more scopes. [list[string]]
-
-
smtp.encryption
The SMTP encryption protocol to use.
-
smtp.encryption = "tls" | true
(default): use required encryption (SSL/TLS). -
smtp.encryption = "start-tls"
: use opportunistic encryption (StartTLS). -
smtp.encryption = "none" | false
: do not use any encryption.
Example
message.send.backend = "smtp"
smtp.host = "smtp.localhost"
smtp.port = 465
smtp.login = "test@localhost"
smtp.passwd.raw = "my-unsafe-password"
smtp.encryption = "tls"
message.send.backend = "smtp"
smtp.host = "smtp.localhost"
smtp.port = 587
smtp.login = "test@localhost"
smtp.oauth2-client-id = "my-oauth2-client-id"
smtp.oauth2-auth-url = "http://localhost/oauth2/auth"
smtp.oauth2-token-url = "http://localhost/oauth2/token"
smtp.oauth2-pkce = true
smtp.oauth2-scopes = ["read", "write"]
smtp.encryption = "start-tls"
Sendmail configuration
sendmail.cmd
(required)
Represents the shell command used to send emails.
sendmail.cmd = "/usr/sbin/sendmail"
PGP configuration
pgp.backend
(required)
Customize the PGP backend:
-
pgp.backend = "cmds"
: Use the PGP backend based on shell commands.Note: Himalaya needs to be compiled with the cargo feature
pgp-commands
to activate this backend. -
pgp.backend = "gpg"
: Use the PGP backend based on GPG.Note: Himalaya needs to be compiled with the cargo feature
pgp-gpg
to activate this backend.Note: the
gpgme
lib needs to be available on the system for this backend to work. -
pgp.backend = "native"
: Use the native PGP backend.The native PGP backend is using rPGP, a Rust implementation of the OpenPGP standard.
Note: Himalaya needs to be compiled with the cargo feature
pgp-native
to activate this backend.
Commands-based PGP configuration
Note: Himalaya needs to be compiled with the cargo feature pgp-commands
to activate this backend.
pgp.backend = "gpg"
Enables the PGP backend based on the shell commands.
pgp.encrypt-cmd
Represents the shell command used to encrypt email parts.
Defaults to gpg --encrypt --quiet --armor <recipients>
, where <recipients>
is the placeholder for recipients’ email. See also pgp.encrypt-recipient-fmt
and pgp.encrypt-recipients-sep
.
pgp.encrypt-recipient-fmt
Represents the template string used to format <recipients>
from pgp.encrypt-cmd
. [string]
Defaults to --recipient <recipient>
, where <recipient>
is the placeholder for a recipient’s email.
pgp.encrypt-recipients-sep
Represents the separator used to concatenate all pgp.encrypt-recipient-fmt
. [string]
Defaults to
(space).
pgp.decrypt-cmd
Represents the shell command used to decrypt email parts. [string]
The encrypted email part is send using stdin
. Defaults to gpg --decrypt --quiet
.
pgp.sign-cmd
Represents the shell command used to sign email parts. [string]
The email part to sign is send using stdin
. Defaults to gpg --sign --quiet --armor
.
pgp.verify-cmd
Represents the shell command used to verify email parts. [string]
The signed part is send using stdin
. Defaults to gpg --verify --quiet
.
Examples
[my-account]
pgp.backend = "cmds"
pgp.encrypt-cmd = "gpg --encrypt --quiet --armor <recipients>"
pgp.decrypt-cmd = "gpg --decrypt --quiet"
pgp.sign-cmd = "gpg --sign --quiet --armor"
pgp.verify-cmd = "gpg --verify --quiet"
[my-account.pgp]
backend = "commands" # alias for cmds
encrypt-cmd = "gpg --encrypt --quiet --armor <recipients>"
decrypt-cmd = "gpg --decrypt --quiet"
sign-cmd = "gpg --sign --quiet --armor"
verify-cmd = "gpg --verify --quiet"
GPG configuration
Note: Himalaya needs to be compiled with the cargo feature pgp-gpg
to activate this backend.
Note: the gpgme
lib needs to be available on the system for this backend to work.
pgp.backend = "gpg"
Enables the PGP backend based on the gpgme library.
Examples
[my-account]
pgp.backend = "gpg"
[my-account.pgp]
backend = "gpg"
Native PGP configuration
Note: Himalaya needs to be compiled with the cargo feature pgp-native
to activate this backend.
pgp.backend = "native"
Enable the Rust native PGP backend.
pgp.secret-key
Represents the PGP secret key in its ASCII armored version.
# The secret key is located at the given path
pgp.secret-key.path = "/tmp/secret.key"
# The secret key is located in the user's global keyring at the given entry.
pgp.secret-key.keyring = "secret-entry"
This field is configured via himalaya account configure
.
pgp.secret-key-passphrase
Represents the secret key passphrase.
# Raw passphrase (unsafe, not recommanded)
pgp.secret-key-passphrase.raw = "passphrase"
# Passphrase retrieved from the given shell command
pgp.secret-key-passphrase.cmd = "pass show passphrase"
# Passphrase retrieved from your system's default password manager at the given entry.
pgp.secret-key-passphrase.keyring = "passphrase-entry"
pgp.wkd
Discovers public keys using the Web Key Directory protocol.
pgp.wkd = true
pgp.key-servers
Discovers public keys using the given key servers.
Key servers should be valid URLs. Supported schemes:
-
http://
andhttps://
: URL should point to a valid public key. -
hkp://
andhkps://
: URL should point to a valid Web Key Directory service.
pgp.key-servers = ["https://meta.sr.ht/privacy/pubkey", "hkps://keys.openpgp.org"]
Examples
[my-account]
pgp.backend = "native"
pgp.secret-key.path = "~/.pgp/secret.key"
pgp.secret-key-passphrase.cmd = "pass show secret"
pgp.wkd = true
pgp.key-servers = ["hkps://keys.openpgp.org", "hkps://keys.mailvelope.com"]
[my-account.pgp]
backend = "native"
secret-key.keyring = "my-account-pgp-secret-key"
secret-key-passphrase.keyring = "my-account-pgp-secret-key-passphrase"
key-servers = ["https://meta.sr.ht/privacy/pubkey"]
Generate man pages
$ himalaya manual [OPTIONS] <DIR>
Generate manual pages to a directory.
This command allows you to generate manual pages (following the man page format) to the given directory. If the directory does not exist, it will be created. Any existing man pages will be overriden.
Generate completion scripts
$ himalaya completion [OPTIONS] <SHELL>
Print completion script for a shell to stdout.
This command allows you to generate completion script for a given shell. The script is printed to the standard output. If you want to write it to a file, just use unix redirection.
Available shells: bash
, elvish
, fish
, powershell
, zsh
.
FAQ
How different is Himalaya CLI from aerc or Mutt?
This tool is a CLI, not a TUI. There is no main loop that blocks your terminal. Instead you run shell commands to interact with your emails.
The other difference is that Himalaya CLI tries not to reinvent the wheel by using email-lib, which contains all the logic associated to email management. Himalaya CLI does not contain any logic related to IMAP or SMTP, it focuses instead on the User Interface.
How can I debug Himalaya CLI?
The simplest way is to use --debug
and --trace
arguments.
The advanced way is based on environment variables:
RUST_LOG=<level>
: determine the log level filter, can be one ofoff
,error
,warn
,info
,debug
andtrace
.RUST_SPANTRACE=1
: enables the spantrace (a span represent periods of time in which a program was executing in a particular context).RUST_BACKTRACE=1
: enables the error backtrace.RUST_BACKTRACE=full
: enables the full error backtrace, which include source lines where the error originated from.
Logs are written to the stderr
, which means that you can redirect them easily to a file:
RUST_LOG=debug himalaya 2>/tmp/himalaya.log
How the wizard discovers IMAP and SMTP configs?
All the lookup mechanisms use the email address domain as base for the lookup. It is heavily inspired from the Thunderbird Autoconfiguration protocol. For example, for the email address test@example.com
, the lookup is performed as (in this order):
- check for
autoconfig.example.com
- look up of
example.com
in the ISPDB (the Thunderbird central database) - look up
MX example.com
in DNS, and formx1.mail.hoster.com
, look uphoster.com
in the ISPDB - look up
SRV example.com
in DNS - try to guess (
imap.example.com
,smtp.example.com
…)
How to save a copy of a sent message?
Add the following option in your configuration:
message.send.save-copy = true
This option is disabled by default, because some email providers automatically save copies of sent messages.
Feel free to send any suggestion at ~soywod/pimalaya@lists.sr.ht.