e90c3fc984
This resolves #114. |
||
---|---|---|
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. 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 $@ }
-
Elvish remembers which directories you have visisted. Use
dirs
to show the history.jump x
jumps to the highest-scored directory containingx
. -
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
. For example, this binds Ctrl-L to clearing the terminal:le:binding[insert][Ctrl-L]={ clear > /dev/tty }
. The first index is the mode and the second is the key. (Yes, the braces enclose a lambda.)Use
put $le:binding
to get a nice (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 no interpolation inside double quotes (yet). Use implicit string concatenation:
~> name=xiaq ~> echo "My name is "$name"." My name is xiaq.
-
Elementary floating-point arithmetics as well as comparisons are builtin. Unfortunately, you have to use prefix notation:
~> + 1 2 ▶ 3 ~> div `mul 2 3` 4 # div for /, mul for * ▶ 1.5 ~> div (mul 2 3) 4 # parentheses are equivalent to backquotes, but look nicer in arithmetics ▶ 1.5 ~> gt 1 2 # gt for > false ~> lt 1 2 # lt for <; silence means "true"
-
Functions are defined with
fn
. You can name arguments:~> 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 on this later.
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 |