Provided by: elvish_0.13+ds1-2ubuntu0.1_amd64 

Introduction
The builtin module contains facilities that are potentially useful to all users. It occupies the
builtin: namespace. You rarely have to explicitly specify the namespace though, since it is one of the
namespaces consulted when resolving unqualified names.
Usage Notation
The usage of a builtin command is described by giving an example usage, using variables as arguments.
For instance, The repeat command takes two arguments and are described as:
repeat $n $v
Optional arguments are represented with a trailing ?, while variadic arguments with a trailing .... For
instance, the count command takes an optional list:
count $input-list?
While the put command takes an arbitrary number of arguments:
put $values...
Options are given along with their default values. For instance, the echo command takes an sep option
and arbitrary arguments:
echo &sep=' ' $value...
(When you calling functions, options are always optional.)
Supplying Input
Some builtin functions, e.g. count and each, can take their input in one of two ways:
1. From pipe:
~> put lorem ipsum | count # count number of inputs
2
~> put 10 100 | each [x]{ + 1 $x } # apply function to each input
▶ 11
▶ 101
Byte pipes are also possible; one line becomes one input:
~> echo "a\nb\nc" | count # count number of lines
▶ 3
2. From an argument -- an iterable value:
~> count [lorem ipsum] # count number of elements in argument
2
~> each [x]{ + 1 $x } [10 100] # apply to each element in argument
▶ 11
▶ 101
Strings, and in future, other sequence types are also possible:
~> count lorem
▶ 5
When documenting such commands, the optional argument is always written as $input-list?. On the other
hand, a trailing $input-list? always indicates that a command can take its input in one of two ways
above: this fact is not repeated below.
Note: You should prefer the first form, unless using it requires explicit put commands. Avoid count
[(some-command)] or each $some-func [(some-command)]; they are, most of the time, equivalent to some-com‐
mand | count or some-command | each $some-func.
Rationale: An alternative way to design this is to make (say) count take an arbitrary number of argu‐
ments, and count its arguments; when there is 0 argument, count inputs. However, this leads to problems
in code like count *; the intention is clearly to count the number of files in the current directory, but
when the current directory is empty, count will wait for inputs. Hence it is required to put the input
in a list: count [*] unambiguously supplies input in the argument, even if there is no file.
Numerical Commands
Commands that operate on numbers are quite flexible about the format of the numbers. Integers can be
specified as decimals (e.g. 233) or hexadecimals (e.g. 0xE9) and floating-point numbers can be speci‐
fied using the scientific notation (e.g. 2.33e2). These are different strings, but equal when consid‐
ered as commands.
Elvish has no special syntax or data type for numbers. Instead, they are just strings. For this reason,
builtin commands for strings and numbers are completely separate. For instance, the numerical equality
command is ==, while the string equality command is ==s. Another example is the + builtin, which only
operates on numbers and does not function as a string concatenation commands.
Predicates
Predicates are functions that write exactly one output that is either $true or $false. They are de‐
scribed like "Determine ..." or "Test ...". See is for one example.
"Do Not Use" Functions and Variables
The name of some variables and functions have a leading -. This is a convention to say that it is sub‐
ject to change and should not be depended upon. They are either only useful for debug purposes, or have
known issues in the interface or implementation, and in the worst case will make Elvish crash. (Before
1.0, all features are subject to change, but those ones are sure to be changed.)
Those functions and variables are documented near the end of the respective sections. Their known prob‐
lem is also discussed.
Builtin Functions
+ - * /
+ $summand...
- $minuend $subtrahend...
* $factor...
/ $dividend $divisor...
Basic arithmetic operations of adding, subtraction, multiplication and division respectively.
All of them can take multiple arguments:
~> + 2 5 7 # 2 + 5 + 7
▶ 14
~> - 2 5 7 # 2 - 5 - 7
▶ -10
~> * 2 5 7 # 2 * 5 * 7
▶ 70
~> / 2 5 7 # 2 / 5 / 7
▶ 0.05714285714285715
When given one element, they all output their sole argument (given that it is a valid number). When giv‐
en no argument,
• + outputs 0, and * outputs 1. You can think that they both have a "hidden" argument of 0 or 1, which
does not alter their behaviors (in mathematical terms, 0 and 1 are identity elements
(https://en.wikipedia.org/wiki/Identity_element) of addition and multiplication, respectively).
• - throws an exception.
• / becomes a synonym for cd /, due to the implicit cd feature. (The implicit cd feature will probably
change to avoid this oddity).
%
% $dividend $divisor
Output the remainder after dividing $dividend by $divisor. Both must be integers. Example:
~> % 23 7
▶ 2
^
^ $base $exponent
Output the result of raising $base to the power of $exponent. Examples:
~> ^ 2 10
▶ 1024
~> ^ 2 0.5
▶ 1.4142135623730951
< <= == != > >=
< $number... # less
<= $number... # less or equal
== $number... # equal
!= $number... # not equal
> $number... # greater
>= $number... # greater or equal
Number comparisons. All of them accept an arbitrary number of arguments:
1. When given fewer than two arguments, all output $true.
2. When given two arguments, output whether the two arguments satisfy the named relationship.
3. When given more than two arguments, output whether every adjacent pair of numbers satisfy the named
relationship.
Examples:
~> == 3 3.0
▶ $true
~> < 3 4
▶ $true
~> < 3 4 10
▶ $true
~> < 6 9 1
▶ $false
As a consequence of rule 3, the != command outputs $true as long as any adjacent pair of numbers are not
equal, even if some numbers that are not adjacent are equal:
~> != 5 5 4
▶ $false
~> != 5 6 5
▶ $true
<s <=s ==s !=s >s >=s
<s $string... # less
<=s $string... # less or equal
==s $string... # equal
!=s $string... # not equal
>s $string... # greater
>=s $string... # greater or equal
String comparisons. They behave similarly to their number counterparts when given multiple arguments.
Examples:
~> >s lorem ipsum
▶ $true
~> ==s 1 1.0
▶ $false
~> >s 8 12
▶ $true
all
all
Pass inputs, both bytes and values, to the output.
This is an identity function in pipelines: a | all | b is equivalent to a | b. It is mainly useful for
turning inputs into arguments, like:
~> put 'lorem,ipsum' | splits , (all)
▶ lorem
▶ ipsum
Or capturing all inputs in a variable:
~> x = [(all)]
foo
bar
(Press ^D)
~> put $x
▶ [foo bar]
assoc
assoc $container $k $v
Output a slightly modified version of $container, such that its value at $k is $v. Applies to both lists
and to maps.
When $container is a list, $k may be a negative index. However, slice is not yet supported.
~> assoc [foo bar quux] 0 lorem
▶ [lorem bar quux]
~> assoc [foo bar quux] -1 ipsum
▶ [foo bar ipsum]
~> assoc [&k=v] k v2
▶ [&k=v2]
~> assoc [&k=v] k2 v2
▶ [&k2=v2 &k=v]
Etymology: Clojure (https://clojuredocs.org/clojure.core/assoc).
@cf dissoc
bool
bool $value
Convert a value to boolean. In Elvish, only $false and errors are booleanly false. Everything else, in‐
cluding 0, empty strings and empty lists, is booleanly true:
~> bool $true
▶ $true
~> bool $false
▶ $false
~> bool $ok
▶ $true
~> bool ?(fail haha)
▶ $false
~> bool ''
▶ $true
~> bool []
▶ $true
~> bool abc
▶ $true
@cf not
cd
cd $dirname
Change directory.
Note that Elvish's cd does not support cd -.
chr
chr $number...
Outputs a string consisting of the given Unicode codepoints. Example:
~> chr 0x61
▶ a
~> chr 0x4f60 0x597d
▶ 你好
Etymology: Python (https://docs.python.org/3/library/functions.html#chr).
@cf ord
constantly
constantly $value...
Output a function that takes no arguments and outputs $values when called. Examples:
~> f=(constantly lorem ipsum)
~> $f
▶ lorem
▶ ipsum
The above example is actually equivalent to simply f = []{ put lorem ipsum }; it is most useful when the
argument is not a literal value, e.g.
~> f = (constantly (uname))
~> $f
▶ Darwin
~> $f
▶ Darwin
The above code only calls uname once, while if you do f = []{ put (uname) }, every time you invoke $f,
uname will be called.
Etymology: Clojure (https://clojuredocs.org/clojure.core/constantly).
count
count $input-list?
Count the number of inputs.
Examples:
~> count lorem # count bytes in a string
▶ 5
~> count [lorem ipsum]
▶ 2
~> range 100 | count
▶ 100
~> seq 100 | count
▶ 100
dir-history
dir-history
Return a list containing the directory history. Each element is a map with two keys: path and score.
The list is sorted by descending score.
Example:
~> dir-history | take 1
▶ [&path=/Users/foo/.elvish &score=96.79928]
dissoc
dissoc $map $k
Output a slightly modified version of $map, with the key $k removed. If $map does not contain $k as a
key, the same map is returned.
~> dissoc [&foo=bar &lorem=ipsum] foo
▶ [&lorem=ipsum]
~> dissoc [&foo=bar &lorem=ipsum] k
▶ [&lorem=ipsum &foo=bar]
@cf assoc
drop
drop $n $input-list?
Drop the first $n elements of the input. If $n is larger than the number of input elements, the entire
input is dropped.
Example:
~> drop 2 [a b c d e]
▶ c
▶ d
▶ e
~> splits ' ' 'how are you?' | drop 1
▶ are
▶ 'you?'
~> range 2 | drop 10
Etymology: Haskell.
@cf take
each
each $f $input-list?
Call $f on all inputs. Examples:
~> range 5 8 | each [x]{ ^ $x 2 }
▶ 25
▶ 36
▶ 49
~> each [x]{ put $x[:3] } [lorem ipsum]
▶ lor
▶ ips
@cf peach
Etymology: Various languages, as for each. Happens to have the same name as the iteration construct of
Factor (http://docs.factorcode.org/content/word-each,sequences.html).
eawk
eawk $f $input-list?
For each input, call $f with the input followed by all its fields.
It should behave the same as the following functions:
fn eawk [f @rest]{
each [line]{
@fields = (re:split '[ \t]+'
(re:replace '^[ \t]+|[ \t]+$' '' $line))
$f $line $@fields
} $@rest
}
This command allows you to write code very similar to awk scripts using anonymous functions. Example:
~> echo ' lorem ipsum
1 2' | awk '{ print $1 }'
lorem
1
~> echo ' lorem ipsum
1 2' | eawk [line a b]{ put $a }
▶ lorem
▶ 1
echo
echo &sep=' ' $value...
Print all arguments, joined by the sep option, and followed by a newline.
Examples:
~> echo Hello elvish
Hello elvish
~> echo "Hello elvish"
Hello elvish
~> echo &sep=, lorem ipsum
lorem,ipsum
Notes: The echo builtin does not treat -e or -n specially. For instance, echo -n just prints -n. Use
double-quoted strings to print special characters, and print to suppress the trailing newline.
@cf print
Etymology: Bourne sh.
eq
eq $values...
Determine whether all $values are structurally equivalent. Writes $true when given no or one argument.
~> eq a a
▶ $true
~> eq [a] [a]
▶ $true
~> eq [&k=v] [&k=v]
▶ $true
~> eq a [b]
▶ $false
@cf is not-eq
Etymology: Perl (https://perldoc.perl.org/perlop.html#Equality-Operators).
exec
exec $command?
Replace the Elvish process with an external $command, defaulting to elvish.
exit
exit $status?
Exit the Elvish process with $status (defaulting to 0).
explode
explode $iterable
Put all elements of $iterable on the structured stdout. Like flatten in functional languages. Equiva‐
lent to [li]{ put $@li }.
Example:
~> explode [a b [x]]
▶ a
▶ b
▶ [x]
Etymology: PHP (http://php.net/manual/en/function.explode.php). PHP's explode is actually equivalent to
Elvish's splits, but the author liked the name too much to not use it.
external
external $program
Construct a callable value for the external program $program. Example:
~> x = (external man)
~> $x ls # opens the manpage for ls
@cf has-external search-external
fail
fail $message
Throw an exception.
~> fail bad
Exception: bad
Traceback:
[interactive], line 1:
fail bad
~> put ?(fail bad)
▶ ?(fail bad)
Note: Exceptions are now only allowed to carry string messages. You cannot do fail [&cause=xxx] (this
will, ironically, throw a different exception complaining that you cannot throw a map). This is subject
to change. Builtins will likely also throw structured exceptions in future.
fclose
fclose $file
Close a file opened with fopen.
@cf fopen
fopen
fopen $filename
Open a file. Currently, fopen only supports opening a file for reading. File must be closed with fclose
explicitly. Example:
~> cat a.txt
This is
a file.
~> f = (fopen a.txt)
~> cat < $f
This is
a file.
~> fclose $f
@cf fclose
from-json
from-json
Takes bytes stdin, parses it as JSON and puts the result on structured stdout. The input can contain
multiple JSONs, which can, but do not have to, be separated with whitespaces.
Examples:
~> echo '"a"' | from-json
▶ a
~> echo '["lorem", "ipsum"]' | from-json
▶ [lorem ipsum]
~> echo '{"lorem": "ipsum"}' | from-json
▶ [&lorem=ipsum]
~> # multiple JSONs running together
echo '"a""b"["x"]' | from-json
▶ a
▶ b
▶ [x]
~> # multiple JSONs separated by newlines
echo '"a"
{"k": "v"}' | from-json
▶ a
▶ [&k=v]
@cf to-json
get-env
get-env $name
Gets the value of an environment variable. Throws an exception if the environment variable does not ex‐
ist. Examples:
~> get-env LANG
▶ zh_CN.UTF-8
~> get-env NO_SUCH_ENV
Exception: non-existent environment variable
[tty], line 1: get-env NO_SUCH_ENV
@cf has-env set-env unset-env
has-env
has-env $name
Test whether an environment variable exists. Examples:
~> has-env PATH
▶ $true
~> has-env NO_SUCH_ENV
▶ $false
@cf get-env set-env unset-env
has-external
has-external $command
Test whether $command names a valid external command. Examples (your output might differ):
~> has-external cat
▶ $true
~> has-external lalala
▶ $false
@cf external search-external
has-key
has-key $container $key
Determine whether $key is a key in $container. A key could be a map key or an index on a list or string.
This includes a range of indexes.
Examples, maps:
~> has-key [&k1=v1 &k2=v2] k1
▶ $true
~> has-key [&k1=v1 &k2=v2] v1
▶ $false
Examples, lists:
~> has-key [v1 v2] 0
▶ $true
~> has-key [v1 v2] 1
▶ $true
~> has-key [v1 v2] 2
▶ $false
~> has-key [v1 v2] 0:2
▶ $true
~> has-key [v1 v2] 0:3
▶ $false
Examples, strings:
~> has-key ab 0
▶ $true
~> has-key ab 1
▶ $true
~> has-key ab 2
▶ $false
~> has-key ab 0:2
▶ $true
~> has-key ab 0:3
▶ $false
has-prefix
has-prefix $string $prefix
Determine whether $prefix is a prefix of $string. Examples:
~> has-prefix lorem,ipsum lor
▶ $true
~> has-prefix lorem,ipsum foo
▶ $false
has-suffix
has-suffix $string $suffix
Determine whether $suffix is a suffix of $string. Examples:
~> has-suffix a.html .txt
▶ $false
~> has-suffix a.html .html
▶ $true
has-value
has-value $container $value
Determine whether $value is a value in $container.
Examples, maps:
~> has-value [&k1=v1 &k2=v2] v1
▶ $true
~> has-value [&k1=v1 &k2=v2] k1
▶ $false
Examples, lists:
~> has-value [v1 v2] v1
▶ $true
~> has-value [v1 v2] k1
▶ $false
Examples, strings:
~> has-value ab b
▶ $true
~> has-value ab c
▶ $false
is
is $values...
Determine whether all $values have the same identity. Writes $true when given no or one argument.
The definition of identity is subject to change. Do not rely on its behavior.
~> is a a
▶ $true
~> is a b
▶ $false
~> is [] []
▶ $true
~> is [a] [a]
▶ $false
@cf eq
Etymology: Python (https://docs.python.org/3/reference/expressions.html#is).
joins
joins $sep $input-list?
Join inputs with $sep. Examples:
~> put lorem ipsum | joins ,
▶ lorem,ipsum
~> joins , [lorem ipsum]
▶ lorem,ipsum
The suffix "s" means "string" and also serves to avoid colliding with the well-known join
(https://en.wikipedia.org/wiki/join_(Unix)) utility.
Etymology: Various languages as join, in particular Python (https://docs.python.org/3.6/library/std‐
types.html#str.join).
@cf splits
keys
keys $map
Put all keys of $map on the structured stdout.
Example:
~> keys [&a=foo &b=bar &c=baz]
▶ a
▶ c
▶ b
Note that there is no guaranteed order for the keys of a map.
kind-of
kind-of $value...
Output the kinds of $values. Example:
~> kind-of lorem [] [&]
▶ string
▶ list
▶ map
The terminology and definition of "kind" is subject to change.
nop
nop &any-opt= $value...
Accepts arbitrary arguments and options and does exactly nothing.
Examples:
~> nop
~> nop a b c
~> nop &k=v
Etymology: Various languages, in particular NOP in assembly languages (https://en.wikipedia.org/wi‐
ki/NOP).
not
not $value
Boolean negation. Examples:
~> not $true
▶ $false
~> not $false
▶ $true
~> not $ok
▶ $false
~> not ?(fail error)
▶ $true
NOTE: and and or are implemented as special commands.
@cf bool
not-eq
not-eq $values...
Determines whether every adjacent pair of $values are not equal. Note that this does not imply that
$values are all distinct. Examples:
~> not-eq 1 2 3
▶ $true
~> not-eq 1 2 1
▶ $true
~> not-eq 1 1 2
▶ $false
@cf eq
only-bytes
only-bytes
Passes byte input to output, and discards value inputs.
Example:
~> { put value; echo bytes } | only-bytes
bytes
only-values
only-values
Passes value input to output, and discards byte inputs.
Example:
~> { put value; echo bytes } | only-values
▶ value
ord
ord $string
Output value of each codepoint in $string, in hexadecimal. Examples:
~> ord a
▶ 0x61
~> ord 你好
▶ 0x4f60
▶ 0x597d
The output format is subject to change.
Etymology: Python (https://docs.python.org/3/library/functions.html#ord).
@cf chr
path-*
path-abs $path
path-base $path
path-clean $path
path-dir $path
path-ext $path
See godoc of path/filepath (https://godoc.org/path/filepath). Go errors are turned into exceptions.
peach
peach $f $input-list?
Call $f on all inputs, possibly in parallel.
Example (your output will differ):
~> range 1 7 | peach [x]{ + $x 10 }
▶ 12
▶ 11
▶ 13
▶ 16
▶ 15
▶ 14
This command is intended for homogeneous processing of possibly unbound data. If you need to do a fixed
number of heterogeneous things in parallel, use run-parallel.
@cf each run-parallel
pipe
pipe
Create a new Unix pipe that can be used in redirections.
A pipe contains both the read FD and the write FD. When redirecting command input to a pipe with <, the
read FD is used. When redirecting command output to a pipe with >, the write FD is used. It is not sup‐
ported to redirect both input and output with <> to a pipe.
Pipes have an OS-dependent buffer, so writing to a pipe without an active reader does not necessarily
block. Pipes must be explicitly closed with prclose and pwclose.
Putting values into pipes will cause those values to be discarded.
Examples (assuming the pipe has a large enough buffer):
~> p = (pipe)
~> echo 'lorem ipsum' > $p
~> head -n1 < $p
lorem ipsum
~> put 'lorem ipsum' > $p
~> head -n1 < $p
# blocks
# $p should be closed with prclose and pwclose afterwards
@cf prclose pwclose
prclose
prclose $pipe
Close the read end of a pipe.
@cf pwclose pipe
put
put $value...
Takes arbitrary arguments and write them to the structured stdout.
Examples:
~> put a
▶ a
~> put lorem ipsum [a b] { ls }
▶ lorem
▶ ipsum
▶ [a b]
▶ <closure 0xc4202607e0>
Etymology: Various languages, in particular C (https://manpages.debian.org/stretch/manpages-
dev/puts.3.en.html) and Ruby (https://ruby-doc.org/core-2.2.2/IO.html#method-i-puts) as puts.
pprint
pprint $value...
Pretty-print representations of Elvish values. Examples:
~> pprint [foo bar]
[
foo
bar
]
~> pprint [&k1=v1 &k2=v2]
[
&k2=
v2
&k1=
v1
]
The output format is subject to change.
@cf repr
print
print &sep=' ' $value...
Like echo, just without the newline.
@cf echo
Etymology: Various languages, in particular Perl (https://perldoc.perl.org/functions/print.html) and zsh
(http://zsh.sourceforge.net/Doc/Release/Shell-Builtin-Commands.html), whose prints do not print a trail‐
ing newline.
pwclose
pwclose $pipe
Close the write end of a pipe.
@cf prclose pipe
range
range &step=1 $low? $high
Output $low, $low + $step, ..., proceeding as long as smaller than $high. If not given, $low defaults to
0.
Examples:
~> range 4
▶ 0
▶ 1
▶ 2
▶ 3
~> range 1 6 &step=2
▶ 1
▶ 3
▶ 5
Beware floating point oddities:
~> range 0 0.8 &step=.1
▶ 0
▶ 0.1
▶ 0.2
▶ 0.30000000000000004
▶ 0.4
▶ 0.5
▶ 0.6
▶ 0.7
▶ 0.7999999999999999
Etymology: Python (https://docs.python.org/3/library/functions.html#func-range).
rand
rand
Output a pseudo-random number in the interval [0, 1). Example:
~> rand
▶ 0.17843564133528436
randint
randint $low $high
Output a pseudo-random integer in the interval [$low, $high). Example:
~> # Emulate dice
randint 1 7
▶ 6
repeat
repeat $n $value
Output $value for $n times. Example:
~> repeat 0 lorem
~> repeat 4 NAN
▶ NAN
▶ NAN
▶ NAN
▶ NAN
Etymology: Clojure (https://clojuredocs.org/clojure.core/repeat).
replaces
replaces &max=-1 $old $repl $source
Replace all occurrences of $old with $repl in $source. If $max is non-negative, it determines the max
number of substitutions.
Note: replaces does not support searching by regular expressions, $old is always interpreted as a plain
string. Use re:replace (re.html#replace) if you need to search by regex.
repr
repr $value...
Writes representation of $values, separated by space and followed by a newline. Example:
~> repr [foo 'lorem ipsum'] "aha\n"
[foo 'lorem ipsum'] "aha\n"
@cf pprint
Etymology: Python (https://docs.python.org/3/library/functions.html#repr).
resolve
resolve $command
Resolve $command. Command resolution is described in the language reference (language.html). (TODO: ac‐
tually describe it there.)
Example:
~> resolve echo
▶ <builtin echo>
~> fn f { }
~> resolve f
▶ <closure 0xc4201c24d0>
~> resolve cat
▶ <external cat>
run-parallel
run-parallel $callable ...
Run several callables in parallel, and wait for all of them to finish.
If one or more callables throw exceptions, the other callables continue running, and a composite excep‐
tion is thrown when all callables finish execution.
The behavior of run-parallel is consistent with the behavior of pipelines, except that it does not per‐
form any redirections.
Here is an example that lets you pipe the stdout and stderr of a command to two different commands:
pout = (pipe)
perr = (pipe)
run-parallel {
foo > $pout 2> $perr
pwclose $pout
pwclose $perr
} {
bar < $pout
prclose $pout
} {
bar2 < $perr
prclose $perr
}
This command is intended for doing a fixed number of heterogeneous things in parallel. If you need homo‐
geneous parallel processing of possibly unbound data, use peach instead.
@cf peach
search-external
search-external $command
Output the full path of the external $command. Throws an exception when not found. Example (your output
might vary):
~> search-external cat
▶ /bin/cat
@cf external has-external
set-env
set-env $name $value
Sets an environment variable to the given value. Example:
~> set-env X foobar
~> put $E:X
▶ foobar
@cf get-env has-env unset-env
slurp
slurp
Reads bytes input into a single string, and put this string on structured stdout.
Example:
~> echo "a\nb" | slurp
▶ "a\nb\n"
Etymology: Perl, as File::Slurp (http://search.cpan.org/~uri/File-Slurp-9999.19/lib/File/Slurp.pm).
splits
splits $sep $string
Split $string by $sep. If $sep is an empty string, split it into codepoints.
~> splits , lorem,ipsum
▶ lorem
▶ ipsum
~> splits '' 你好
▶ 你
▶ 好
Note: splits does not support splitting by regular expressions, $sep is always interpreted as a plain
string. Use re:split (re.html#split) if you need to split by regex.
Etymology: Various languages as split, in particular Python (https://docs.python.org/3.6/library/std‐
types.html#str.split).
@cf joins
src
src
Output a map-like value describing the current source being evaluated. The value contains the following
fields:
• type, which can be one of interactive, script or module;
• name, which is set to the name under which a script is executed or a module is imported. It is an emp‐
ty string when type = interactive;
• path, which is the path to the current source. It is an empty string when type = interactive;
• code, which is the full body of the current source.
Examples:
~> put (src)[type name path code]
▶ interactive
▶ ''
▶ ''
▶ 'put (src)[type name path code]'
~> echo 'put (src)[type name path code]' > foo.elv
~> elvish foo.elv
▶ script
▶ foo.elv
▶ /home/xiaq/foo.elv
▶ "put (src)[type name path code]\n"
~> echo 'put (src)[type name path code]' > ~/.elvish/lib/m.elv
~> use m
▶ module
▶ m
▶ /home/xiaq/.elvish/lib/m.elv
▶ "put (src)[type name path code]\n"
Note: this builtin always returns information of the source of the calling function. Example:
~> echo 'fn f { put (src)[type name path code] }' > ~/.elvish/lib/n.elv
~> use n
~> n:f
▶ module
▶ n
▶ /home/xiaq/.elvish/lib/n.elv
▶ "fn f { put (src)[type name path code] }\n"
styled
styled $object $style-transformer...
Construct a styled text by applying the supplied transformers to the supplied object. $object can be ei‐
ther a string, a styled segment (see below), a styled text or an arbitrary concatenation of them. A
$style-transformer is either:
• The name of a builtin style transformer, which may be one of the following:
• On of the attribute names bold, dim, italic, underlined, blink or inverse for setting the correspond‐
ing attribute
• An attribute name prefixed by no- for unsetting the attribute
• An attribute name prefixed by toggle- for toggling the attribute between set and unset
• A color name for setting the text color, which may be one of the following:
• One of the 8 basic ANSI colors: black, red, green, yellow, blue, magenta, cyan and white
• The bright variant of the 8 basic ANSI colors, with a bright- prefix
• Any color from the xterm 256-color palette, as colorX (such as color12)
• A 24-bit RGB color, as #RRGGBB, such as #778899.
• A color name prefixed by bg- to set the background color
• A lambda that receives a styled segment as the only argument and returns a single styled segment
• A function with the same properties as the lambda (provided via the $transformer~ syntax)
When a styled text is converted to a string the corresponding ANSI SGR code (https://en.wikipedia.org/wi‐
ki/ANSI_escape_code#SGR_.28Select_Graphic_Rendition.29_parameters) is built to render the style.
A styled text is nothing more than a wrapper around a list of styled segments. They can be accessed by
indexing into it.
s = (styled abc red)(styled def green)
put $s[0] $s[1]
styled-segment
styled-segment $object &fg-color=default &bg-color=default &bold=$false &dim=$false &italic=$false &underlined=$false &blink=$false &inverse=$false
Constructs a styled segment and is a helper function for styled transformers. $object can be a plain
string, a styled segment or a concatenation thereof. Probably the only reason to use it is to build cus‐
tom style transformers:
fn my-awesome-style-transformer [seg]{ styled-segment $seg &bold=(not $seg[dim]) &dim=(not $seg[italic]) &italic=$seg[bold] }
styled abc $my-awesome-style-transformer~
As just seen the properties of styled segments can be inspected by indexing into it. Valid indices are
the same as the options to styled-segment plus text.
s = (styled-segment abc &bold)
put $s[text]
put $s[fg-color]
put $s[bold]
take
take $n $input-list?
Retain the first $n input elements. If $n is larger than the number of input elements, the entire input
is retained. Examples:
~> take 3 [a b c d e]
▶ a
▶ b
▶ c
~> splits ' ' 'how are you?' | take 1
▶ how
~> range 2 | take 10
▶ 0
▶ 1
Etymology: Haskell.
tilde-abbr
tilde-abbr $path
If $path represents a path under the home directory, replace the home directory with ~. Examples:
~> echo $E:HOME
/Users/foo
~> tilde-abbr /Users/foo
▶ '~'
~> tilde-abbr /Users/foobar
▶ /Users/foobar
~> tilde-abbr /Users/foo/a/b
▶ '~/a/b'
to-json
to-json
Takes structured stdin, convert it to JSON and puts the result on bytes stdout.
~> put a | to-json
"a"
~> put [lorem ipsum] | to-json
["lorem","ipsum"]
~> put [&lorem=ipsum] | to-json
{"lorem":"ipsum"}
@cf from-json
to-string
to-string $value...
Convert arguments to string values.
~> to-string foo [a] [&k=v]
▶ foo
▶ '[a]'
▶ '[&k=v]'
unset-env
unset-env $name
Unset an environment variable. Example:
~> E:X = foo
~> unset-env X
~> has-env X
▶ $false
~> put $E:X
▶ ''
@cf has-env get-env set-env
wcswidth
wcswidth $string
Output the width of $string when displayed on the terminal. Examples:
~> wcswidth a
▶ 1
~> wcswidth lorem
▶ 5
~> wcswidth 你好,世界
▶ 10
-gc
-gc
Force the Go garbage collector to run.
This is only useful for debug purposes.
-ifaddrs
-ifaddrs
Output all IP addresses of the current host.
This should be part of a networking module instead of the builtin module.
-log
-log $filename
Direct internal debug logs to the named file.
This is only useful for debug purposes.
-stack
-stack
Print a stack trace.
This is only useful for debug purposes.
-source
-source $filename
Read the named file, and evaluate it in the current scope.
Examples:
~> cat x.elv
echo 'executing x.elv'
foo = bar
~> -source x.elv
executing x.elv
~> echo $foo
bar
Note that while in the example, you can reference $foo after sourcing x.elv, putting the -source command
and reference to $foo in the same code chunk (e.g. by using Alt-Enter to insert a literal Enter, or us‐
ing ;) is invalid:
~> # A new Elvish session
~> cat x.elv
echo 'executing x.elv'
foo = bar
~> -source x.elv; echo $foo
Compilation error: variable $foo not found
[interactive], line 1:
-source x.elv; echo $foo
This is because the reading of the file is done in the evaluation phase, while the check for variables
happens at the compilation phase (before evaluation). So the compiler has no evidence showing that $foo
is actually valid, and will complain. (See here (../learn/unique-semantics.html#execution-phases) for a
more detailed description of execution phases.)
To work around this, you can add a forward declaration for $foo:
~> # Another new session
~> cat x.elv
echo 'executing x.elv'
foo = bar
~> foo = ''; -source x.elv; echo $foo
executing x.elv
bar
-time
-time $callable
Run the callable, and write the time used to run it. Example:
~> -time { sleep 1 }
1.006060647s
When the callable also produces outputs, they are a bit tricky to separate from the output of -time. The
easiest workaround is to redirect the output into a temporary file:
~> f = (mktemp)
~> -time { { echo output; sleep 1 } > $f }
1.005589823s
~> cat $f
output
~> rm $f
Builtin Variables
$_
A blackhole variable.
Values assigned to it will be discarded. Trying to use its value (like put $_) causes an exception.
$after-chdir
A list of functions to run after changing directory. These functions are always called with directory to
change it, which might be a relative path. The following example also shows $before-chdir:
~> before-chdir = [[dir]{ echo "Going to change to "$dir", pwd is "$pwd }]
~> after-chdir = [[dir]{ echo "Changed to "$dir", pwd is "$pwd }]
~> cd /usr
Going to change to /usr, pwd is /Users/xiaq
Changed to /usr, pwd is /usr
/usr> cd local
Going to change to local, pwd is /usr
Changed to local, pwd is /usr/local
/usr/local>
@cf before-chdir
$args
A list containing command-line arguments. Analogous to argv in some other languages. Examples:
~> echo 'put $args' > args.elv
~> elvish args.elv foo -bar
▶ [foo -bar]
~> elvish -c 'put $args' foo -bar
▶ [foo -bar]
As demonstrated above, this variable does not contain the name of the script used to invoke it. For that
information, use the src command.
@cf src
$before-chdir
A list of functions to run before changing directory. These functions are always called with the new
working directory.
@cf after-chdir
$false
The boolean false value.
$ok
The special value used by ?() to signal absence of exceptions.
$nil
A special value useful for representing the lack of values.
WARNING: Due to a bug, $nil cannot be used as a map key now.
$num-bg-jobs
Number of background jobs.
$notify-bg-job-success
Whether to notify success of background jobs, defaulting to $true.
Failures of background jobs are always notified.
$paths
A list of search paths, kept in sync with $E:PATH. It is easier to use than $E:PATH.
$pid
The process ID of the current Elvish process.
$pwd
The present working directory. Setting this variable has the same effect as cd. This variable is most
useful in temporary assignment.
Example:
## Updates all git repositories
for x [*/] {
pwd=$x {
if ?(test -d .git) {
git pull
}
}
}
Etymology: the pwd command.
$true
The boolean true value.
$value-out-indicator
A string put before value outputs (such as those of of put). Defaults to '▶ '. Example:
~> put lorem ipsum
▶ lorem
▶ ipsum
~> value-out-indicator = 'val> '
~> put lorem ipsum
val> lorem
val> ipsum
Note that you almost always want some trailing whitespace for readability.
Elvish 0.13 Oct 10, 2022 elvish-builtin(7)