Switch branches/tags
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
208 lines (156 sloc) 6.75 KB

Automatic proxy settings for Elvish

Manipulation of proxy-related environment variables (including auto-setting/unsetting based on a user-defined test) for Elvish.

This file is written in literate programming style, to make it easy to explain. See proxy.elv for the generated file.

Table of Contents


Install the elvish-modules package using epm:

use epm

In your rc.elv, load this module:


Set your default proxy host (including port number) by assigning it to the $proxy:host variable. For example:

proxy:host = ""

You can now manually set/unset the proxy environment variables by calling proxy:set and proxy:unset, respectively.

For now only the http_proxy and https_proxy environment variables are set.

If you want to enable automatic proxy switching, you need to define a check function and assign it to the $proxy:test variable. It should be a lambda which receives no arguments, and returns a true/false value. When the function returns true, the proxy will be set. For example, the following function will set the proxy whenever /etc/resolv.conf contains any search or domain definitions ending in “”:

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

If you want to temporarily disable the proxy auto-set function in the current session after having defined a test function, you can run the proxy:disable command. Use proxy:enable to reenable it when needed. Note that proxy:disable also unsets the proxy variables.



We use the prompt-hooks library to set up the hooks for the auto-set feature.

use ./prompt-hooks


The $proxy:host variable contains the proxy host to used by default, in “http://host:port” format.

host = ""

$proxy:test contains the auto-set test function. It must be either $false (to disable auto-setting) or a lambda which receives no arguments, and return a true value (anything except $false or an error, as per Elvish’s booleanly interpretation of values) when the proxy needs to be automatically set, false otherwise.

To enable auto-setting you must override it with code that performs a meaningful check for your needs.

test = $false

Whether to print notifications when setting/unsetting the proxy.

notify = $true

Whether autoset should be disabled (useful for temporarily stopping the automatic proxy setting using proxy:disable).

disable-autoset = $false

The list of environment variables to set. By default only http_proxy and https_proxy are set.

env-vars = [ http_proxy https_proxy ]


Elvish does not include an eval function, but we emulate one using the -source command. We use this to dynamically query and set the variables according to the contents of $proxy:env-vars.

fn eval [str]{
  tmpf = (mktemp)
  echo $str > $tmpf
  -source $tmpf
  rm -f $tmpf

Check whether the proxy is set. We use the first variable in $proxy:env-vars for the check, with the assumption that the other variables follow. The need to dynamically determine which variable to check makes this function a bit tricky - basically we create a temporary file (using the mktemp command), and then evaluate code that removes the file if the proxy variable is unset - then the existence of the file indicates the setting of the variable.

fn is-set {
  -tmp-file = (mktemp)
  eval "if (eq $E:"(take 1 $env-vars)" '') { rm "$-tmp-file" }"
  -res = (bool ?(test -f $-tmp-file))
  rm -f $-tmp-file
  put $-res

Set the proxy variables to the given string. If no parameters are given but $proxy:host is set, then its value is used. Note that passing an argument to this function does not set $param:host, this needs to be done explicitly if you want it.

fn set [@param]{
  proxyhost = $host
  if (> (count $param) 0) {
    proxyhost = $param[0]
  if (not-eq $proxyhost "") {
    eval (each [var]{ put "E:"$var" = "$host } $env-vars | joins "; ")

Unset the proxy variables.

fn unset {
  eval (each [var]{ put "del E:"$var } $env-vars | joins "; ")

Disable auto-set and unset the proxy.

fn disable {
  disable-autoset = $true

Enable auto-set after it had been disabled using proxy:disable-autoset.

fn enable {
  disable-autoset = $false

This is the function that powers the auto-set feature. It runs $proxy:test and sets/unsets the variables depending on the result.

fn autoset [@_]{
  if (or (not $test) $disable-autoset) {
  if ($test) {
    if (and $host (not (eq $host ""))) {
      if (and $notify (not (is-set))) {
        echo (styled "Setting proxy "$host blue) > /dev/tty
    } else {
      fail "You need to set $proxy:host to the proxy to use"
  } else {
    if (and $notify (is-set)) {
      echo (styled "Unsetting proxy" blue) > /dev/tty

The proxy:init function adds the proxy:autoset function to both the before- and after-command hooks.

fn init {
  prompt-hooks:add-before-readline $autoset~
  prompt-hooks:add-after-readline $autoset~

We call init automatically on module load.