Switch branches/tags
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
381 lines (271 sloc) 15.5 KB

My Elvish config file

This is my main config file for Elvish.

This file is written in literate programming style using org-mode. See rc.elv for the generated file. You can see this in a nicer format on my blog post My Elvish Configuration With Commentary.

Table of Contents


First we set up the executable paths. We set the GOPATH environment variable while we are at it, since we need to use it as part of the path.

E:GOPATH = ~/Dropbox/Personal/devel/go
E:RACKETPATH = ~/Library/Racket/7.1
paths = [

Package installation

The bundled epm module allows us to install and manage Elvish packages.

use epm

For now I use these packages:

epm:install &silent-if-installed=$true   \     \ \      \               \          \

The modules within each package get loaded individually below.

Automatic proxy settings

When I am in the office, I need to use a proxy to access the Internet. For macOS applications, the proxy is set automatically using a company-provided PAC file. For the environment variables http_proxy and https_proxy, commonly used by command-line programs, the proxy module allows me to define a test which determines when the proxy should be used, so that the change is done automatically. We load this early on so that other modules which need to access the network get the correct settings already.

First, we load the module and set the proxy host.

proxy:host = ""

Next, we set the test function to enable proxy auto-setting. In my case, the /etc/resolv.conf file contains the domain (set through DHCP) when I’m in the corporate network, so I can check for that.

proxy:test = {
  and ?(test -f /etc/resolv.conf) \
  ?(egrep -q '^(search|domain).*(|' /etc/resolv.conf)

We run an initial check so that other commands in get the correctd settings already, even before the first prompt.


Base modules

Load the bundled re module to have access to regular expression functions.

use re

The bundled readline-binding module associates some Emacs-like keybindings for manipulation of the command line.

use readline-binding

I add a couple of keybindings which are missing from the default readline-binding module:

  • Alt-backspace to delete small-word
    edit:insert:binding[Alt-Backspace] = $edit:kill-small-word-left~
  • Alt-d to delete the small-word under the cursor
    edit:insert:binding[Alt-d] = $edit:kill-small-word-right~


Elvish does not have built-in alias functionality, but this is implemented easily using the alias module, which stores the alias definitions as functions under ~/.elvish/aliases/ and loads them automatically.


For reference, I define here a few of my commonly-used aliases:

alias:new dfc e:dfc -W -l -p -/dev/disk1s4,devfs
alias:new ls e:ls --color=auto
alias:new more less
alias:new v vagrant


The smart-matcher module tries prefix match, smart-case prefix match, substring match, smart-case substring match, subsequence match and smart-case subsequence match automatically.


Other possible values for edit:completion:matcher are [p]{ edit:match-prefix &smart-case $p } for smart-case completion (if your pattern is entirely lower case it ignores case, otherwise it’s case sensitive). &smart-case can be replaced with &ignore-case to make it always case-insensitive.

I also configure Tab to trigger completion mode, but also to automatically enter “filter mode”, so I can keep typing the filename I want, without having to use the arrow keys. Disabled as this is the default behavior starting with commit b24e4a7, but you may need it if you are running an older version for any reason and want this behavior.

edit:insert:binding[Tab] = { edit:completion:smart-start; edit:completion:trigger-filter }

I load some command-specific completions from the elvish-completions package:


I configure the git completer to use hub instead of git (if you use plain git, you don’t need to call git:init)

git:git-command = hub

This is not usually necessary, but I load the comp library specifically since I do a lot of tests and development of completions.


Prompt theme

I use the chain prompt theme, ported from the fish theme at

chain:bold-prompt = $true

I set the color of the directory segment, the prompt chains and the prompt arrow in my prompt to a session-identifying color.

chain:segment-style = [
  &dir=          session
  &chain=        session
  &arrow=        session
  &git-combined= session

Elvish has a comprehensive mechanism for displaying prompts with useful information while avoiding getting blocked by prompt functions which take too long to finish. For the most part the defaults work well. One change I like to make is to change the stale prompt transformer function to make the prompt dim when stale:

edit:prompt-stale-transform = { each [x]{ styled $x[text] "gray" } }

Another possibility is to make the prompt stay the same when stale - useful to avoid distractions (disabled for now):

edit:prompt-stale-transform = $all~

I also like the continuous update of the prompt as I type (by default it only updates on Enter and on $pwd changes, but I like also git status changes to be updated automatically), so I increase its eagerness.

edit:-prompt-eagerness = 10

Long-running-command notifications

The long-running-notifications module allows for producing a notification when a command takes longer than a certain time to finish (by default the period is 10 seconds). The module automatically detects when terminal-notifier is available on macOS and uses it to produce Mac-style notifications, otherwise it prints a notification on the terminal.


Directory and command navigation and history

Elvish comes with built-in location and command history modes, and these are the main mechanism for accessing prior directories and commands. The weight-keeping in location mode makes the most-used directories automatically raise to the top of the list over time.

I have decades of muscle memory using !! and !$ to insert the last command and its last argument, respectively. The bang-bang module allows me to keep using them.


The dir module implements a directory history and some related functions. I alias the cd command to dir:cd so that any directory changes are kept in the history. I also alias cdb to dir:cdb function, which allows changing to the base directory of the argument.

alias:new cd &use=[] dir:cd
alias:new cdb &use=[] dir:cdb

dir also implements a narrow-based directory history chooser, which I bind to Alt-i (I have found I don’t use this as much as I thought I would - the built-in location mode works nicely).

edit:insert:binding[Alt-i] = $dir:history-chooser~

I bind Alt-b/f to dir:left-small-word-or-prev-dir and dir:right-small-word-or-next-dir respectively, which “do the right thing” depending on the current content of the command prompt: if it’s empty, they move back/forward in the directory history, otherwise they move through the words of the current command. In my setup, Alt-left/right also produce Alt-b/f, so these bindings work for those keys as well.

edit:insert:binding[Alt-b] = $dir:left-small-word-or-prev-dir~
edit:insert:binding[Alt-f] = $dir:right-small-word-or-next-dir~

Dynamic terminal title

The terminal-title module handles setting the terminal title dynamically according to the current directory or the current command being executed.


Loading private settings

The private module sets up some private settings such as authentication tokens. This is not on github :) The $private-loaded variable gets set to $ok if the module was loaded correctly.

private-loaded = ?(use private)

O’Reilly Atlas

I sometimes use the O’Reilly Atlas publishing platform. The atlas module contains some useful functions for triggering and accessing document builds.



I use OpsGenie at work, so I have put together the opsgenie library to make API operations easier.



I use LeanPub for publishing my books, so I have written a few utility functions.


Environment variables

Default options to less.

E:LESS = "-i -R"

Use vim as the editor from the command line (although I am an Emacs fan, I still sometimes use vim for quick editing).

E:EDITOR = "vim"

Locale setting.

E:LC_ALL = "en_US.UTF-8"

Utility functions

The util module includes various utility functions.


I use muesli’s git utilities module.


The update.elv package prints a message if there are new commits in Elvish after the running version.

update:curl-timeout = 3
update:check-commit &verbose

Work-specific stuff

I have a private library which contains some work-specific functions.

use swisscom

Exporting aliases

We populate $-exports- with the alias definitions so that they become available in the interactive namespace.

-exports- = (alias:export)