Permalink
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

Paths

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 = [
  ~/bin
  $E:GOPATH/bin
  $E:RACKETPATH/bin
  /usr/local/opt/coreutils/libexec/gnubin
  /usr/local/opt/python/libexec/bin
  ~/Dropbox/Personal/devel/hammerspoon/spoon/bin
  ~/.gem/ruby/2.4.0/bin
  /opt/X11/bin
  /Library/TeX/texbin
  /usr/local/bin
  /usr/local/sbin
  /usr/sbin
  /sbin
  /usr/bin
  /bin
]

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   \
  github.com/zzamboni/elvish-modules     \
  github.com/zzamboni/elvish-completions \
  github.com/zzamboni/elvish-themes      \
  github.com/xiaq/edit.elv               \
  github.com/muesli/elvish-libs          \
  github.com/iwoloschin/elvish-packages

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.

use github.com/zzamboni/elvish-modules/proxy
proxy:host = "http://proxy.corproot.net:8079"

Next, we set the test function to enable proxy auto-setting. In my case, the /etc/resolv.conf file contains the corproot.net 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).*(corproot.net|swissptt.ch)' /etc/resolv.conf)
}

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

proxy:autoset

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~
        

Aliases

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.

use github.com/zzamboni/elvish-modules/alias

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

Completions

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.

use github.com/xiaq/edit.elv/smart-matcher
smart-matcher:apply

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:

use github.com/zzamboni/elvish-completions/vcsh
use github.com/zzamboni/elvish-completions/cd
use github.com/zzamboni/elvish-completions/ssh
use github.com/zzamboni/elvish-completions/builtins

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

use github.com/zzamboni/elvish-completions/git
git:git-command = hub
git:init

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

use github.com/zzamboni/elvish-completions/comp

Prompt theme

I use the chain prompt theme, ported from the fish theme at https://github.com/oh-my-fish/theme-chain.

use github.com/zzamboni/elvish-themes/chain
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.

use github.com/zzamboni/elvish-modules/long-running-notifications

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.

use github.com/zzamboni/elvish-modules/bang-bang

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.

use github.com/zzamboni/elvish-modules/dir
alias:new cd &use=[github.com/zzamboni/elvish-modules/dir] dir:cd
alias:new cdb &use=[github.com/zzamboni/elvish-modules/dir] 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 Terminal.app 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.

use github.com/zzamboni/elvish-modules/terminal-title

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.

use github.com/zzamboni/elvish-modules/atlas

OpsGenie

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

use github.com/zzamboni/elvish-modules/opsgenie

LeanPub

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

use github.com/zzamboni/elvish-modules/leanpub

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.

use github.com/zzamboni/elvish-modules/util

I use muesli’s git utilities module.

use github.com/muesli/elvish-libs/git

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

use github.com/iwoloschin/elvish-packages/update
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)