edit | ||
eval | ||
glob | ||
parse | ||
run | ||
store | ||
stub | ||
stubimpl | ||
sys | ||
util | ||
.gitattributes | ||
.gitignore | ||
.travis.yml | ||
CONTRIBUTING.md | ||
Dockerfile | ||
LICENSE | ||
main.go | ||
Makefile | ||
README.md |
A novel Unix shell
This project aims to explore the potentials of the Unix shell. It is a work in progress; things will change without warning.
The issues list contains many things I'm working on.
Screenshot
Elvish looks like this:
Prebuilt binaries
Up-to-date binaries for 64-bit Linux and Mac OS X. Download the archive and install with sudo tar vxfz elvish-*.tar.gz -C /usr/bin
.
See also Building Elvish.
Getting Started
Put your startup script in ~/.elvish/rc.elv
.
Elvish mimics bash and zsh in a lot of places. The following shows some key differences and highlights, as well as some common tasks:
-
Press Up to search through history. It uses what you have typed to do prefix match. To cancel, press Escape.
-
Press Tab to start completion. Press Ctrl-N to start navigation mode. Likewise, pressing Escape gets you back to the default mode.
-
Define aliases like
fn ls { external:ls --color $@ }
-
Lists look like
[a b c]
, and maps look like[&key1=value1 &key2=value2]
. Unlike other shells, lists never expands to multiple words, unless you explicitly splice it by prefixing the variable name with$@
:~> li=[1 2 3] ~> for x in $li; do echo $x; done [1 2 3] ~> for x in $@li; do echo $x; done 1 2 3
-
You can manipulate search paths through the special list
$paths
:~> echo $paths [/bin /sbin] ~> paths=[/opt/bin $@paths /usr/bin] ~> echo $paths [/opt/bin /bin /sbin /usr/bin] ~> echo $env:PATH /opt/bin:/bin:/sbin:/usr/bin
-
You can manipulate the keybinding through the map
$le:binding
, which is indexed by the mode name and then by the key name.For example, this binds Ctrl-L to clearing the terminal:
le:binding[insert][Ctrl-L]={ clear > /dev/tty }
(yes, the braces enclose a lambda).Use
put $le:binding
to get a pretty-printed (albeit long) view of the current keybinding. -
Environment variables live in a separate
env:
namespace and must be explicitly qualified:~> put $env:HOME ▶ /home/xiaq ~> env:PATH=$env:PATH":/bin"
-
There is builtin directory history. Use
dirs
to show the history.jump x
jumps to the highest-scored directory containinga
. -
There is no interpolation inside double quotes (yet). Use implicit string concatenation:
~> name=xiaq ~> echo "My name is "$name"." My name is xiaq.
-
A few arithmetic operations are builtin. However, you need to use prefix notation:
~> + 1 2 ▶ 3 ~> mul `+ 1 2` 3 ▶ 9
-
Functions are defined with
fn
. You can name arguments in the definition:~> fn square [x]{ mul $x $x } ~> square 4 ▶ 16
-
Output of some builtin commands start with a funny "▶". It is not part of the output itself, but shows that such commands output a stream of values instead of bytes. As such, their internal structures as well as boundaries between valued are preserved. This allows us to manipulate structured data in the shell.
More Screenshots:
Tab completion:
Navigation mode:
Building Elvish
Go >= 1.5 is required. Linux is fully supported. It is likely to work on BSDs and Mac OS X. Windows is not supported yet.
The main binary can be installed using go get github.com/elves/elvish
. There is also an auxiliary program called elvish-stub; install it with make stub
. Elvish is funtional without the stub, but job control features depend on it.
If you are lazy and use bash
for zsh
now, here is something you can copy-paste into your terminal:
export GOPATH=$HOME/go
export PATH=$PATH:$GOPATH/bin
mkdir -p $GOPATH
go get github.com/elves/elvish
make -C $GOPATH/src/github.com/elves/elvish stub
for f in ~/.bashrc ~/.zshrc; do
echo -e 'export GOPATH=$HOME/go\nexport PATH=$PATH:$GOPATH/bin' >> $f
done
How To Write Go Code explains how $GOPATH
works.
Name
In roguelikes, items made by the elves have a reputation of high quality. These are usually called elven items, but I chose elvish for an obvious reason.
The adjective for elvish is also "elvish", not "elvishy" and definitely not "elvishish".
Test coverages:
Package | Coverage |
---|---|
edit | |
eval | |
glob | |
parse | |
run | |
store | |
stub | |
sys | |
util |