elvish-builtin(7)
✨ Introduction ✨
bestie, this is the elvish-builtin(7) manual page. The builtin module contains facilities that are potentially useful to all users. 💖
🫶 Using builtin: explicitly 🫶
okay so the builtin module is consulted implicitly when resolving unqualified names, so you usually don’t need to specify builtin: explicitly. However, there are some cases where it is useful to do that:
- When a builtin function is shadowed by a local function, you can still use the builtin function by specifying
builtin:. This is especially useful when wrapping a builtin function:
use builtin
fn cd [@args]{
echo running my cd function
builtin:cd $@args
}
- Introspecting 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 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:
- 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
- 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 explicitputcommands. Avoidcount [(some-command)]oreach $some-func [(some-command)]; they are, most of the time, equivalent tosome-command | countorsome-command | each $some-func.
Rationale: An alternative way to design this is to make (say)counttake an arbitrary number of arguments, and count its arguments; when there is 0 argument,countinputs. However, this leads to problems in code likecount *; the intention is clearly to count the number of files in the current directory, but when the current directory is empty,countwill 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 🔢
Anywhere 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 {#exactness-preserving} 💯
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.
🧪 Predicates 🧪
Predicates are functions that write exactly one output that is either $true or $false. They are described 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 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.)
Those functions and variables are documented near the end of the respective sections. Their known problem is also discussed.
🧚 Variables 🧚
$_ {#_} — the blackhole variable 🕳️
A blackhole variable.
Values assigned to it will be discarded. Referencing it always results in $nil.
$after-chdir {#after-chdir} — post-cd functions 💫
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>
See also before-chdir.
$args {#args} — command-line args, bestie 🎀
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 {#before-chdir} — pre-cd functions 🌸
A list of functions to run before changing directory. These functions are always called with the new working directory.
See also after-chdir.
$buildinfo {#buildinfo} — build info map 🛠️
A psuedo-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 {#false} — false bool 💔
The boolean false value.
$nil {#nil} — the lack-of-values icon 🌫️
A special value useful for representing the lack of values.
$notify-bg-job-success {#notify-bg-job-success} — bg job success pings 🔔
Whether to notify success of background jobs, defaulting to $true.
Failures of background jobs are always notified.
$num-bg-jobs {#num-bg-jobs} — how many bg jobs? 👀
Number of background jobs.
$ok {#ok} — no exceptions, periodt ✅
The special value used by ?() to signal absence of exceptions.
$paths {#paths} — search paths, but easier 🛣️
A list of search paths, kept in sync with $E:PATH. It is easier to use than $E:PATH.
$pid {#pid} — process ID 🆔
The process ID of the current Elvish process.
$pwd {#pwd} — present working directory 📍
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
for x [*/] {
pwd=$x {
if ?(test -d .git) {
git pull
}
}
}
Etymology: the pwd command.
See also cd.
$true {#true} — true bool 💚
The boolean true value.
$value-out-indicator {#value-out-indicator} — the little arrow before outputs ➡️
A string put before value outputs (such as those 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.
$version {#version} — version string, but don't just compare it 🏷️
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 ➕
+ {#add} — sum it up ✨
+ $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)
- {#sub} — subtraction and negation 💅
- $x-num $y-num...
Outputs the result of subtracting from $x-num all the $y-nums, 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)
* {#mul} — multiply the vibes ✖️
* $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)
/ {#div} — division 🌀
/ $x-num $y-num...
so next up ✨ in the builtin roster is the division command — you know, the slash / that you'd expect. It takes $x-num and divides it by all the $y-nums, working from left to right. If you don't give it any $y-num, it gives you the reciprocal of $x-num instead. In other words, / $y-num is literally equivalent to / 1 $y-num. 💅
Dividing by exact 0? Big yikes — it raises an exception. But dividing by inexact 0? That gives you either infinity or NaN, following floating-point semantics. So 0 and 0.0 are NOT the same. 💀
This command is exactness-preserving, which is iconic. And when $x-num is exact 0 and no $y-num is exact 0, the result is exact 0. Periodt. 💅
Here's the vibe check with 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 6], line 1: / 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 will probably change to avoid this oddity). So yeah, just / by itself changes directory to root. Wild, right? 🌀
% {#rem} 🎀
% $x $y
Output the remainder after dividing $x by $y. The result has the same sign as $x. Both must be integers that can be represented in a machine word (this limit may be lifted in future). So it's like the % operator in C, but as a command. 🔢
Examples:
~> % 10 3
▶ 1
~> % -10 3
▶ -1
~> % 10 -3
▶ 1
< <= == != > >= {#num-cmp} ✨
< $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:
- When given fewer than two arguments, all output
$true. - When given two arguments, output whether the two arguments satisfy the named relationship.
- 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 {#str-cmp} 🦋
<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} 🌸
all $input-list?
Passes inputs to the output as is. Byte inputs into values, one per line.
This is an identity function for commands with value outputs: a | all is equivalent to a if it only outputs values.
This function is useful for turning inputs into arguments, like:
~> use str
~> put 'lorem,ipsum' | str:split , (all)
▶ lorem
▶ ipsum
Or capturing all inputs in a variable:
~> x = [(all)]
foo
bar
(Press ^D)
~> put $x
▶ [foo bar]
When given a list, it outputs all elements of the list:
~> all [foo bar]
▶ foo
▶ bar
See also one.
assoc {#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).
See also dissoc.
base {#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
bool {#bool} 👑
bool $value
Convert a value to boolean. In Elvish, only $false 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
cd {#cd} 🌀
cd $dirname
Change directory. This affects the entire process; i.e., all threads whether running indirectly (e.g., prompt functions) or started explicitly by commands such as peach.
Note that Elvish’s cd does not support cd -.
See also pwd.
compare {#compare} ⭐
compare $a $b
Outputs -1 if $a < $b, 0 if $a = $b, and 1 if $a > $b.
The following comparison algorithm is used:
- Typed numbers are compared numerically. The comparison is consistent with the number comparison commands, except that NaN values are considered equal to each other and smaller than all other numbers.
- Strings are compared lexicographically by bytes, consistent with the string comparison commands. For UTF-8 encoded strings, this is equivalent to comparing by codepoints.
- Lists are compared lexicographically by elements, if the elements at the same positions are comparable.
If the ordering between two elements is not defined by the conditions above, i.e. if the value of $a or $b is not covered by any of the cases above or if they belong to different cases, a “bad value” exception is thrown.
Examples:
~> compare a b
▶ (num 1)
~> compare b a
▶ (num -1)
~> compare x x
▶ (num 0)
~> compare (float64 10) (float64 1)
▶ (num 1)
Beware that strings that look like numbers are treated as strings, not numbers.
See also order.
constantly {#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).
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} 🔥
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
deprecate {#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
~> fn f { deprecate msg }
~> f
deprecation: msg
[tty 19], line 1: f
~> exec
~> deprecate msg
deprecation: msg
~> fn f { deprecate msg }
~> f
deprecation: msg
[tty 3], line 1: f
~> f # a different call site; shows deprecate message
deprecation: msg
[tty 4], line 1: f
~> fn g { f }
~> g
deprecation: msg
[tty 5], line 1: fn g { f }
~> g # same call site, no more deprecation message
dir-history {#dir-history} 🌈
dir-history
Return a list containing the interactive 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]
See also edit:command-history.
dissoc {#dissoc}
dissoc $map $k
Hands you back a slightly different version of $map — specifically the one where key $k has been yeeted into the void 🫶. And if $map never had $k as a key in the first place? You just get the same map back. no notes, no drama.
~> dissoc [&foo=bar &lorem=ipsum] foo
▶ [&lorem=ipsum]
~> dissoc [&foo=bar &lorem=ipsum] k
▶ [&lorem=ipsum &foo=bar]
See also assoc.
drop {#drop}
drop $n $input-list?
Drops the first $n elements of the input, periodt. And if $n is bigger than the actual number of input elements you've got? Then the entire input gets dropped 💀. gone. all of it.
Example:
~> drop 2 [a b c d e]
▶ c
▶ d
▶ e
~> use str
~> str:split ' ' 'how are you?' | drop 1
▶ are
▶ 'you?'
~> range 2 | drop 10
Etymology: Haskell.
See also take.
each {#each}
each $f $input-list?
Calls $f on all the inputs. that's it, that's the whole vibe ✨
An exception raised from break is caught by each, and it'll make it terminate early. An exception raised from continue is swallowed, and you can use it to terminate a single iteration early.
Examples:
~> range 5 8 | each {|x| * $x $x }
▶ 25
▶ 36
▶ 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 (http://docs.factor-code.org/content/word-each,sequences.html).
eawk {#eawk}
eawk $f $input-list?
For each input, calls $f with the input followed by all of its fields. A break command will make eawk stop processing inputs. A continue command will exit $f, but eawk just ignores it 🙈.
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 lets you write code that's very similar to awk scripts, but using anonymous functions. slay. 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}
echo &sep=' ' $value...
Prints all its 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. To print special characters, use double-quoted strings, and reach for print when you want to suppress the trailing newline.
See also print.
Etymology: Bourne sh.
eq {#eq}
eq $values...
Figures out whether all $values are equal. With no arguments or just one, it writes $true (yes bestie, vacuously true, iconic).
Two values are equal when they have the same type and value.
For complex data structures like lists and maps, the comparison is done recursively. A pseudo-map is equal to another pseudo-map with the same internal type (which isn't exposed to Elvish code right now) and value.
~> eq a a
▶ $true
~> eq [a] [a]
▶ $true
~> eq [&k=v] [&k=v]
▶ $true
~> eq a [b]
▶ $false
See also is and not-eq.
Etymology: Perl (https://perldoc.perl.org/perlop.html#Equality-Operators).
eval {#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 you can specify with the &ns option. Once evaluation finishes, the new namespace gets passed to the callback specified by &on-end — if it's not nil, that is.
The namespace specified by &ns is never modified; it will not be affected by the creation or deletion of variables by $code. However — plot twist — the values of the variables may be mutated by $code.
If the &ns option is $nil (which is 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
~> x = foo
~> eval 'put $x'
▶ foo
~> ns = (ns [&x=bar])
~> eval &ns=$ns 'put $x'
▶ bar
Examples that modify existing variables:
~> y = foo
~> eval 'y = bar'
~> put $y
▶ bar
Examples that creates new variables and uses the callback to access it:
~> eval 'z = lorem'
~> put $z
compilation error: variable $z not found
[ttz 2], line 1: put $z
~> saved-ns = $nil
~> eval &on-end={|ns| saved-ns = $ns } 'z = lorem'
~> put $saved-ns[z]
▶ lorem
exact-num {#exact-num}
exact-num $string-or-number
Coerces the argument to an exact number. If the argument is infinity or NaN, an exception gets thrown 🚨.
If the argument is a string, it's converted to a typed number first. If the argument is already an exact number, it comes back to you 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)
exec {#exec}
exec $command? $args...
Replaces the Elvish process with an external $command, defaulting to elvish, passing along 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}
exit $status?
Exits the Elvish process with $status (which defaults to 0). bye bestie 👋
external {#external}
external $program
Constructs a callable value for the external program $program. Example:
~> x = (external man)
~> $x ls # opens the manpage for ls
See also has-external and search-external.
fail {#fail}
fail $v
Throws an exception; $v can be any type. And if $v is already an exception, fail rethrows it 🔥.
~> fail bad
Exception: bad
[tty 9], line 1: fail bad
~> put ?(fail bad)
▶ ?(fail bad)
~> fn f { fail bad }
~> fail ?(f)
Exception: bad
Traceback:
[tty 7], line 1:
fn f { fail bad }
[tty 8], line 1:
fail ?(f)
float64 {#float64}
float64 $string-or-number
Constructs a floating-point number.
This command is deprecated; use num instead. 🫶
from-json {#from-json}
from-json
Takes bytes on stdin, parses them as JSON, and puts the result on structured stdout. The input can contain multiple JSONs, and whitespace between them is ignored.
Note that JSON's only number type corresponds to Elvish's floating-point number type, and is always considered inexact. It may be necessary to coerce JSON numbers to exact numbers using exact-num.
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]
See also to-json.
from-lines {#from-lines}
from-lines
Splits byte input into lines, and writes them to the value output. Value input is ignored (sorry, value input, it's not your moment 💅).
~> { 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}
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 gets 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}
-gc
Forces the Go garbage collector to run. ✨
This is only useful for debug purposes.
get-env {#get-env}
get-env $name
Gets the value of an environment variable. Throws an exception if the environment variable doesn't exist 😭. 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
See also has-env, set-env and unset-env.
has-env {#has-env}
has-env $name
Tests whether an environment variable exists. Examples:
~> has-env PATH
▶ $true
~> has-env NO_SUCH_ENV
▶ $false
See also get-env, set-env and unset-env.
has-external {#has-external}
has-external $command
Tests 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}
has-key $container $key
Determines 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, btw 👑
Examples, maps:
~> has-key [&k1=v1 &k2=v2] k1
▶ $true
~> has-key [&k1=v1 &k2=v2] v1
▶ $false
Examples, lists:
and for lists, it's giving:
~> 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}
has-value $container $value
So bestie, has-value is literally checking if $value is a value in $container. It's giving “is this in here?” energy. 💅
🗺️ 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}
-ifaddrs
Outputs all IP addresses of the current host. Lowkey this should be part of a networking module instead of the builtin module. 🙈
🪞 is {#is}
is $values...
Determines 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. No cap.
~> is a a
▶ $true
~> is a b
▶ $false
~> is [] []
▶ $true
~> is [a] [a]
▶ $false
See also eq.
Etymology: Python (https://docs.python.org/3/reference/expressions.html#is). 🐍
🔑 keys {#keys}
keys $map
Puts 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. It's giving chaotic. 😭
🧬 kind-of {#kind-of}
kind-of $value...
Outputs the kinds of $values. Example:
~> kind-of lorem [] [&]
▶ string
▶ list
▶ map
The terminology and definition of “kind” is subject to change. So don't get too attached. 💀
📝 -log {#-log}
-log $filename
Directs internal debug logs to the named file.
This is only useful for debug purposes. It's giving “for the devs only” energy. 🛠️
🗺️ make-map {#make-map}
make-map $input?
Outputs a map from an input consisting of containers with two elements. The first element of each container 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. Slay.
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}
nop &any-opt= $value...
Accepts arbitrary arguments and options and does exactly nothing. It's the definition of “I'm just here for the vibes.” 💅
Examples:
~> nop
~> nop a b c
~> nop &k=v
Etymology: Various languages, in particular NOP in assembly languages (https://en.wikipedia.org/wiki/NOP). 🏛️
❌ not {#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. So it's giving reliable. ✨
See also bool.
🚫 not-eq {#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
See also eq.
📦 ns {#ns}
ns $map
Constructs a namespace from $map, using the keys as variable names and the values as their values. Examples:
~> n = (ns [&name=value])
~> put $n[name]
▶ value
~> n: = (ns [&name=value])
~> put $n:name
▶ value
🔢 num {#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. So lowkey you might not need it. 😌
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)
1️⃣ one {#one}
one $input-list?
Passes inputs to outputs, if there is only a single one. Otherwise 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}
only-bytes
Passes byte input to output, and discards value inputs.
Example:
~> { put value; echo bytes } | only-bytes
bytes
🔢 only-values {#only-values}
only-values
Passes value input to output, and discards byte inputs.
Example:
~> { put value; echo bytes } | only-values
▶ value
🔀 order {#order}
order &reverse=$false $less-than=$nil $inputs?
Outputs the input values sorted in ascending order. The sort is guaranteed to be stable (https://en.wikipedia.org/wiki/Sorting_algorithm#Stability).
&reverse— if true, reverses the order of output.&less-than— if given, establishes the ordering of the elements. Its value should be a function that takes two arguments and outputs a single boolean indicating whether the first argument is less than the second argument. If the function throws an exception,orderrethrows the exception without outputting any value.
If &less-than has value $nil (the default if not set), it is equivalent to {|a b| eq -1 (compare $a $b) }.
Examples:
~> put foo bar ipsum | order
▶ bar
▶ foo
▶ ipsum
~> order [(float64 10) (float64 1) (float64 5)]
▶ (float64 1)
▶ (float64 5)
▶ (float64 10)
~> order [[a b] [a] [b b] [a c]]
▶ [a]
▶ [a b]
▶ [a c]
▶ [b b]
~> order &reverse [a c b]
▶ c
▶ b
▶ a
~> order &less-than={|a b| eq $a x } [l x o r x e x m]
▶ x
▶ x
▶ x
▶ l
▶ o
▶ r
▶ e
▶ m
Beware that strings that look like numbers are treated as strings, not numbers. To sort strings as numbers, use an explicit &less-than option:
~> order [5 1 10]
▶ 1
▶ 10
▶ 5
~> order &less-than={|a b| < $a $b } [5 1 10]
▶ 1
▶ 5
▶ 10
See also compare.
🍑 peach {#peach}
peach $f $input-list?
Calls $f on all inputs, 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 not even guaranteed.
An exception raised from continue is swallowed and can be used to terminate a single iteration early.
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}
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. So don't get too comfortable. 😌
See also repr.
🖨️ print {#print}
print &sep=' ' $value...
Like echo, just without the newline.
See also 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 trailing newline. 🌍
🖨️ printf {#printf}
printf $template $value...
Prints values to the byte stream according to a template. If you need to inject the output into the value stream use this pattern: printf .... | slurp. That ensures that any newlines in the output of printf do not cause its output to be broken into multiple values, thus eliminating the newlines, which will occur if you do put (printf ....).
Like print, this command does not add an implicit newline; include an explicit "\n" in the formatting template instead. For example, printf "%.1f\n" (/ 10.0 3).
See Go’s fmt (https://golang.org/pkg/fmt/#hdr-Printing) package for details about the formatting verbs and the various flags that modify the default behavior, such as padding and justification.
Unlike Go, each formatting verb has a single associated internal type, and accepts any argument that can reasonably be converted to that type:
- The verbs
%s,%qand%vconvert the corresponding argument to a string in different ways:%susesto-stringto convert a value to string.%qusesreprto convert a value to string.%vis equivalent to%s, and%#vis equivalent to%q.
- The verb
%tfirst convert the corresponding argument to a boolean usingbool, and then uses its counterpart to format the boolean. - The verbs
%b,%c,%d,%o,%O,%x,%Xand%Ufirst convert the corresponding argument to an integer using an internal algorithm, and then use their Go counterparts to format the integer. slay 💅 - The verbs
%e,%E,%f,%F,%gand%Gfirst convert the corresponding argument to a floating-point number usingfloat64, and then use their Go counterparts to format the number. vibe check passed ✨
The special verb %% prints a literal % and consumes no argument. no cap
Verbs not documented above are not supported. periodt 💀
Examples:
~> printf "%10s %.2f\n" Pi $math:pi
Pi 3.14
~> 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']
Note: Compared to the POSIX printf command (https://pubs.opengroup.org/onlinepubs/007908799/xcu/printf.html) found in other shells, there are 3 key differences:
- The behavior of the formatting verbs are based on Go’s
fmt(https://golang.org/pkg/fmt/) package instead of the POSIX specification. iykyk - 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. fr fr
- This command does not interpret escape sequences such as
\n; just use double-quoted strings. facts
See also print, echo, pprint and repr.
put {#put}
put $value...
Takes arbitrary arguments and write them to the structured stdout. iconic 👑
Examples:
~> put a
▶ a
~> put lorem ipsum [a b] { ls }
▶ lorem
▶ ipsum
▶ [a b]
▶ <closure 0xc4202607e0>
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. the way that works 😭
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. periodt
rand {#rand}
rand
Output a pseudo-random number in the interval [0, 1). Example:
~> rand
▶ 0.17843564133528436
randint {#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
range {#range}
range &step $start=0 $end
Outputs numbers, starting from $start and ending before $end, using &step as the increment. math queen 🧚
- If
$start <= $end,&stepdefaults to1, andrangeoutputs values as long as they are smaller than$end. An exception is thrown if&stepis given a negative value. no negative vibes - If
$start > $end,&stepdefaults to-1, andrangeoutputs values as long as they are greater than$end. An exception is thrown if&stepis given a positive value. opposite day
As a special case, if the outputs are floating point numbers, range also terminates if the values stop changing. vibe check
This command is exactness-preserving. slay
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)
~> 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)
Etymology: Python (https://docs.python.org/3/library/functions.html#func-range). iykyk
read-line {#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}
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. lowkey useful
The $terminator must be a single ASCII character such as "\x00" (NUL). important
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
repeat {#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). obsessed
repr {#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"
See also pprint. fr fr
Etymology: Python (https://docs.python.org/3/library/functions.html#repr). iykyk
resolve {#resolve}
resolve $command
Output what $command resolves to in symbolic form. Command resolution is described in the language reference. the more you know 🌈
Example:
~> resolve echo
▶ <builtin echo>
~> fn f { }
~> resolve f
▶ <closure 0xc4201c24d0>
~> 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. main character energy 👑
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. no cap
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
the way that works 😭
run-parallel {#run-parallel}
run-parallel $callable ...
Run several callables in parallel, and wait for all of them to finish. multitasking queen 🦋
If one or more callables throw exceptions, the other callables continue running, and a composite exception is thrown when all callables finish execution. drama
The behavior of run-parallel is consistent with the behavior of pipelines, except that it does not perform any redirections. facts
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:
~> 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. iykyk
See also peach.
search-external {#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. slay
set-env {#set-env}
set-env $name $value
Sets an environment variable to the given value. Example:
~> set-env X foobar
~> put $E:X
▶ foobar
See also get-env, has-env and unset-env. env queen
show {#show}
show $e
Shows the value to the output, which is assumed to be a VT-100-compatible terminal. retro vibes
Currently, the only type of value that can be showed is exceptions, but this will likely expand in future. coming soon
Example:
~> e = ?(fail lorem-ipsum)
~> show $e
Exception: lorem-ipsum
[tty 3], line 1: e = ?(fail lorem-ipsum)
sleep {#sleep}
sleep $duration
Pauses for at least the specified duration. The actual pause duration depends on the system. beauty sleep 💅
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. mind your own business
A duration can be a simple number (with optional fractional value) without an explicit unit suffix, with an implicit unit of seconds. math
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”. time is a construct
ok so bestie, real talk: if you pass a negative duration to sleep, it throws an exception. that's not like the typical BSD or GNU sleep command, which just silently exits with a success status and doesn't pause at all when you give it a negative duration. so don't expect that vibe here 💅
if you wanna know more about how durations are parsed, check the Go documentation at (https://golang.org/pkg/time/#ParseDuration) — that's where the tea is ☕
examples, because we love a visual:
~> 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
see? negative duration = exception. periodt.
slurp 🌊
ok so slurp reads bytes input into a single string, and then puts that string on structured stdout. it's giving 'vacuum up all the bytes' energy 🌀
Example:
~> echo "a\nb" | slurp
▶ "a\nb\n"
Etymology: it's from Perl, specifically File::Slurp (http://search.cpan.org/~uri/File-Slurp-9999.19/lib/File/Slurp.pm). periodt.
src 📍
src outputs a map-like value describing the current source being evaluated. the value contains these fields:
name, a unique name of the current source. if the source originates from a file, it's the full path of the file.code, the full body of the current source.is-file, whether the source originates from a file.
Examples:
~> put (src)[name code is-file]
▶ '[tty]'
▶ 'put (src)[name code is-file]'
▶ $false
~> echo 'put (src)[name code is-file]' > show-src.elv
~> elvish show-src.elv
▶ /home/elf/show-src.elv
▶ "put (src)[name code is-file]\n"
▶ $true
Note: this builtin always returns information of the source of the function calling src. consider the following example:
~> echo 'fn show { put (src)[name] }' > ~/.elvish/lib/src-fsutil.elv
~> use src-util
~> src-util:show
▶ /home/elf/.elvish/lib/src-fsutil.elv
-stack 🥞
prints a stack trace. this is only useful for debug purposes. no cap.
styled 💅
styled $object $style-transformer...
constructs a styled text by applying the supplied transformers to the supplied object. $object can be either 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:
- one of the attribute names
bold,dim,italic,underlined,blinkorinversefor 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.
- one of the attribute names
- 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,cyanandwhite. - 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
#RRGGBBsuch as'#778899'.
- one of the 8 basic ANSI colors:
Note: you need to quote such values since an unquoted#char introduces a comment. so use'bg-#778899'notbg-#778899. if you omit the quotes the text after the#char is ignored which will result in an error or unexpected behavior.
- a color name prefixed by
bg-to set the background color. - 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 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/wiki/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 custom 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?
retains 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
~> use str
~> str:split ' ' 'how are you?' | take 1
▶ how
~> range 2 | take 10
▶ 0
▶ 1
Etymology: Haskell. iykyk.
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 calls $on-end with the duration it took, as a number in seconds. if $on-end is $nil (the default), it 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
~> t = ''
~> time &on-end={|x| t = $x } { sleep 1 }
~> put $t
▶ (float64 1.000925004)
~> time &on-end={|x| t = $x } { sleep 0.01 }
~> put $t
▶ (float64 0.011030208)
to-json 📦
to-json
takes structured stdin, converts 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 $input?
writes each value input to a separate line in the byte output. byte input is ignored.
~> put a b | to-lines
a
b
~> to-lines [a b]
a
b
~> { put a; echo b } | to-lines
b
a
See also from-lines and to-terminated.
to-string 🧵
to-string $value...
converts arguments to string values.
~> to-string foo [a] [&k=v]
▶ foo
▶ '[a]'
▶ '[&k=v]'
to-terminated 🔚
to-terminated $terminator $input?
writes each value input to the byte output with the specified terminator character. byte input is ignored. this behavior is useful, for example, when feeding output into a program that accepts NUL terminated lines to avoid ambiguities if the values contain newline characters.
the $terminator must be a single ASCII character such as "\x00" (NUL).
~> 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
unsets an environment variable. Example:
~> 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 'x = value' > a.elv
~> put (use-mod ./a)[x]
▶ value
wcswidth 📏
wcswidth $string
outputs the width of $string when displayed on the terminal. Examples:
~> wcswidth a
▶ 1
~> wcswidth lorem
▶ 5
~> wcswidth 你好,世界
▶ 10
and that's the whole vibe, bestie! this was from Elvish 0.17.0, dated Nov 18, 2024, and the page is elvish-builtin(7). now go slay some shells 👑💖
📦 where this page comes from
- ubuntu jammy: elvish 0.17.0-1ubuntu0.1 · BSD-2-Clause
- 💖 girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms