- Introduction
- Variables
- Functions
- !=
- !=s
- %
- *
- +
- -
- /
- <
- <=
- <=s
- <s
- ==
- ==s
- >
- >=
- >=s
- >s
- all
- assoc
- base
- benchmark
- bool
- break
- call
- cd
- compact
- compare
- conj
- constantly
- continue
- count
- defer
- deprecate
- dissoc
- drop
- each
- eawk
- echo
- eq
- eval
- exact-num
- exec
- exit
- external
- fail
- from-json
- from-lines
- from-terminated
- -gc
- get-env
- has-env
- has-external
- has-key
- has-value
- -ifaddrs
- inexact-num
- is
- keys
- kind-of
- -log
- make-map
- nop
- not
- not-eq
- ns
- num
- one
- only-bytes
- only-values
- order
- peach
- pprint
- printf
- put
- rand
- randint
- -randseed
- range
- read-bytes
- read-line
- read-upto
- render-styledown
- repeat
- repr
- resolve
- return
- run-parallel
- search-external
- set-env
- show
- sleep
- slurp
- src
- -stack
- styled
- styled-segment
- take
- tilde-abbr
- time
- to-json
- to-lines
- to-string
- to-terminated
- unset-env
- use-mod
- wcswidth
Introduction
The builtin module contains facilities that are potentially useful to all users.
Using builtin: explicitly
The builtin module is consulted implicitly when resolving unqualified names, and Elvish’s namespacing mechanism makes it impossible for other modules to redefine builtin symbols. It’s almost always sufficient (and safe) to use builtin functions and variables with their unqualified names.
Nonetheless, the builtin module is also available as a
pre-defined module. It can be imported with
use builtin
, which makes all the builtin symbols available under the
builtin:
namespace. This can be useful in several cases:
-
To refer to a builtin function when it is shadowed locally. This is especially useful when the function that shadows the builtin one is a wrapper:
use builtin fn cd {|@args| echo running my cd function builtin:cd $@args }
Note that the shadowing of
cd
is only in effect in the local lexical scope. -
To introspect the builtin module, for example
keys $builtin:
.
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 is 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 $inputs?
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 a sep
option and arbitrary arguments:
echo &sep=' ' $value...
(When you call functions, options are always optional.)
Commands taking value inputs
Most commands that take value inputs (e.g. count
, each
) can take the inputs
in one of two ways:
-
From the pipeline:
~> put lorem ipsum | count # count number of inputs 2 ~> put 10 100 | each {|x| + 1 $x } # apply function to each input ▶ (num 11) ▶ (num 101)
If the previous command outputs bytes, one line becomes one string input, as if there is an implicit
from-lines
(this behavior is subject to change):~> print "a\nb\nc\n" | count # count number of lines ▶ 3 ~> use str ~> print "a\nb\nc\n" | each $str:to-upper~ # apply to each line ▶ A ▶ B ▶ C
-
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 supported:
~> count lorem ▶ 5
When documenting such commands, the optional argument is always written as
$inputs?
.
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 equivalent to
some-command | count
or some-command | each $some-func
.
Rationale: An alternative way to design this is to make (say) count
take
an arbitrary number of arguments, 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.
Numeric commands
Wherever a command expects a number argument, that argument can be supplied
either with a typed number or a string that can be
converted to a number. This includes numeric comparison commands like ==
.
When a command outputs numbers, it always outputs a typed number.
Examples:
~> + 2 10
▶ (num 12)
~> == 2 (num 2)
▶ $true
Exactness-preserving commands
Some numeric commands are designated exactness-preserving. When such commands are called with only exact numbers (i.e. integers or rationals), they will always output an exact number. Examples:
~> + 10 1/10
▶ (num 101/10)
~> * 12 5/17
▶ (num 60/17)
If the condition above is not satisfied – i.e. when a numeric command is not designated exactness-preserving, or when at least one of the arguments is inexact (i.e. a floating-point number), the result is an inexact number, unless otherwise documented. Examples:
~> + 10 0.1
▶ (num 10.1)
~> + 10 1e1
▶ (num 20.0)
~> use math
~> math:sin 1
▶ (num 0.8414709848078965)
There are some cases where the result is exact despite the use of inexact arguments or non-exactness-preserving commands. Such cases are always documented in their respective commands.
Unstable features
The name of some variables and functions have a leading -
. This is a
convention to say that it is subject 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.)
Variables
$_
A blackhole variable.
Values assigned to it will be discarded. Referencing it always results in $nil.
$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
:
~> set before-chdir = [{|dir| echo "Going to change to "$dir", pwd is "$pwd }]
~> set 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>
Note: The use of echo
above is for illustrative purposes. When Elvish
is used interactively, the working directory may be changed in location mode
or navigation mode, and outputs from echo
can garble the terminal. If you
are writing a plugin that works with the interactive mode, it’s better to use
edit:notify
.
See also $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.
See also src
.
$before-chdir
A list of functions to run before changing directory. These functions are always called with the new working directory.
See also $after-chdir
.
$before-exit
A list of functions to run before Elvish exits.
$buildinfo
A map that exposes information about the Elvish binary. Running put $buildinfo | to-json
will produce the same output as elvish -buildinfo -json
.
See also $version
.
$false
The boolean false value.
$nil
A special value useful for representing the lack of values.
$notify-bg-job-success
Whether to notify success of background jobs, defaulting to $true
.
Failures of background jobs are always notified.
$num-bg-jobs
Number of background jobs.
$ok
The special value used by ?()
to signal absence of exceptions.
$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 a temporary assignment.
Example:
## Updates all git repositories
use path
for x [*/] {
tmp pwd = $x
if (path:is-dir .git) {
git pull
}
}
Etymology: the pwd
command.
See also cd
.
$true
The boolean true value.
$value-out-indicator
A string put before value outputs (such as those of put
). Defaults to
'▶ '
. Example:
~> put lorem ipsum
▶ lorem
▶ ipsum
~> set value-out-indicator = 'val> '
~> put lorem ipsum
val> lorem
val> ipsum
Note that you almost always want some trailing whitespace for readability.
$version
The full version of the Elvish binary as a string. This is the same information reported by
elvish -version
and the value of $buildinfo[version]
.
Note: In general it is better to perform functionality tests rather than testing $version
.
For example, do something like
has-key $builtin: new-var
to test if variable new-var
is available rather than comparing against $version
to see if the
elvish version is equal to or newer than the version that introduced new-var
.
See also $buildinfo
.
Functions
!=
!= $a $b
Determines whether $a
and $b
are numerically inequal. Equivalent to not (== $a $b)
.
Examples:
~> != 1 2
▶ $true
~> != 1 1
▶ $false
!=s
!=s $a $b
Outputs whether $a
and $b
are not the same string. Equivalent to not (==s $a $b)
.
%
% $x $y
Outputs the remainder after dividing $x
by $y
. The result has the same
sign as $x
. Both arguments must be exact integers.
Examples:
~> % 10 3
▶ (num 1)
~> % -10 3
▶ (num -1)
~> % 10 -3
▶ (num 1)
~> % 10000000000000000000 3
▶ (num 1)
~> % 10.0 3
Exception: bad value: argument must be exact integer, but is (num 10.0)
[tty]:1:1-8: % 10.0 3
This limit may be lifted in the future.
*
* $num...
Outputs the product of all arguments, or 1 when there are no arguments.
This command is exactness-preserving. Additionally, when any argument is exact 0 and no other argument is a floating-point infinity, the result is exact 0.
Examples:
~> * 2 5 7
▶ (num 70)
~> * 1/2 0.5
▶ (num 0.25)
~> * 0 0.5
▶ (num 0)
+
+ $num...
Outputs the sum of all arguments, or 0 when there are no arguments.
This command is exactness-preserving.
Examples:
~> + 5 2 7
▶ (num 14)
~> + 1/2 1/3 1/4
▶ (num 13/12)
~> + 1/2 0.5
▶ (num 1.0)
-
- $x-num $y-num...
Outputs the result of subtracting from $x-num
all the $y-num
s, working
from left to right. When no $y-num
is given, outputs the negation of
$x-num
instead (in other words, - $x-num
is equivalent to - 0 $x-num
).
This command is exactness-preserving.
Examples:
~> - 5
▶ (num -5)
~> - 5 2
▶ (num 3)
~> - 5 2 7
▶ (num -4)
~> - 1/2 1/3
▶ (num 1/6)
~> - 1/2 0.3
▶ (num 0.2)
~> - 10
▶ (num -10)
/
/ $x-num $y-num...
Outputs the result of dividing $x-num
with all the $y-num
s, working from
left to right. When no $y-num
is given, outputs the reciprocal of $x-num
instead (in other words, / $y-num
is equivalent to / 1 $y-num
).
Dividing by exact 0 raises an exception. Dividing by inexact 0 results with either infinity or NaN according to floating-point semantics.
This command is exactness-preserving. Additionally,
when $x-num
is exact 0 and no $y-num
is exact 0, the result is exact 0.
Examples:
~> / 2
▶ (num 1/2)
~> / 2.0
▶ (num 0.5)
~> / 10 5
▶ (num 2)
~> / 2 5
▶ (num 2/5)
~> / 2 5 7
▶ (num 2/35)
~> / 0 1.0
▶ (num 0)
~> / 2 0
Exception: bad value: divisor must be number other than exact 0, but is exact 0
[tty]:1:1-5: / 2 0
~> / 2 0.0
▶ (num +Inf)
When given no argument, this command is equivalent to cd /
, due to the
implicit cd feature. (The implicit cd feature is deprecated since 0.21.0).
<
< $number...
Outputs whether $number
s in the given order are numerically strictly
increasing. Outputs $true
when given fewer than two numbers.
Examples:
~> < 1 2
▶ $true
~> < 2 1
▶ $false
~> < 1 2 3
▶ $true
<=
<= $number...
Outputs whether $number
s in the given order are numerically non-decreaing.
Outputs $true
when given fewer than two numbers.
Examples:
~> <= 1 1
▶ $true
~> <= 2 1
▶ $false
~> <= 1 1 2
▶ $true
<=s
<=s $string...
Outputs whether $string
s in the given order are strictly non-decreasing.
Outputs $true
when given fewer than two strings.
<s
<s $string...
Outputs whether $string
s in the given order are strictly increasing. Outputs
$true
when given fewer than two strings.
==
== $number...
Outputs whether $number
s are all numerically equal. Outputs $true
when
given fewer than two numbers.
Examples:
~> == 1 1
▶ $true
~> == 1 (num 1)
▶ $true
~> == 1 (num 1) 1
▶ $true
~> == 1 (num 1) 1.0
▶ $true
~> == 1 2
▶ $false
==s
==s $string...
Outputs whether $string
s are all the same string. Outputs $true
when given
fewer than two strings.
>
> $number...
Determines whether $number
s in the given order are numerically strictly
decreasing. Outputs $true
when given fewer than two numbers.
Examples:
~> > 2 1
▶ $true
~> > 1 2
▶ $false
~> > 3 2 1
▶ $true
>=
>= $number...
Outputs whether $number
s in the given order are numerically non-increasing.
Outputs $true
when given fewer than two numbers.
Examples:
~> >= 1 1
▶ $true
~> >= 1 2
▶ $false
~> >= 2 1 1
▶ $true
>=s
>=s $string...
Outputs whether $string
s in the given order are strictly non-increasing.
Outputs $true
when given fewer than two strings.
>s
>s $string...
Outputs whether $string
s in the given order are strictly decreasing. Outputs
$true
when given fewer than two strings.
all
all $inputs?
Takes value inputs, and outputs those values unchanged.
This is an identity
function for the value
channel; in other words, a | all
is equivalent to just a
if a
only has
value output.
This command can be used inside output capture (i.e. (all)
) to turn value
inputs into arguments. For example:
~> echo '["foo","bar"] ["lorem","ipsum"]' | from-json
▶ [foo bar]
▶ [lorem ipsum]
~> echo '["foo","bar"] ["lorem","ipsum"]' | from-json | put (all)[0]
▶ foo
▶ lorem
The latter pipeline is equivalent to the following:
~> put (echo '["foo","bar"] ["lorem","ipsum"]' | from-json)[0]
▶ foo
▶ lorem
In general, when (all)
appears in the last command of a pipeline, it is
equivalent to just moving the previous commands of the pipeline into ()
.
The choice is a stylistic one; the (all)
variant is longer overall, but can
be more readable since it allows you to avoid putting an excessively long
pipeline inside an output capture, and keeps the data flow within the
pipeline.
Putting the value capture inside []
(i.e. [(all)]
) is useful for storing
all value inputs in a list for further processing:
~> fn f { var inputs = [(all)]; put $inputs[1] }
~> put foo bar baz | f
▶ bar
The all
command can also take “inputs” from an iterable argument. This can
be used to flatten lists or strings (although not recursively):
~> all [foo [lorem ipsum]]
▶ foo
▶ [lorem ipsum]
~> all foo
▶ f
▶ o
▶ o
This can be used together with (one)
to turn a single iterable value in the
pipeline into its elements:
~> echo '["foo","bar","lorem"]' | from-json
▶ [foo bar lorem]
~> echo '["foo","bar","lorem"]' | from-json | all (one)
▶ foo
▶ bar
▶ lorem
When given byte inputs, the all
command currently functions like
from-lines
, although this behavior is subject to change:
~> print "foo\nbar\n" | all
▶ foo
▶ bar
See also one
.
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
▶ [&k=v &k2=v2]
Etymology: Clojure.
See also dissoc
.
base
base $base $number...
Outputs a string for each $number
written in $base
. The $base
must be
between 2 and 36, inclusive. Examples:
~> base 2 1 3 4 16 255
▶ 1
▶ 11
▶ 100
▶ 10000
▶ 11111111
~> base 16 1 3 4 16 255
▶ 1
▶ 3
▶ 4
▶ 10
▶ ff
benchmark
benchmark &min-runs=5 &min-time=1s &on-end=$nil &on-run-end=$nil $callable
Runs $callable
repeatedly, and reports statistics about how long each run
takes.
If the &on-end
callback is not given, benchmark
prints the average,
standard deviation, minimum and maximum of the time it took to run
$callback
, and the number of runs. If the &on-end
callback is given,
benchmark
instead calls it with a map containing these metrics, keyed by
avg
, stddev
, min
, max
and runs
. Each duration value (i.e. all
except runs
) is given as the number of seconds.
The number of runs is controlled by &min-runs
and &min-time
. The
$callable
is run at least &min-runs
times, and when the total
duration is at least &min-time
.
The &min-runs
option must be a non-negative integer within the range of the
machine word.
The &min-time
option must be a string representing a non-negative duration,
specified as a sequence of decimal numbers with a unit suffix (the numbers
may have fractional parts), such as “300ms”, “1.5h” and “1h45m7s”. Valid time
units are “ns”, “us” (or “µs”), “ms”, “s”, “m”, “h”.
If &on-run-end
is given, it is called after each call to $callable
, with
the time that call took, given as the number of seconds.
If $callable
throws an exception, benchmark
terminates and propagates the
exception after the &on-end
callback (or the default printing behavior)
finishes. The duration of the call that throws an exception is not passed to
&on-run-end
, nor is it included when calculating the statistics for
&on-end
. If the first call to $callable
throws an exception and &on-end
is $nil
, nothing is printed and any &on-end
callback is not called.
If &on-run-end
is given and throws an exception, benchmark
terminates and
propagates the exception after the &on-end
callback (or the default
printing behavior) finishes, unless $callable
has already thrown an
exception
If &on-end
throws an exception, the exception is propagated, unless
$callable
or &on-run-end
has already thrown an exception.
Example:
~> benchmark { }
98ns ± 382ns (min 0s, max 210.417µs, 10119226 runs)
~> benchmark &on-end={|m| put $m[avg]} { }
▶ (num 9.8e-08)
~> benchmark &on-run-end={|d| echo $d} { sleep 0.3 }
0.301123625
0.30123775
0.30119075
0.300629166
0.301260333
301.088324ms ± 234.298µs (min 300.629166ms, max 301.260333ms, 5 runs)
See also time
.
bool
bool $value
Convert a value to boolean. In Elvish, only $false
, $nil
, and errors are
booleanly false. Everything else, including 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
See also not
.
break
break
Raises the special “break” exception. When raised inside a loop it is captured and causes the loop to terminate.
Because break
raises an exception it can be caught by a
try
block. If not caught, either implicitly by a loop
or explicitly, it causes a failure like any other uncaught exception.
See the discussion about flow commands and exceptions
Note: You can create a break
function and it will shadow the builtin
command. If you do so you should explicitly invoke the builtin. For example:
~> use builtin
~> fn break { put 'break'; builtin:break; put 'should not appear' }
~> for x [a b c] { put $x; break; put 'unexpected' }
▶ a
▶ break
call
call $fn $args $opts
Calls $fn
with $args
as the arguments, and $opts
as the option. Useful
for calling a function with dynamic option keys.
Example:
~> var f = {|a &k1=v1 &k2=v2| put $a $k1 $k2 }
~> call $f [foo] [&k1=bar]
▶ foo
▶ bar
▶ v2
cd
cd $dirname
Changes directory.
This affects the entire process, including parallel tasks that are started
implicitly (such as prompt functions) or explicitly (such as one started by
peach
).
Note that Elvish’s cd
does not support cd -
.
In interactive shells, location mode provides an alternative to quickly change to past directories.
See also $pwd
.
compact
compact $inputs?
Replaces consecutive runs of equal values with a single copy. Similar to the
uniq
command on Unix.
Examples:
~> put a a b b c | compact
▶ a
▶ b
▶ c
~> compact [a a b b c]
▶ a
▶ b
▶ c
~> put a b a | compact
▶ a
▶ b
▶ a
compare
compare &total=$false $a $b
Outputs the number -1 if $a
is smaller than $b
, 0 if $a
is equal to
$b
, and 1 if $a
is greater than $b
.
The following algorithm is used:
-
If
$a
and$b
have the same type and that type is listed below, they are compared accordingly:-
Booleans:
$false
is smaller than$true
. -
Typed numbers: Compared numerically, consistent with
<
and<=
, except thatNaN
values are considered equal to each other and smaller than all other numbers. -
Strings: Compared lexicographically by bytes, consistent with
<s
and<=s
. For UTF-8 encoded strings, this is equivalent to comparing by codepoints.Beware that strings that look like numbers are compared as strings, not numbers.
-
Lists: Compared lexicographically by elements, with elements compared recursively.
-
-
If
eq $a $b
is true,compare $a $b
outputs the number 0. -
Otherwise the behavior depends on the
&total
option:-
If it is
$false
(the default),compare
throws an exception complaning that the two values can’t be compared. -
If it is
$true
,compare
compares the types of$a
and$b
: if they have the same type, it outputs 0; if they have different types, it outputs -1 and 1 depending on which type comes first in an internal ordering of all types.The internal ordering of all types is unspecified, but it is guaranteed to be consistent during the same Elvish session. For example, if
compare &total $a $b
outputs -1 when$a
is a number and$b
is a string, it will always output -1 for such pairs.This creates an artificial total order, which is mainly useful for sorting values of mixed types.
-
Examples comparing values of the same type:
~> compare a b
▶ (num -1)
~> compare b a
▶ (num 1)
~> compare x x
▶ (num 0)
~> compare (num 10) (num 1)
▶ (num 1)
Examples comparing values of different types:
~> compare a (num 10)
Exception: bad value: inputs to "compare" or "order" must be comparable values, but is uncomparable values
[tty]:1:1-18: compare a (num 10)
~> compare &total a (num 10)
▶ (num -1)
~> compare &total (num 10) a
▶ (num 1)
See also order
.
conj
conj $list $more...
Outputs a list created from adding values in $more
to the end of $list
.
The output is the same as [$@list $more...]
, but the time complexity is
guaranteed to be O(m), where m is the number of values in $more
.
Examples:
~> conj [] a
▶ [a]
~> conj [a b] c d
▶ [a b c d]
Etymology: Clojure.
constantly
constantly $value...
Output a function that takes no arguments and outputs $value
s when called.
Examples:
~> var f = (constantly lorem ipsum)
~> $f
▶ lorem
▶ ipsum
The above example is equivalent to simply var f = { put lorem ipsum }
;
it is most useful when the argument is not a literal value, e.g.
~> var f = (constantly (whoami))
~> $f
▶ elf
~> $f
▶ elf
The above code only calls whoami
once when defining $f
. In contrast, if
$f
is defined as var f = { put (whoami) }
, every time you invoke $f
,
whoami
will be called.
Etymology: Clojure.
continue
continue
Raises the special “continue” exception. When raised inside a loop it is captured and causes the loop to begin its next iteration.
Because continue
raises an exception it can be caught by a
try
block. If not caught, either implicitly by a loop
or explicitly, it causes a failure like any other uncaught exception.
See the discussion about flow commands and exceptions
Note: You can create a continue
function and it will shadow the builtin
command. If you do so you should explicitly invoke the builtin. For example:
~> use builtin
~> fn continue { put 'continue'; builtin:continue; put 'should not appear' }
~> for x [a b c] { put $x; continue; put 'unexpected' }
▶ a
▶ continue
▶ b
▶ continue
▶ c
▶ continue
count
count $input-list?
Count the number of inputs.
Examples:
~> count lorem # count bytes in a string
▶ (num 5)
~> count [lorem ipsum]
▶ (num 2)
~> range 100 | count
▶ (num 100)
~> seq 100 | count
▶ (num 100)
defer
defer $fn
Schedules a function to be called when execution reaches the end of the current closure. The function is called with no arguments or options, and any exception it throws gets propagated.
Examples:
~> { defer { put foo }; put bar }
▶ bar
▶ foo
~> defer { put foo }
Exception: defer must be called from within a closure
[tty]:1:1-17: defer { put foo }
deprecate
deprecate $msg
Shows the given deprecation message to stderr. If called from a function or module, also shows the call site of the function or import site of the module. Does nothing if the combination of the call site and the message has been shown before.
~> deprecate msg
Deprecation: msg
[tty]:1:1-13: deprecate msg
~> fn f { deprecate msg }
~> f
Deprecation: msg
[tty]:1:1-1: f
~> f # a different call site; shows deprecate message
Deprecation: msg
[tty]:1:1-50: f # a different call site; shows deprecate message
~> fn g { f }
~> g
Deprecation: msg
[tty]:1:8-9: fn g { f }
~> g # same call site, no more deprecation message
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
▶ [&foo=bar &lorem=ipsum]
See also assoc
.
drop
drop $n $inputs?
Ignores the first $n
value inputs and outputs the rest.
If $n
is larger than the number of value inputs, outputs nothing.
Example:
~> range 10 | drop 8
▶ (num 8)
▶ (num 9)
~> range 2 | drop 10
~> drop 2 [a b c d e]
▶ c
▶ d
▶ e
~> use str
~> str:split ' ' 'how are you?' | drop 1
▶ are
▶ 'you?'
Etymology: Haskell.
See also take
.
each
each $f $inputs?
Calls $f
on each value input.
An exception raised from break
is caught by each
, and will cause it to
terminate early.
An exception raised from continue
is swallowed and can be used to
terminate a single iteration early.
Examples:
~> range 5 8 | each {|x| * $x $x }
▶ (num 25)
▶ (num 36)
▶ (num 49)
~> each {|x| put $x[..3] } [lorem ipsum]
▶ lor
▶ ips
See also peach
.
Etymology: Various languages, as for each
. Happens to have the same name as
the iteration construct of
Factor.
eawk
eawk &sep='[ \t]+' &sep-posix=$false &sep-longest=$false $f $inputs?
Deprecated alias for re:awk
. Will be removed in 0.21.0.
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.
See also print
.
Etymology: Bourne sh.
eq
eq $values...
Determines whether all $value
s are equal. Writes $true
when
given no or one argument.
Two values are equal when they have the same type and value.
For complex data structures like lists and maps, comparison is done recursively. A pseudo-map is equal to another pseudo-map with the same internal type (which is not exposed to Elvish code now) and value.
~> eq a a
▶ $true
~> eq [a] [a]
▶ $true
~> eq [&k=v] [&k=v]
▶ $true
~> eq a [b]
▶ $false
Etymology: Perl.
eval
eval $code &ns=$nil &on-end=$nil
Evaluates $code
, which should be a string. The evaluation happens in a
new, restricted namespace, whose initial set of variables can be specified by
the &ns
option. After evaluation completes, the new namespace is passed to
the callback specified by &on-end
if it is not nil.
The namespace specified by &ns
is never modified; it will not be affected
by the creation or deletion of variables by $code
. However, the values of
the variables may be mutated by $code
.
If the &ns
option is $nil
(the default), a temporary namespace built by
amalgamating the local and upvalue scopes of the
caller is used.
If $code
fails to parse or compile, the parse error or compilation error is
raised as an exception.
Basic examples that do not modify the namespace or any variable:
~> eval 'put x'
▶ x
~> var x = foo
~> eval 'put $x'
▶ foo
~> var ns = (ns [&x=bar])
~> eval &ns=$ns 'put $x'
▶ bar
Examples that modify existing variables:
~> var y = foo
~> eval 'set y = bar'
~> put $y
▶ bar
Examples that creates new variables and uses the callback to access it:
~> eval 'var z = lorem'
~> put $z
Compilation error: variable $z not found
[tty]:1:5-6: put $z
~> var saved-ns = $nil
~> eval &on-end={|ns| set saved-ns = $ns } 'var z = lorem'
~> put $saved-ns[z]
▶ lorem
Note that when using variables from an outer scope, only those
that have been referenced are captured as upvalues (see closure
semantics) and thus accessible to eval
:
~> var a b
~> fn f {|code| nop $a; eval $code }
~> f 'echo $a'
$nil
~> f 'echo $b'
Exception: Compilation error: variable $b not found
[eval 2]:1:6-7: echo $b
[tty]:1:22-32: fn f {|code| nop $a; eval $code }
[tty]:1:1-11: f 'echo $b'
exact-num
exact-num $string-or-number
Coerces the argument to an exact number. If the argument is infinity or NaN, an exception is thrown.
If the argument is a string, it is converted to a typed number first. If the argument is already an exact number, it is returned as is.
Examples:
~> exact-num (num 0.125)
▶ (num 1/8)
~> exact-num 0.125
▶ (num 1/8)
~> exact-num (num 1)
▶ (num 1)
Beware that seemingly simple fractions that can’t be represented precisely in binary can result in the denominator being a very large power of 2:
~> exact-num 0.1
▶ (num 3602879701896397/36028797018963968)
See also num
and inexact-num
.
exec
exec $command? $args...
Replace the Elvish process with an external $command
, defaulting to
elvish
, passing the given arguments. This decrements $E:SHLVL
before
starting the new process.
This command always raises an exception on Windows with the message “not supported on Windows”.
exit
exit $status?
Exit the Elvish process with $status
(defaulting to 0).
external
external $program
Construct a callable value for the external program $program
. Example:
~> var x = (external man)
~> $x ls # opens the manpage for ls
See also has-external
and search-external
.
fail
fail $v
Throws an exception; $v
may be any type. If $v
is already an exception,
fail
rethrows it.
~> fail bad
Exception: bad
[tty]:1:1-8: fail bad
~> put ?(fail bad)
▶ [^exception &reason=[^fail-error &content=bad &type=fail] &stack-trace=<...>]
~> fn f { fail bad }
~> fail ?(f)
Exception: bad
[tty]:1:8-16: fn f { fail bad }
[tty]:1:8-8: fail ?(f)
from-json
from-json
Takes bytes stdin, parses it as JSON and puts the result on structured stdout. The input can contain multiple JSONs, and whitespace between them are ignored.
Numbers in JSON are parsed as follows:
-
Numbers without fractional parts are parsed as exact integers, with support for arbitrary precision.
-
Numbers with fractional parts (even if it’s
.0
) are parsed as inexact floating-point numbers, and the parsing may fail if the number can’t be represented.
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]
~> echo '[42, 100000000000000000000, 42.0, 42.2]' | from-json
▶ [(num 42) (num 100000000000000000000) (num 42.0) (num 42.2)]
See also to-json
.
from-lines
from-lines
Splits byte input into lines, and writes them to the value output. Value input is ignored.
~> { echo a; echo b } | from-lines
▶ a
▶ b
~> { echo a; put b } | from-lines
▶ a
See also from-terminated
, read-upto
, and to-lines
.
from-terminated
from-terminated $terminator
Splits byte input into lines at each $terminator
character, and writes
them to the value output. If the byte input ends with $terminator
, it is
dropped. Value input is ignored.
The $terminator
must be a single ASCII character such as "\x00"
(NUL).
~> { echo a; echo b } | from-terminated "\x00"
▶ "a\nb\n"
~> print "a\x00b" | from-terminated "\x00"
▶ a
▶ b
~> print "a\x00b\x00" | from-terminated "\x00"
▶ a
▶ b
See also from-lines
, read-upto
, and to-terminated
.
-gc
-gc
Force the Go garbage collector to run.
This is only useful for debug purposes.
get-env
get-env $name
Gets the value of an environment variable. Throws an exception if the environment variable does not exist.
Calling get-env VAR_NAME
is similar to put $E:VAR_NAME
, but allows the
variable name to be dynamic, and throws an exception instead of producing an
empty string for nonexistent environment variables.
Examples:
~> get-env LANG
▶ zh_CN.UTF-8
~> get-env NO_SUCH_ENV
Exception: non-existent environment variable
[tty]:1:1-19: get-env NO_SUCH_ENV
See also has-env
, set-env
, and unset-env
.
has-env
has-env $name
Test whether an environment variable exists. This command has no equivalent
operation using the E:
namespace (but see https://b.elv.sh/1026).
Examples:
~> has-env PATH
▶ $true
~> has-env NO_SUCH_ENV
▶ $false
See also get-env
, set-env
, and 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
See also external
and 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-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
-ifaddrs
-ifaddrs
Output all IP addresses of the current host.
This should be part of a networking module instead of the builtin module.
inexact-num
inexact-num $string-or-number
Coerces the argument to an inexact number.
If the argument is a string, it is converted to a typed number first. If the argument is already an inexact number, it is returned as is.
Examples:
~> inexact-num (num 1)
▶ (num 1.0)
~> inexact-num (num 0.5)
▶ (num 0.5)
~> inexact-num (num 1/2)
▶ (num 0.5)
~> inexact-num 1/2
▶ (num 0.5)
Since the underlying representation for inexact numbers has limited range, numbers with very large magnitudes may be converted to an infinite value:
~> inexact-num 1000000000000000000
▶ (num 1e+18)
~> inexact-num 10000000000000000000
▶ (num +Inf)
~> inexact-num -10000000000000000000
▶ (num -Inf)
Likewise, numbers with very small magnitudes may be converted to 0:
~> use math
~> math:pow 10 -323
▶ (num 1/100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)
~> inexact-num (math:pow 10 -323)
▶ (num 1e-323)
~> math:pow 10 -324
▶ (num 1/1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)
~> inexact-num (math:pow 10 -324)
▶ (num 0.0)
is
is $values...
Determine whether all $value
s 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
See also eq
.
Etymology: Python.
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 $value
s. Example:
~> kind-of lorem [] [&]
▶ string
▶ list
▶ map
The terminology and definition of “kind” is subject to change.
-log
-log $filename
Direct internal debug logs to the named file.
This is only useful for debug purposes.
make-map
make-map $input?
Outputs a map from the value inputs, each of which must be an iterable value with with two elements. The first element of each value is used as the key, and the second element is used as the value.
If the same key appears multiple times, the last value is used.
Examples:
~> make-map [[k v]]
▶ [&k=v]
~> make-map [[k v1] [k v2]]
▶ [&k=v2]
~> put [k1 v1] [k2 v2] | make-map
▶ [&k1=v1 &k2=v2]
~> put aA bB | make-map
▶ [&a=A &b=B]
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.
not
not $value
Boolean negation. Examples:
~> not $true
▶ $false
~> not $false
▶ $true
~> not $ok
▶ $false
~> not ?(fail error)
▶ $true
Note: The related logical commands and
and or
are implemented as
special commands instead, since they do not
always evaluate all their arguments. The not
command always evaluates its
only argument, and is thus a normal command.
See also bool
.
not-eq
not-eq $a $b
Determines whether $a
and $b
are not equal. Equivalent to not (eq $a $b)
.
~> not-eq 1 2
▶ $true
~> not-eq 1 1
▶ $false
See also eq
.
ns
ns $map
Constructs a namespace from $map
, using the keys as variable names and the
values as their values. Examples:
~> var n = (ns [&name=value])
~> put $n[name]
▶ value
~> var n: = (ns [&name=value])
~> put $n:name
▶ value
num
num $string-or-number
Constructs a typed number.
If the argument is a string, this command outputs the typed number the argument represents, or raises an exception if the argument is not a valid representation of a number. If the argument is already a typed number, this command outputs it as is.
This command is usually not needed for working with numbers; see the discussion of numeric commands.
Examples:
~> num 10
▶ (num 10)
~> num 0x10
▶ (num 16)
~> num 1/12
▶ (num 1/12)
~> num 3.14
▶ (num 3.14)
~> num (num 10)
▶ (num 10)
See also exact-num
and inexact-num
.
one
one $inputs?
Takes exactly one value input and outputs it. If there are more than one value inputs, raises an exception.
This function can be used in a similar way to all
, but is a better
choice when you expect that there is exactly one output.
See also all
.
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
order
order &less-than=$nil &total=$false &key=$nil &reverse=$false $inputs?
Outputs the value inputs after sorting. The sorting process is stable.
By default, order
sorts the values in ascending order, using the same
comparator as compare
, which only supports values of the same ordered
type. Its options modify this behavior:
-
The
&less-than
option, if given, overrides the comparator. Its value should be a function that takes two arguments$a
and$b
and outputs a boolean indicating whether$a
is less than$b
. If the function throws an exception,order
rethrows the exception without outputting any value.The default behavior of
order
is equivalent toorder &less-than={|a b| == -1 (compare $a $b)}
. -
The
&total
option, if true, overrides the comparator to be same ascompare &total=$true
, which allows sorting values of mixed types and unordered types. The result groups values by their types. Groups of ordered types are sorted internally, and groups of unordered types retain their original relative order.Specifying
&total=$true
is equivalent to specifying&less-than={|a b| == -1 (compare &total=$true $a $b)}
. It is an error to both specify&total=$true
and a non-nil&less-than
callback. -
The
&key
option, if given, is a function that gets called with each input value. It must output a single value, which is used for comparison in place of the original value. The comparator used can be affected by$less-than
or&total
.If the function throws an exception,
order
rethrows the exception.Use of
&key
can usually be rewritten to use&less-than
instead, but using&key
can be faster. The&key
callback is only called once for each element, whereas the&less-than
callback is called O(n*lg(n)) times on average. -
The
&reverse
option, if true, reverses the order of output.
Examples:
~> put foo bar ipsum | order
▶ bar
▶ foo
▶ ipsum
~> order [(num 10) (num 1) (num 5)]
▶ (num 1)
▶ (num 5)
▶ (num 10)
~> order [[a b] [a] [b b] [a c]]
▶ [a]
▶ [a b]
▶ [a c]
▶ [b b]
~> order &reverse [a c b]
▶ c
▶ b
▶ a
~> put [0 x] [1 a] [2 b] | order &key={|l| put $l[1]}
▶ [1 a]
▶ [2 b]
▶ [0 x]
~> order &less-than={|a b| eq $a x } [l x o r x e x m]
▶ x
▶ x
▶ x
▶ l
▶ o
▶ r
▶ e
▶ m
Ordering heterogeneous values:
~> order [a (num 2) c (num 0) b (num 1)]
Exception: bad value: inputs to "compare" or "order" must be comparable values, but is uncomparable values
[tty]:1:1-37: order [a (num 2) c (num 0) b (num 1)]
~> order &total [a (num 2) c (num 0) b (num 1)]
▶ (num 0)
▶ (num 1)
▶ (num 2)
▶ a
▶ b
▶ c
Beware that strings that look like numbers are treated as strings, not
numbers. To sort strings as numbers, use an explicit &key
or &less-than
:
~> order [5 1 10]
▶ 1
▶ 10
▶ 5
~> order &key=$num~ [5 1 10]
▶ 1
▶ 5
▶ 10
~> order &less-than=$"<~" [5 1 10]
▶ 1
▶ 5
▶ 10
(The $"<~"
syntax is a reference to the <
function.)
See also compare
.
peach
peach &num-workers=(num +inf) $f $inputs?
Calls $f
for each value input, possibly in parallel.
Like each
, an exception raised from break
will cause peach
to
terminate early. However due to the parallel nature of peach
, the exact time
of termination is non-deterministic, and termination is not guaranteed.
An exception raised from continue
is swallowed and can be used to
terminate a single iteration early.
The &num-workers
option restricts the number of functions that may run in
parallel, and must be either an exact positive or +inf
. A value of +inf
(the default) means no restriction. Note that peach &num-workers=1
is
equivalent to each
.
Example (your output will differ):
~> range 1 10 | peach {|x| + $x 10 }
▶ (num 12)
▶ (num 13)
▶ (num 11)
▶ (num 16)
▶ (num 18)
▶ (num 14)
▶ (num 17)
▶ (num 15)
▶ (num 19)
~> range 1 101 |
peach {|x| if (== 50 $x) { break } else { put $x } } |
+ (all) # 1+...+49 = 1225; 1+...+100 = 5050
▶ (num 1328)
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
.
See also each
and run-parallel
.
pprint
pprint $value...
Pretty-print representations of Elvish values. Examples:
~> pprint [foo bar]
[
foo
bar
]
~> pprint [&k1=v1 &k2=v2]
[
&k1= v1
&k2= v2
]
The output format is subject to change.
See also repr
.
print &sep=' ' $value...
Like echo
, just without the newline.
See also echo
.
Etymology: Various languages, in particular
Perl and
zsh, whose
print
s do not print a trailing newline.
printf
printf $template $value...
Prints values to the byte stream according to a template.
The template may contain “formatting verbs”, sequences that start with %
.
Each verb corresponds to an argument, and specifies how that argument will be
converted and formatted:
-
%s
,%q
and%v
convert the argument to a string: -
%t
converts the argument to a boolean using bool, and prints it as eithertrue
orfalse
. -
%b
,%c
,%d
,%o
,%O
,%x
,%X
and%U
convert the argument to an integer, and then print it as follows:-
%b
: base 2 -
%c
: the character represented by the Unicode codepoint -
%d
: base 10 -
%o
: base 8 -
%O
: base 8, with0o
prefix -
%x
: base 16, with lower-case letters for a-f -
%X
: base 16, with upper-case letters for A-F -
%U
: Unicode format like U+1234; same asU+%04X
-
-
%e
,%E
,%f
,%F
,%g
and%G
convert the argument to a floating-point number usinginexact-num
, and print it as follows:-
%e
: scientific notation like -1.234456e+78 -
%E
: scientific notation like -1.234456E+78 -
%f
: decimal point but no exponent, like 123.456 -
%F
: same as%f
-
%g
:%e
for large exponents,%f
otherwise -
%G
:%E
for large exponents,%F
otherwise
-
-
%%
prints a literal%
and consumes no argument.
Unsupported verbs not documented don’t cause exceptions, but the output will
contain content like %!Z(unsupported formatting verb)
.
Flags may be added between %
and the verb to modify behavior like precision
and padding. See Go’s fmt
package for details.
This command does not add a trailing newline. Include it explicitly in the
template, like printf "Hello %s\n" world
.
Examples:
~> use math
~> printf ": %10s %.3f\n" Pi $math:pi
printf ": %10s %.3f\n" E $math:e
: Pi 3.142
: E 2.718
~> printf "%-10s %.2f %s\n" Pi $math:pi $math:pi
Pi 3.14 3.141592653589793
~> printf "%d\n" 0b11100111
231
~> printf "%08b\n" 231
11100111
~> printf "list is: %q\n" [foo bar 'foo bar']
list is: [foo bar 'foo bar']
Since printf
writes to the byte stream, capturing its output will generate
one value per line. To capture it into one string value, use it together with
slurp
, as in var s = (printf ... | slurp)
.
Note: Compared to the POSIX printf
command
found in other shells, there are 3 key differences:
-
The behavior of the formatting verbs are based on Go’s
fmt
package instead of the POSIX specification. -
The number of arguments after the formatting template must match the number of formatting verbs. The POSIX command will repeat the template string to consume excess values; this command does not have that behavior.
-
This command does not interpret escape sequences such as
\n
; just use double-quoted strings.
See also print
, echo
, pprint
, and repr
.
put
put $value...
Takes arbitrary arguments and write them to the structured stdout.
Examples:
~> put a
▶ a
~> put lorem ipsum [a b] [&k=v]
▶ lorem
▶ ipsum
▶ [a b]
▶ [&k=v]
Note: It is almost never necessary to use put (...)
- just write the
...
part. For example, put (eq a b)
is the equivalent to just eq a b
.
Etymology: Various languages, in particular
C and
Ruby as puts
.
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 N such that $low <= N < $high
. If not given,
$low
defaults to 0. Examples:
~> # Emulate dice
randint 1 7
▶ 6
-randseed
-randseed $seed
Sets the seed for the random number generator.
range
range &step $start=0 $end
Outputs numbers, starting from $start
and ending before $end
, using
&step
as the increment.
-
If
$start
<=$end
,&step
defaults to 1, andrange
outputs values as long as they are smaller than$end
. An exception is thrown if&step
is given a negative value. -
If
$start
>$end
,&step
defaults to -1, andrange
outputs values as long as they are greater than$end
. An exception is thrown if&step
is given a positive value.
As a special case, if the outputs are floating point numbers, range
also
terminates if the values stop changing.
This command is exactness-preserving.
Examples:
~> range 4
▶ (num 0)
▶ (num 1)
▶ (num 2)
▶ (num 3)
~> range 4 0
▶ (num 4)
▶ (num 3)
▶ (num 2)
▶ (num 1)
~> range -3 3 &step=2
▶ (num -3)
▶ (num -1)
▶ (num 1)
~> range 3 -3 &step=-2
▶ (num 3)
▶ (num 1)
▶ (num -1)
~> use math
~> range (- (math:pow 2 53) 1) +inf
▶ (num 9007199254740991.0)
▶ (num 9007199254740992.0)
When using floating-point numbers, beware that numerical errors can result in an incorrect number of outputs:
~> range 0.9 &step=0.3
▶ (num 0.0)
▶ (num 0.3)
▶ (num 0.6)
▶ (num 0.8999999999999999)
Avoid this problem by using exact rationals:
~> range 9/10 &step=3/10
▶ (num 0)
▶ (num 3/10)
▶ (num 3/5)
One usage of this command is to execute something a fixed number of times by combining with each:
~> range 3 | each {|_| echo foo }
foo
foo
foo
Etymology: Python.
read-bytes
read-bytes $n
Reads $n
bytes, or until end-of-file, and outputs the bytes as a string
value. The result may not be a valid UTF-8 string.
Examples:
~> echo "a,b" | read-bytes 2
▶ 'a,'
~> echo "a,b" | read-bytes 10
▶ "a,b\n"
read-line
read-line
Reads a single line from byte input, and writes the line to the value output,
stripping the line ending. A line can end with "\r\n"
, "\n"
, or end of
file. Examples:
~> print line | read-line
▶ line
~> print "line\n" | read-line
▶ line
~> print "line\r\n" | read-line
▶ line
~> print "line-with-extra-cr\r\r\n" | read-line
▶ "line-with-extra-cr\r"
read-upto
read-upto $terminator
Reads byte input until $terminator
or end-of-file is encountered. It outputs the part of the
input read as a string value. The output contains the trailing $terminator
, unless read-upto
terminated at end-of-file.
The $terminator
must be a single ASCII character such as "\x00"
(NUL).
Examples:
~> echo "a,b,c" | read-upto ","
▶ 'a,'
~> echo "foo\nbar" | read-upto "\n"
▶ "foo\n"
~> echo "a.elv\x00b.elv" | read-upto "\x00"
▶ "a.elv\x00"
~> print "foobar" | read-upto "\n"
▶ foobar
render-styledownadded in 0.21
render-styledown $s
Renders “styledown” markup into a styled text. For the styledown markup format, see https://pkg.go.dev/src.elv.sh@master/pkg/ui/styledown.
Examples:
~> render-styledown '
foo bar
*** ###
'[1..]
▶ [^styled (styled-segment foo &bold) ' ' (styled-segment bar &inverse) "\n"]
To see the rendered text in the terminal, pass it to print
, like
render-styledown ... | print (one)
.
See also styled
.
repeat
repeat $n $value
Output $value
for $n
times. Example:
~> repeat 0 lorem
~> repeat 4 NAN
▶ NAN
▶ NAN
▶ NAN
▶ NAN
Etymology: Clojure.
repr
repr $value...
Writes representation of $value
s, separated by space and followed by a
newline. Example:
~> repr [foo 'lorem ipsum'] "aha\n"
[foo 'lorem ipsum'] "aha\n"
See also pprint
.
Etymology: Python.
resolve
resolve $command
Output what $command
resolves to in symbolic form. Command resolution is
described in the language reference.
Example:
~> resolve echo
▶ '$echo~'
~> fn f { }
~> resolve f
▶ '$f~'
~> resolve cat
▶ '(external cat)'
return
return
Raises the special “return” exception. When raised inside a named function
(defined by the fn
keyword) it is captured by the
function and causes the function to terminate. It is not captured by an
ordinary anonymous function.
Because return
raises an exception it can be caught by a
try
block. If not caught, either implicitly by a
named function or explicitly, it causes a failure like any other uncaught
exception.
See the discussion about flow commands and exceptions
Note: If you want to shadow the builtin return
function with a local
wrapper, do not define it with fn
as fn
swallows the special exception
raised by return. Consider this example:
~> use builtin
~> fn return { put return; builtin:return }
~> fn test-return { put before; return; put after }
~> test-return
▶ before
▶ return
▶ after
Instead, shadow the function by directly assigning to return~
:
~> use builtin
~> var return~ = { put return; builtin:return }
~> fn test-return { put before; return; put after }
~> test-return
▶ before
▶ return
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 exception is thrown when all callables finish execution.
The behavior of run-parallel
is consistent with the behavior of pipelines,
except that it does not perform any redirections.
Here is an example that lets you pipe the stdout and stderr of a command to two different commands in order to independently capture the output of each byte stream:
~> use file
~> fn capture {|f|
var pout = (file:pipe)
var perr = (file:pipe)
var out err
run-parallel {
$f > $pout[w] 2> $perr[w]
file:close $pout[w]
file:close $perr[w]
} {
set out = (slurp < $pout[r])
file:close $pout[r]
} {
set err = (slurp < $perr[r])
file:close $perr[r]
}
put $out $err
}
~> capture { echo stdout-test; echo stderr-test >&2 }
▶ "stdout-test\n"
▶ "stderr-test\n"
This command is intended for doing a fixed number of heterogeneous things in
parallel. If you need homogeneous parallel processing of possibly unbound data,
use peach
instead.
See also 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
See also external
and has-external
.
set-env
set-env $name $value
Sets an environment variable to the given value. Calling set-env VAR_NAME value
is similar to set E:VAR_NAME = value
, but allows the variable name
to be dynamic.
Example:
~> set-env X foobar
~> put $E:X
▶ foobar
See also get-env
, has-env
, and unset-env
.
show
show $e
Shows the value to the output, which is assumed to be a VT-100-compatible terminal.
Currently, the only type of value that can be showed is exceptions, but this will likely expand in future.
Example:
~> var e = ?(fail lorem-ipsum)
~> show $e
Exception: lorem-ipsum
[tty]:1:11-26: var e = ?(fail lorem-ipsum)
sleep
sleep $duration
Pauses for at least the specified duration. The actual pause duration depends on the system.
This only affects the current Elvish context. It does not affect any other
contexts that might be executing in parallel as a consequence of a command
such as peach
.
A duration can be a simple number (with optional fractional value) without an explicit unit suffix, with an implicit unit of seconds.
A duration can also be a string written as a sequence of decimal numbers, each with optional fraction, plus a unit suffix. For example, “300ms”, “1.5h” or “1h45m7s”. Valid time units are “ns”, “us” (or “µs”), “ms”, “s”, “m”, “h”.
Passing a negative duration causes an exception; this is different from the
typical BSD or GNU sleep
command that silently exits with a success status
without pausing when given a negative duration.
See the Go documentation for more information about how durations are parsed.
Examples:
~> sleep 0.1 # sleeps 0.1 seconds
~> sleep 100ms # sleeps 0.1 seconds
~> sleep 1.5m # sleeps 1.5 minutes
~> sleep 1m30s # sleeps 1.5 minutes
~> sleep -1
Exception: sleep duration must be >= zero
[tty 8], line 1: sleep -1
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
.
src
src
Output a map describing the current source, which is the source file or
interactive command that contains the call to src
. The value contains the
following fields:
-
name
, a unique name of the current source. If the source originates from a file, it is the full path of the file. -
code
, the full body of the current source. -
is-file
, whether the source originates from a file.
Examples:
~> src
▶ [&code=src &is-file=$false &name='[tty 1]']
~> elvish show-src.elv
▶ [&code="src\n" &is-file=$true &name=/home/elf/show-src.elv]
~> echo src > .config/elvish/lib/show-src.elv
~> use show-src
▶ [&code="src\n" &is-file=$true &name=/home/elf/.config/elvish/lib/show-src.elv]
-stack
-stack
Print a stack trace.
This is only useful for debug purposes.
styled
styled $object $style-transformer...
Constructs a styled text by applying the supplied transformers to the
supplied $object
, which may be a string, a styled
segment, or an existing styled text.
Each $style-transformer
can be one of the following:
-
A boolean attribute name:
-
One of
bold
,dim
,italic
,underlined
,blink
andinverse
for setting the corresponding 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
andwhite
. -
The bright variant of the 8 basic ANSI colors, with a
bright-
prefix. -
Any color from the xterm 256-color palette, as
colorX
(such ascolor12
). -
A 24-bit RGB color written as
#RRGGBB
(such as'#778899'
).Note: You need to quote such values, since an unquoted
#
introduces a comment (e.g. use'bg-#778899'
instead ofbg-#778899
).
-
-
A color name prefixed by
fg-
to set the foreground color. This has the same effect as specifying the color name without thefg-
prefix. -
A color name prefixed by
bg-
to set the background color. -
A function that receives a styled segment as the only argument and outputs a single styled segment: this function will be applied to all the segments.
When a styled text is converted to a string the corresponding ANSI SGR code is built to render the style.
If the NO_COLOR
environment variable is set and
non-empty when Elvish starts, color output is suppressed. Modifications to
NO_COLOR
within Elvish (including from rc.elv
) do not affect the current
process, but will affect child Elvish processes.
Examples:
echo (styled foo red bold) # prints red bold "foo"
echo (styled (styled foo red bold) green) # prints green bold "foo"
A styled text can contain multiple segments with different styles. Such styled texts can be constructed by concatenating multiple styled texts with the compounding syntax. Strings and styled segments are automatically “promoted” to styled texts when concatenating. Examples:
echo foo(styled bar red) # prints "foo" + red "bar"
echo (styled foo bold)(styled bar red) # prints bold "foo" + red "bar"
The individual segments in a styled text can be extracted by indexing:
var s = (styled abc red)(styled def green)
put $s[0] $s[1]
When printed to the terminal, a styled text is not affected by any existing SGR styles in effect, and it will always reset the SGR style afterwards. For example:
print "\e[1m"
echo (styled foo red)
echo bar
# "foo" will be printed as red, but not bold
# "bar" will be printed without any style
See also render-styledown
.
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, a building block for styled texts.
-
If
$object
is a string, constructs a styled segment with$object
as the content, and the properties specified by the options. -
If
$object
is a styled segment, constructs a styled segment that is a copy of$object
, with the properties specified by the options overridden.
The properties of styled segments can be inspected by indexing into it. Valid
keys are the same as the options to styled-segment
, plus text
for the
string content:
~> var s = (styled-segment abc &bold)
~> put $s[text]
▶ abc
~> put $s[fg-color]
▶ default
~> put $s[bold]
▶ $true
Prefer the high-level styled
command to build and transform styled
texts. Styled segments are a low-level construct, and you only have to deal
with it when building custom style transformers.
In the following example, a custom transformer sets the inverse
property
for every bold segment:
styled foo(styled bar bold) {|x| styled-segment $x &inverse=$x[bold] }
# transforms "foo" + bold "bar" into "foo" + bold and inverse "bar"
take
take $n $inputs?
Outputs the first $n
value inputs. If $n
is larger than
the number of value inputs, outputs everything.
Examples:
~> range 2 | take 10
▶ (num 0)
▶ (num 1)
~> take 3 [a b c d e]
▶ a
▶ b
▶ c
~> use str
~> str:split ' ' 'how are you?' | take 1
▶ how
Etymology: Haskell.
See also drop
.
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'
time
time &on-end=$nil $callable
Runs the callable, and call $on-end
with the duration it took, as a
number in seconds. If $on-end
is $nil
(the default), prints the
duration in human-readable form.
If $callable
throws an exception, the exception is propagated after the
on-end or default printing is done.
If $on-end
throws an exception, it is propagated, unless $callable
has
already thrown an exception.
Example:
~> time { sleep 1 }
1.006060647s
~> time { sleep 0.01 }
1.288977ms
~> var t = ''
~> time &on-end={|x| set t = $x } { sleep 1 }
~> put $t
▶ (num 1.000925004)
~> time &on-end={|x| set t = $x } { sleep 0.01 }
~> put $t
▶ (num 0.011030208)
See also benchmark
.
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"}
See also from-json
.
to-lines
to-lines $inputs?
Writes each input to a separate line in the byte output.
~> put a b | to-lines
a
b
~> to-lines [a b]
a
b
See also from-lines
and to-terminated
.
to-string
to-string $value...
Convert arguments to string values.
~> to-string foo [a] [&k=v]
▶ foo
▶ '[a]'
▶ '[&k=v]'
to-terminated
to-terminated $terminator $inputs?
Writes each input to the byte output with the specified terminator character.
The $terminator
must be a single ASCII character such as "\x00"
(NUL).
Using NUL is useful for feeding output to programs that expect NUL-terminated
strings, such as grep -z
or xargs -0
.
~> put a b | to-terminated "\x00" | slurp
▶ "a\x00b\x00"
~> to-terminated "\x00" [a b] | slurp
▶ "a\x00b\x00"
See also from-terminated
and to-lines
.
unset-env
unset-env $name
Unset an environment variable. Calling unset-env VAR_NAME
is similar to
del E:VAR_NAME
, but allows the variable name to be dynamic.
Example:
~> set E:X = foo
~> unset-env X
~> has-env X
▶ $false
~> put $E:X
▶ ''
See also has-env
, get-env
, and set-env
.
use-mod
use-mod $use-spec
Imports a module, and outputs the namespace for the module.
Most code should use the use special command instead.
Examples:
~> echo 'var x = value' > a.elv
~> put (use-mod ./a)[x]
▶ value
wcswidth
wcswidth $string
Output the width of $string
when displayed on the terminal. Examples:
~> wcswidth a
▶ (num 1)
~> wcswidth lorem
▶ (num 5)
~> wcswidth 你好,世界
▶ (num 10)