2016-01-27 07:11:55 +08:00
# A novel Unix shell
2013-06-16 16:45:22 +08:00
2014-10-30 08:06:42 +08:00
[![GoDoc ](http://godoc.org/github.com/elves/elvish?status.svg )](http://godoc.org/github.com/elves/elvish)
2016-02-12 10:51:20 +08:00
[![Build Status on Travis ](https://travis-ci.org/elves/elvish.svg?branch=master )](https://travis-ci.org/elves/elvish)
2014-01-31 21:02:49 +08:00
2016-01-27 07:11:55 +08:00
This project aims to explore the potentials of the Unix shell. It is a work in
progress; things will change without warning.
## The Interface
2014-01-08 19:07:34 +08:00
Syntax highlighting (also showcasing right-hand-side prompt):
2016-01-29 09:22:29 +08:00
![syntax
highlighting](https://raw.githubusercontent.com/elves/images/master/syntax.png)
2014-01-08 19:07:34 +08:00
2014-03-08 16:31:59 +08:00
Tab completion for files:
2014-01-08 19:07:34 +08:00
2016-01-29 09:22:29 +08:00
![tab completion ](https://raw.githubusercontent.com/elves/images/master/completion.png )
2014-01-08 19:07:34 +08:00
2014-03-08 16:35:50 +08:00
Navigation mode (triggered with ^N, inspired by
[ranger ](http://ranger.nongnu.org/ )):
2014-03-08 16:31:59 +08:00
2016-01-29 09:22:29 +08:00
![navigation mode ](https://raw.githubusercontent.com/elves/images/master/navigation.png )
2014-03-08 16:31:59 +08:00
2013-12-29 15:04:37 +08:00
2016-01-27 07:11:55 +08:00
Planned features:
2013-12-29 15:04:37 +08:00
2016-01-27 07:11:55 +08:00
* Auto-suggestion (like fish)
2013-12-29 15:04:37 +08:00
* Programmable line editor
2016-01-27 07:11:55 +08:00
* Directory jumping (#27)
2013-12-29 15:04:37 +08:00
* A vi keybinding that makes sense
2016-01-27 07:11:55 +08:00
* History listing (like
[ptpython ](https://github.com/jonathanslenders/ptpython ))
* Intuitive multiline editing
2013-12-29 15:04:37 +08:00
2014-01-24 11:21:49 +08:00
## The Language
2013-12-29 15:04:37 +08:00
2016-01-27 07:11:55 +08:00
Some things that the language is already capable of:
2013-12-29 15:20:49 +08:00
2016-01-27 07:19:48 +08:00
* External programs and pipelines: (`~>` is the prompt):
2013-12-29 15:12:01 +08:00
```
2015-01-27 03:56:07 +08:00
~> vim README.md
2013-12-29 15:20:49 +08:00
...
2015-01-27 03:56:07 +08:00
~> cat -v /dev/random
2013-12-29 15:20:49 +08:00
...
2016-01-27 07:19:48 +08:00
~> dmesg | grep -i acpi
2013-12-29 15:20:49 +08:00
...
2013-12-29 15:12:01 +08:00
```
2016-01-27 07:19:48 +08:00
* Arithmetics using the prefix notation:
2013-12-29 15:07:29 +08:00
```
2015-01-27 03:56:07 +08:00
~> + 1 2
2014-09-21 06:30:26 +08:00
▶ 3
2016-02-07 21:12:19 +08:00
~> mul (+ 1 2) 3
2014-09-21 06:30:26 +08:00
▶ 9
2013-12-29 15:07:29 +08:00
```
2013-12-29 15:04:37 +08:00
2016-01-27 07:19:48 +08:00
* Quoting:
2013-12-29 15:07:29 +08:00
```
2016-01-27 05:18:19 +08:00
~> echo "| C'est pas une pipe."
| C'est pas une pipe.
2013-12-29 15:07:29 +08:00
```
2013-12-29 15:04:37 +08:00
2016-01-27 07:19:48 +08:00
* Lists and maps:
2013-12-29 15:07:29 +08:00
```
2016-02-07 10:56:25 +08:00
~> println list: [a list] map: [& key value]
2016-01-27 05:18:19 +08:00
list: [a list] map: [& key value]
~> println [a b c][0]
2013-12-29 15:07:29 +08:00
a
2016-01-27 05:18:19 +08:00
~> println [& key value][key]
2013-12-29 15:07:29 +08:00
value
```
2013-12-29 15:04:37 +08:00
2016-01-27 07:19:48 +08:00
* Variables:
2013-12-29 15:07:29 +08:00
```
2016-02-07 10:56:25 +08:00
~> v=[& foo bar]; put $v[foo]
2016-01-27 05:18:19 +08:00
▶ bar
2013-12-29 15:07:29 +08:00
```
2013-12-29 15:04:37 +08:00
2016-01-27 07:11:55 +08:00
* Defining functions:
2013-12-29 15:07:29 +08:00
```
2016-02-07 10:56:25 +08:00
~> fn map [f xs]{ put [(put $@xs | each $f)] }
2013-12-29 15:07:29 +08:00
```
2013-12-29 15:04:37 +08:00
2016-01-27 07:11:55 +08:00
* Lisp-like functional programming:
2013-12-29 15:07:29 +08:00
```
2016-01-27 07:11:55 +08:00
~> map [x]{+ 10 $x} [1 2 3]
[11 12 13]
2016-02-07 21:12:19 +08:00
~> map [x]{div $x 2} (map [x]{+ 10 $x} [1 2 3])
2016-01-27 07:11:55 +08:00
[5.5 6 6.5]
2013-12-29 15:07:29 +08:00
```
2013-12-29 15:04:37 +08:00
2016-01-27 07:11:55 +08:00
* More natural concatenative style:
```
2016-02-07 21:12:19 +08:00
~> put 1 2 3 | each [x]{+ 10 $x} | each [x]{div $x 2}
2016-01-27 07:11:55 +08:00
▶ 5.5
▶ 6
▶ 6.5
```
2016-01-27 07:19:48 +08:00
* A separate `env:` namespace for environmental variables:
2013-12-29 15:07:29 +08:00
```
2015-01-27 03:56:07 +08:00
~> put $env:HOME
2015-01-25 07:12:40 +08:00
▶ /home/xiaq
2016-02-09 17:10:30 +08:00
~> env:PATH=$env:PATH":/bin"
2013-12-29 15:07:29 +08:00
```
2013-12-29 15:04:37 +08:00
2016-01-27 07:11:55 +08:00
The language is not yet complete. Notably, control structures like `if` and
`while` are not yet implemented. The issues list contain some of things I'm
currently working on.
2016-02-10 08:16:31 +08:00
## Getting elvish
2016-01-27 07:11:55 +08:00
2016-02-10 08:16:31 +08:00
### Prebuilt binaries
2016-01-27 07:11:55 +08:00
2016-02-10 08:18:06 +08:00
Prebuilt binaries are available for 64-bit [Linux ](https://dl.elvish.io/elvish-linux ) and [Mac OS X ](https://dl.elvish.io/elvish-osx ). They are always built using the latest commit that builds.
2016-01-27 07:11:55 +08:00
2016-02-10 08:16:31 +08:00
### Building It Yourself
2016-01-27 07:11:55 +08:00
2016-02-14 04:14:38 +08:00
Go >= 1.5 is required. This repository is a go-getable package.
2016-01-27 07:11:55 +08:00
2016-02-06 07:49:37 +08:00
Linux and FreeBDS are fully supported. It is likely to work on other BSDs and
Mac OS X. Windows is **not** supported yet.
2013-09-22 18:49:07 +08:00
2016-01-27 07:11:55 +08:00
In case you are new to Go, you are advised to read [How To Write Go
Code](http://golang.org/doc/code.html), but here is a quick snippet:
2013-09-22 18:49:07 +08:00
2016-01-27 07:11:55 +08:00
```
export GOPATH=$HOME/go
export PATH=$PATH:$GOPATH/bin
go get github.com/elves/elvish
elvish
```
2013-09-22 18:49:07 +08:00
2016-01-27 07:11:55 +08:00
To update and rebuild:
2014-01-24 11:21:49 +08:00
2016-01-27 07:11:55 +08:00
```
go get -u github.com/elves/elvish
```
2014-01-24 11:21:49 +08:00
2016-01-27 07:11:55 +08:00
Remember to put the two `export` s above into your `bashrc` or `zshrc` (or
whatever).
## Notes for Contributors
### Testing
Always run unit tests before committing. `make` will take care of this.
### Generated files
Some files are generated from other files. They should be commmited into the
2016-01-29 09:22:29 +08:00
repository for this package to be go-getable. Run `go generate ./...` to
regenerate them in case you modified the source.
2016-01-27 07:11:55 +08:00
### Formatting the Code
Always format the code with `goimports` before committing. Run
2016-01-29 09:22:29 +08:00
`go get golang.org/x/tools/cmd/goimports` to install `goimports` , and
2016-01-27 07:11:55 +08:00
`goimports -w .` to format all golang sources.
To automate this you can set up a `goimports` filter for Git by putting this
in `~/.gitconfig` :
[filter "goimports"]
clean = goimports
smudge = cat
2016-01-29 09:22:29 +08:00
Git will then always run `goimports` for you before comitting, since
`.gitattributes` in this repository refers to this filter. More about Git
2016-01-27 07:11:55 +08:00
attributes and filters
[here ](https://www.kernel.org/pub/software/scm/git/docs/gitattributes.html ).
### Licensing
By contributing, you agree to license your code under the same license as
2016-02-06 07:49:37 +08:00
existing source code of elvish. See the LICENSE file.
2016-02-10 08:16:31 +08:00
## Name
In [roguelikes ](https://en.wikipedia.org/wiki/Roguelike ), 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".
It is not directly related to the fictional
[elvish language ](https://en.wikipedia.org/wiki/Elvish_language ), but I
believe there is not much room for confusion and the google-ability is still
pretty good.