Powerful scripting language & versatile interactive shell add sylixos support.
Go to file
2016-02-23 13:33:38 +01:00
edit Prompt can now be customized by modifying le:{,r}prompt. 2016-02-23 13:24:28 +01:00
eval New builtin "tilde-abbr". 2016-02-23 13:29:10 +01:00
glob Implement an "all" modifier for wildcards; fix tests. 2016-02-23 02:45:35 +01:00
parse Allow newlines in more spaces. 2016-02-22 13:44:56 +01:00
run Prompt can now be customized by modifying le:{,r}prompt. 2016-02-23 13:24:28 +01:00
store Go back to mattn/go-sqlite3. 2016-02-20 03:04:44 +01:00
stub Only use stub when it is alive. 2016-02-23 12:33:32 +01:00
stubimpl Update working directory of elvish-stub. 2016-02-22 18:42:25 +01:00
sys sys: Fix error reporting of Tcsetgrp. 2016-02-21 16:20:01 +01:00
util New builtin "tilde-abbr". 2016-02-23 13:29:10 +01:00
.gitattributes Use .gitattributes to filter go sources through goimports 2014-02-10 12:41:16 +08:00
.gitignore In Makefile, shorten coverage to cover 2014-09-24 23:56:12 +02:00
.travis.yml Give up the attempt of using Travis to upload artifacts. 2016-02-09 23:54:28 +01:00
CONTRIBUTING.md Move the "contributing" section to a shiny CONTRIBUTING.md file 2016-02-19 00:13:35 +01:00
Dockerfile update Dockerfile 2016-02-09 16:43:58 +08:00
LICENSE Project rename: das -> elvish 2014-01-29 18:44:07 +08:00
main.go Put the actual entry function in a new run package. 2016-02-21 12:52:47 +01:00
Makefile Reorganize README; switch to gz for binaries. 2016-02-23 00:44:03 +01:00
README.md Document le:{,r}prompt. 2016-02-23 13:33:38 +01:00

A novel Unix shell

GoDoc Build Status on Travis

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:

syntax highlighting

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:

  • Define aliases like fn ls { external:ls --color $@ }

  • The left and right prompts and be customized by modifying le:prompt and le:rprompt. They can be assigned either to a function, in which their outputs are used, or a constant string. The following simulates the default prompts:

    # Changes during a session; use function
    le:prompt={ echo `tilde-abbr $pwd`'> ' }
    # Doesn't change during a session; use constant string
    le:rprompt=`whoami`@`hostname`
    
  • 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. Use arrow key and Tab to select the candidate; press Enter, or just continue typing to accept. To cancel, press Enter.

  • Press Ctrl-N to start navigation mode. Press Ctrl-H to show hidden files; press again to hide. Likewise, pressing Escape gets you back to the default (insert) mode.

  • Try typing echo [ and press Enter. Elvish knows that the command is unfinished due to the unclosed [ and inserts a newline instead of accepting the command. Moreover, common errors like syntax errors and missing variables are highlighted in real time.

  • Elvish remembers which directories you have visisted. Use dirs to show the history. jump x jumps to the highest-scored directory containing x.

  • 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 23
    ~> 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 416
    
  • 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:

tab completion

Navigation mode:

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 edit
eval eval
glob glob
parse parse
run run
store store
stub stub
sys sys
util util