.\" Automatically generated by Pandoc 2.9.2.1 .\" .TH "elvish-builtin" "7" "Jul 18, 2021" "Elvish 0.15.0" "Miscellaneous Information Manual" .hy .SH Introduction .PP The builtin module contains facilities that are potentially useful to all users. .SS Using builtin: explicitly .PP The builtin module is consulted implicitly when resolving unqualified names, so you usually don\[cq]t need to specify \f[C]builtin:\f[R] explicitly. However, there are some cases where it is useful to do that: .IP \[bu] 2 When a builtin function is shadowed by a local function, you can still use the builtin function by specifying \f[C]builtin:\f[R]. This is especially useful when wrapping a builtin function: .RS 2 .IP .nf \f[C] use builtin fn cd [\[at]args]{ echo running my cd function builtin:cd $\[at]args } \f[R] .fi .RE .IP \[bu] 2 Introspecting the builtin module, for example \f[C]keys $builtin:\f[R]. .SS Usage Notation .PP The usage of a builtin command is described by giving an example usage, using variables as arguments. For instance, The \f[C]repeat\f[R] command takes two arguments and are described as: .IP .nf \f[C] repeat $n $v \f[R] .fi .PP Optional arguments are represented with a trailing \f[C]?\f[R], while variadic arguments with a trailing \f[C]...\f[R]. For instance, the \f[C]count\f[R] command takes an optional list: .IP .nf \f[C] count $input-list? \f[R] .fi .PP While the \f[C]put\f[R] command takes an arbitrary number of arguments: .IP .nf \f[C] put $values... \f[R] .fi .PP Options are given along with their default values. For instance, the \f[C]echo\f[R] command takes an \f[C]sep\f[R] option and arbitrary arguments: .IP .nf \f[C] echo &sep=\[aq] \[aq] $value... \f[R] .fi .PP (When you calling functions, options are always optional.) .SS Supplying Input .PP Some builtin functions, e.g. \f[C]count\f[R] and \f[C]each\f[R], can take their input in one of two ways: .IP "1." 3 From pipe: .RS 4 .IP .nf \f[C] \[ti]> put lorem ipsum | count # count number of inputs 2 \[ti]> put 10 100 | each [x]{ + 1 $x } # apply function to each input \[u25B6] 11 \[u25B6] 101 \f[R] .fi .PP Byte pipes are also possible; one line becomes one input: .IP .nf \f[C] \[ti]> echo \[dq]a\[rs]nb\[rs]nc\[dq] | count # count number of lines \[u25B6] 3 \f[R] .fi .RE .IP "2." 3 From an argument \[en] an iterable value: .RS 4 .IP .nf \f[C] \[ti]> count [lorem ipsum] # count number of elements in argument 2 \[ti]> each [x]{ + 1 $x } [10 100] # apply to each element in argument \[u25B6] 11 \[u25B6] 101 \f[R] .fi .PP Strings, and in future, other sequence types are also possible: .IP .nf \f[C] \[ti]> count lorem \[u25B6] 5 \f[R] .fi .RE .PP When documenting such commands, the optional argument is always written as \f[C]$input-list?\f[R]. On the other hand, a trailing \f[C]$input-list?\f[R] always indicates that a command can take its input in one of two ways above: this fact is not repeated below. .PP \f[B]Note\f[R]: You should prefer the first form, unless using it requires explicit \f[C]put\f[R] commands. Avoid \f[C]count [(some-command)]\f[R] or \f[C]each $some-func [(some-command)]\f[R]; they are, most of the time, equivalent to \f[C]some-command | count\f[R] or \f[C]some-command | each $some-func\f[R]. .PP \f[B]Rationale\f[R]: An alternative way to design this is to make (say) \f[C]count\f[R] 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 \f[C]count *\f[R]; the intention is clearly to count the number of files in the current directory, but when the current directory is empty, \f[C]count\f[R] will wait for inputs. Hence it is required to put the input in a list: \f[C]count [*]\f[R] unambiguously supplies input in the argument, even if there is no file. .SS Commands That Operate On Numbers .PP Commands that operate on numbers are quite flexible about the format of those numbers. See the discussion of the number data type. .PP Because numbers are normally specified as strings, rather than as an explicit \f[C]float64\f[R] data type, some builtin commands have variants intended to operate on strings or numbers exclusively. For instance, the numerical equality command is \f[C]==\f[R], while the string equality command is \f[C]==s\f[R]. Another example is the \f[C]+\f[R] builtin, which only operates on numbers and does not function as a string concatenation command. Consider these examples: .IP .nf \f[C] \[ti]> + x 1 Exception: wrong type of 1\[aq]th argument: cannot parse as number: x [tty], line 1: + x 1 \[ti]> + inf 1 \[u25B6] (float64 +Inf) \[ti]> + -inf 1 \[u25B6] (float64 -Inf) \[ti]> + -infinity 1 \[u25B6] (float64 -Inf) \[ti]> + -infinityx 1 Exception: wrong type of 1\[aq]th argument: cannot parse as number: -infinityx [tty], line 1: + -infinityx 1 \f[R] .fi .SS Predicates .PP Predicates are functions that write exactly one output that is either \f[C]$true\f[R] or \f[C]$false\f[R]. They are described like \[lq]Determine \&...\[rq] or \[lq]Test \&...\[rq]. See \f[C]is\f[R] for one example. .SS \[lq]Do Not Use\[rq] Functions and Variables .PP The name of some variables and functions have a leading \f[C]-\f[R]. 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.) .PP Those functions and variables are documented near the end of the respective sections. Their known problem is also discussed. .SH Variables .SS $_ .PP A blackhole variable. .PP Values assigned to it will be discarded. Referencing it always results in $nil. .SS $after-chdir .PP 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 \f[C]$before-chdir\f[R]: .IP .nf \f[C] \[ti]> before-chdir = [[dir]{ echo \[dq]Going to change to \[dq]$dir\[dq], pwd is \[dq]$pwd }] \[ti]> after-chdir = [[dir]{ echo \[dq]Changed to \[dq]$dir\[dq], pwd is \[dq]$pwd }] \[ti]> 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> \f[R] .fi .PP \[at]cf before-chdir .SS $args .PP A list containing command-line arguments. Analogous to \f[C]argv\f[R] in some other languages. Examples: .IP .nf \f[C] \[ti]> echo \[aq]put $args\[aq] > args.elv \[ti]> elvish args.elv foo -bar \[u25B6] [foo -bar] \[ti]> elvish -c \[aq]put $args\[aq] foo -bar \[u25B6] [foo -bar] \f[R] .fi .PP As demonstrated above, this variable does not contain the name of the script used to invoke it. For that information, use the \f[C]src\f[R] command. .PP \[at]cf src .SS $before-chdir .PP A list of functions to run before changing directory. These functions are always called with the new working directory. .PP \[at]cf after-chdir .SS $false .PP The boolean false value. .SS $nil .PP A special value useful for representing the lack of values. .SS $notify-bg-job-success .PP Whether to notify success of background jobs, defaulting to \f[C]$true\f[R]. .PP Failures of background jobs are always notified. .SS $num-bg-jobs .PP Number of background jobs. .SS $ok .PP The special value used by \f[C]?()\f[R] to signal absence of exceptions. .SS $paths .PP A list of search paths, kept in sync with \f[C]$E:PATH\f[R]. It is easier to use than \f[C]$E:PATH\f[R]. .SS $pid .PP The process ID of the current Elvish process. .SS $pwd .PP The present working directory. Setting this variable has the same effect as \f[C]cd\f[R]. This variable is most useful in a temporary assignment. .PP Example: .IP .nf \f[C] ## Updates all git repositories for x [*/] { pwd=$x { if ?(test -d .git) { git pull } } } \f[R] .fi .PP Etymology: the \f[C]pwd\f[R] command. .PP \[at]cf cd .SS $true .PP The boolean true value. .SS $value-out-indicator .PP A string put before value outputs (such as those of of \f[C]put\f[R]). Defaults to \f[C]\[aq]\[u25B6] \[aq]\f[R]. Example: .IP .nf \f[C] \[ti]> put lorem ipsum \[u25B6] lorem \[u25B6] ipsum \[ti]> value-out-indicator = \[aq]val> \[aq] \[ti]> put lorem ipsum val> lorem val> ipsum \f[R] .fi .PP Note that you almost always want some trailing whitespace for readability. .SH Functions .SS % .IP .nf \f[C] % $dividend $divisor \f[R] .fi .PP Output the remainder after dividing \f[C]$dividend\f[R] by \f[C]$divisor\f[R]. Both must be integers. Example: .IP .nf \f[C] \[ti]> % 23 7 \[u25B6] 2 \f[R] .fi .SS < <= == != > >= .IP .nf \f[C] < $number... # less <= $number... # less or equal == $number... # equal != $number... # not equal > $number... # greater >= $number... # greater or equal \f[R] .fi .PP Number comparisons. All of them accept an arbitrary number of arguments: .IP "1." 3 When given fewer than two arguments, all output \f[C]$true\f[R]. .IP "2." 3 When given two arguments, output whether the two arguments satisfy the named relationship. .IP "3." 3 When given more than two arguments, output whether every adjacent pair of numbers satisfy the named relationship. .PP Examples: .IP .nf \f[C] \[ti]> == 3 3.0 \[u25B6] $true \[ti]> < 3 4 \[u25B6] $true \[ti]> < 3 4 10 \[u25B6] $true \[ti]> < 6 9 1 \[u25B6] $false \f[R] .fi .PP As a consequence of rule 3, the \f[C]!=\f[R] command outputs \f[C]$true\f[R] as long as any \f[I]adjacent\f[R] pair of numbers are not equal, even if some numbers that are not adjacent are equal: .IP .nf \f[C] \[ti]> != 5 5 4 \[u25B6] $false \[ti]> != 5 6 5 \[u25B6] $true \f[R] .fi .SS s >=s .IP .nf \f[C] s $string... # greater >=s $string... # greater or equal \f[R] .fi .PP String comparisons. They behave similarly to their number counterparts when given multiple arguments. Examples: .IP .nf \f[C] \[ti]> >s lorem ipsum \[u25B6] $true \[ti]> ==s 1 1.0 \[u25B6] $false \[ti]> >s 8 12 \[u25B6] $true \f[R] .fi .SS + - * / .IP .nf \f[C] + $summand... - $minuend $subtrahend... * $factor... / $dividend $divisor... \f[R] .fi .PP Basic arithmetic operations of adding, subtraction, multiplication and division respectively. .PP All of them can take multiple arguments: .IP .nf \f[C] \[ti]> + 2 5 7 # 2 + 5 + 7 \[u25B6] 14 \[ti]> - 2 5 7 # 2 - 5 - 7 \[u25B6] -10 \[ti]> * 2 5 7 # 2 * 5 * 7 \[u25B6] 70 \[ti]> / 2 5 7 # 2 / 5 / 7 \[u25B6] 0.05714285714285715 \f[R] .fi .PP When given one element, they all output their sole argument (given that it is a valid number). When given no argument, .IP \[bu] 2 \f[C]+\f[R] outputs 0, and \f[C]*\f[R] outputs 1. You can think that they both have a \[lq]hidden\[rq] argument of 0 or 1, which does not alter their behaviors (in mathematical terms, 0 and 1 are identity elements (https://en.wikipedia.org/wiki/Identity_element) of addition and multiplication, respectively). .IP \[bu] 2 \f[C]-\f[R] throws an exception. .IP \[bu] 2 \f[C]/\f[R] becomes a synonym for \f[C]cd /\f[R], due to the implicit cd feature. (The implicit cd feature will probably change to avoid this oddity). .SS all .IP .nf \f[C] all $input-list? \f[R] .fi .PP Passes inputs to the output as is. Byte inputs into values, one per line. .PP This is an identity function for commands with value outputs: \f[C]a | all\f[R] is equivalent to \f[C]a\f[R] if it only outputs values. .PP This function is useful for turning inputs into arguments, like: .IP .nf \f[C] \[ti]> use str \[ti]> put \[aq]lorem,ipsum\[aq] | str:split , (all) \[u25B6] lorem \[u25B6] ipsum \f[R] .fi .PP Or capturing all inputs in a variable: .IP .nf \f[C] \[ti]> x = [(all)] foo bar (Press \[ha]D) \[ti]> put $x \[u25B6] [foo bar] \f[R] .fi .PP When given a list, it outputs all elements of the list: .IP .nf \f[C] \[ti]> all [foo bar] \[u25B6] foo \[u25B6] bar \f[R] .fi .PP \[at]cf one .SS assoc .IP .nf \f[C] assoc $container $k $v \f[R] .fi .PP Output a slightly modified version of \f[C]$container\f[R], such that its value at \f[C]$k\f[R] is \f[C]$v\f[R]. Applies to both lists and to maps. .PP When \f[C]$container\f[R] is a list, \f[C]$k\f[R] may be a negative index. However, slice is not yet supported. .IP .nf \f[C] \[ti]> assoc [foo bar quux] 0 lorem \[u25B6] [lorem bar quux] \[ti]> assoc [foo bar quux] -1 ipsum \[u25B6] [foo bar ipsum] \[ti]> assoc [&k=v] k v2 \[u25B6] [&k=v2] \[ti]> assoc [&k=v] k2 v2 \[u25B6] [&k2=v2 &k=v] \f[R] .fi .PP Etymology: Clojure (https://clojuredocs.org/clojure.core/assoc). .PP \[at]cf dissoc .SS base .IP .nf \f[C] base $base $number... \f[R] .fi .PP Outputs a string for each \f[C]$number\f[R] written in \f[C]$base\f[R]. The \f[C]$base\f[R] must be between 2 and 36, inclusive. Examples: .IP .nf \f[C] \[ti]> base 2 1 3 4 16 255 \[u25B6] 1 \[u25B6] 11 \[u25B6] 100 \[u25B6] 10000 \[u25B6] 11111111 \[ti]> base 16 1 3 4 16 255 \[u25B6] 1 \[u25B6] 3 \[u25B6] 4 \[u25B6] 10 \[u25B6] ff \f[R] .fi .SS bool .IP .nf \f[C] bool $value \f[R] .fi .PP Convert a value to boolean. In Elvish, only \f[C]$false\f[R] and errors are booleanly false. Everything else, including 0, empty strings and empty lists, is booleanly true: .IP .nf \f[C] \[ti]> bool $true \[u25B6] $true \[ti]> bool $false \[u25B6] $false \[ti]> bool $ok \[u25B6] $true \[ti]> bool ?(fail haha) \[u25B6] $false \[ti]> bool \[aq]\[aq] \[u25B6] $true \[ti]> bool [] \[u25B6] $true \[ti]> bool abc \[u25B6] $true \f[R] .fi .PP \[at]cf not .SS break .PP Raises the special \[lq]break\[rq] exception. When raised inside a loop it is captured and causes the loop to terminate. .PP Because \f[C]break\f[R] raises an exception it can be caught by a \f[C]try\f[R] block. If not caught, either implicitly by a loop or explicitly, it causes a failure like any other uncaught exception. .PP See the discussion about flow commands and exceptions .PP \f[B]Note\f[R]: You can create a \f[C]break\f[R] function and it will shadow the builtin command. If you do so you should explicitly invoke the builtin. For example: .IP .nf \f[C] > fn break []{ put \[aq]break\[aq]; builtin:break; put \[aq]should not appear\[aq] } > for x [a b c] { put $x; break; put \[aq]unexpected\[aq] } \[u25B6] a \[u25B6] break \f[R] .fi .SS cd .IP .nf \f[C] cd $dirname \f[R] .fi .PP 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 \f[C]peach\f[R]. .PP Note that Elvish\[cq]s \f[C]cd\f[R] does not support \f[C]cd -\f[R]. .PP \[at]cf pwd .SS chr .IP .nf \f[C] chr $number... \f[R] .fi .PP This function is deprecated; use str:from-codepoints instead. .PP Outputs a string consisting of the given Unicode codepoints. Example: .IP .nf \f[C] \[ti]> chr 0x61 \[u25B6] a \[ti]> chr 0x4f60 0x597d \[u25B6] \[u4F60]\[u597D] \f[R] .fi .PP Etymology: Python (https://docs.python.org/3/library/functions.html#chr). .PP \[at]cf ord .SS constantly .IP .nf \f[C] constantly $value... \f[R] .fi .PP Output a function that takes no arguments and outputs \f[C]$value\f[R]s when called. Examples: .IP .nf \f[C] \[ti]> f=(constantly lorem ipsum) \[ti]> $f \[u25B6] lorem \[u25B6] ipsum \f[R] .fi .PP The above example is actually equivalent to simply \f[C]f = []{ put lorem ipsum }\f[R]; it is most useful when the argument is \f[B]not\f[R] a literal value, e.g. .IP .nf \f[C] \[ti]> f = (constantly (uname)) \[ti]> $f \[u25B6] Darwin \[ti]> $f \[u25B6] Darwin \f[R] .fi .PP The above code only calls \f[C]uname\f[R] once, while if you do \f[C]f = []{ put (uname) }\f[R], every time you invoke \f[C]$f\f[R], \f[C]uname\f[R] will be called. .PP Etymology: Clojure (https://clojuredocs.org/clojure.core/constantly). .SS continue .PP Raises the special \[lq]continue\[rq] exception. When raised inside a loop it is captured and causes the loop to begin its next iteration. .PP Because \f[C]continue\f[R] raises an exception it can be caught by a \f[C]try\f[R] block. If not caught, either implicitly by a loop or explicitly, it causes a failure like any other uncaught exception. .PP See the discussion about flow commands and exceptions .PP \f[B]Note\f[R]: You can create a \f[C]continue\f[R] function and it will shadow the builtin command. If you do so you should explicitly invoke the builtin. For example: .IP .nf \f[C] > fn break []{ put \[aq]continue\[aq]; builtin:continue; put \[aq]should not appear\[aq] } > for x [a b c] { put $x; continue; put \[aq]unexpected\[aq] } \[u25B6] a \[u25B6] continue \[u25B6] b \[u25B6] continue \[u25B6] c \[u25B6] continue \f[R] .fi .SS count .IP .nf \f[C] count $input-list? \f[R] .fi .PP Count the number of inputs. .PP Examples: .IP .nf \f[C] \[ti]> count lorem # count bytes in a string \[u25B6] 5 \[ti]> count [lorem ipsum] \[u25B6] 2 \[ti]> range 100 | count \[u25B6] 100 \[ti]> seq 100 | count \[u25B6] 100 \f[R] .fi .SS deprecate .IP .nf \f[C] deprecate $msg \f[R] .fi .PP 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. .IP .nf \f[C] \[ti]> deprecate msg deprecation: msg \[ti]> fn f { deprecate msg } \[ti]> f deprecation: msg [tty 19], line 1: f \[ti]> exec \[ti]> deprecate msg deprecation: msg \[ti]> fn f { deprecate msg } \[ti]> f deprecation: msg [tty 3], line 1: f \[ti]> f # a different call site; shows deprecate message deprecation: msg [tty 4], line 1: f \[ti]> fn g { f } \[ti]> g deprecation: msg [tty 5], line 1: fn g { f } \[ti]> g # same call site, no more deprecation message \f[R] .fi .SS dir-history .IP .nf \f[C] dir-history \f[R] .fi .PP Return a list containing the directory history. Each element is a map with two keys: \f[C]path\f[R] and \f[C]score\f[R]. The list is sorted by descending score. .PP Example: .IP .nf \f[C] \[ti]> dir-history | take 1 \[u25B6] [&path=/Users/foo/.elvish &score=96.79928] \f[R] .fi .SS dissoc .IP .nf \f[C] dissoc $map $k \f[R] .fi .PP Output a slightly modified version of \f[C]$map\f[R], with the key \f[C]$k\f[R] removed. If \f[C]$map\f[R] does not contain \f[C]$k\f[R] as a key, the same map is returned. .IP .nf \f[C] \[ti]> dissoc [&foo=bar &lorem=ipsum] foo \[u25B6] [&lorem=ipsum] \[ti]> dissoc [&foo=bar &lorem=ipsum] k \[u25B6] [&lorem=ipsum &foo=bar] \f[R] .fi .PP \[at]cf assoc .SS drop .IP .nf \f[C] drop $n $input-list? \f[R] .fi .PP Drop the first \f[C]$n\f[R] elements of the input. If \f[C]$n\f[R] is larger than the number of input elements, the entire input is dropped. .PP Example: .IP .nf \f[C] \[ti]> drop 2 [a b c d e] \[u25B6] c \[u25B6] d \[u25B6] e \[ti]> use str \[ti]> str:split \[aq] \[aq] \[aq]how are you?\[aq] | drop 1 \[u25B6] are \[u25B6] \[aq]you?\[aq] \[ti]> range 2 | drop 10 \f[R] .fi .PP Etymology: Haskell. .PP \[at]cf take .SS each .IP .nf \f[C] each $f $input-list? \f[R] .fi .PP Call \f[C]$f\f[R] on all inputs. Examples: .IP .nf \f[C] \[ti]> range 5 8 | each [x]{ \[ha] $x 2 } \[u25B6] 25 \[u25B6] 36 \[u25B6] 49 \[ti]> each [x]{ put $x[:3] } [lorem ipsum] \[u25B6] lor \[u25B6] ips \f[R] .fi .PP \[at]cf peach .PP Etymology: Various languages, as \f[C]for each\f[R]. Happens to have the same name as the iteration construct of Factor (http://docs.factorcode.org/content/word-each,sequences.html). .SS eawk .IP .nf \f[C] eawk $f $input-list? \f[R] .fi .PP For each input, call \f[C]$f\f[R] with the input followed by all its fields. The function may call \f[C]break\f[R] and \f[C]continue\f[R]. .PP It should behave the same as the following functions: .IP .nf \f[C] fn eawk [f \[at]rest]{ each [line]{ \[at]fields = (re:split \[aq][ \[rs]t]+\[aq] (re:replace \[aq]\[ha][ \[rs]t]+|[ \[rs]t]+$\[aq] \[aq]\[aq] $line)) $f $line $\[at]fields } $\[at]rest } \f[R] .fi .PP This command allows you to write code very similar to \f[C]awk\f[R] scripts using anonymous functions. Example: .IP .nf \f[C] \[ti]> echo \[aq] lorem ipsum 1 2\[aq] | awk \[aq]{ print $1 }\[aq] lorem 1 \[ti]> echo \[aq] lorem ipsum 1 2\[aq] | eawk [line a b]{ put $a } \[u25B6] lorem \[u25B6] 1 \f[R] .fi .SS echo .IP .nf \f[C] echo &sep=\[aq] \[aq] $value... \f[R] .fi .PP Print all arguments, joined by the \f[C]sep\f[R] option, and followed by a newline. .PP Examples: .IP .nf \f[C] \[ti]> echo Hello elvish Hello elvish \[ti]> echo \[dq]Hello elvish\[dq] Hello elvish \[ti]> echo &sep=, lorem ipsum lorem,ipsum \f[R] .fi .PP Notes: The \f[C]echo\f[R] builtin does not treat \f[C]-e\f[R] or \f[C]-n\f[R] specially. For instance, \f[C]echo -n\f[R] just prints \f[C]-n\f[R]. Use double-quoted strings to print special characters, and \f[C]print\f[R] to suppress the trailing newline. .PP \[at]cf print .PP Etymology: Bourne sh. .SS eq .IP .nf \f[C] eq $values... \f[R] .fi .PP Determine whether all \f[C]$value\f[R]s are structurally equivalent. Writes \f[C]$true\f[R] when given no or one argument. .IP .nf \f[C] \[ti]> eq a a \[u25B6] $true \[ti]> eq [a] [a] \[u25B6] $true \[ti]> eq [&k=v] [&k=v] \[u25B6] $true \[ti]> eq a [b] \[u25B6] $false \f[R] .fi .PP \[at]cf is not-eq .PP Etymology: Perl (https://perldoc.perl.org/perlop.html#Equality-Operators). .SS eval .IP .nf \f[C] eval $code &ns=$nil &on-end=$nil \f[R] .fi .PP Evaluates \f[C]$code\f[R], which should be a string. The evaluation happens in a new, restricted namespace, whose initial set of variables can be specified by the \f[C]&ns\f[R] option. After evaluation completes, the new namespace is passed to the callback specified by \f[C]&on-end\f[R] if it is not nil. .PP The namespace specified by \f[C]&ns\f[R] is never modified; it will not be affected by the creation or deletion of variables by \f[C]$code\f[R]. However, the values of the variables may be mutated by \f[C]$code\f[R]. .PP If the \f[C]&ns\f[R] option is \f[C]$nil\f[R] (the default), a temporary namespace built by amalgamating the local and upvalue scopes of the caller is used. .PP If \f[C]$code\f[R] fails to parse or compile, the parse error or compilation error is raised as an exception. .PP Basic examples that do not modify the namespace or any variable: .IP .nf \f[C] \[ti]> eval \[aq]put x\[aq] \[u25B6] x \[ti]> x = foo \[ti]> eval \[aq]put $x\[aq] \[u25B6] foo \[ti]> ns = (ns [&x=bar]) \[ti]> eval &ns=$ns \[aq]put $x\[aq] \[u25B6] bar \f[R] .fi .PP Examples that modify existing variables: .IP .nf \f[C] \[ti]> y = foo \[ti]> eval \[aq]y = bar\[aq] \[ti]> put $y \[u25B6] bar \f[R] .fi .PP Examples that creates new variables and uses the callback to access it: .IP .nf \f[C] \[ti]> eval \[aq]z = lorem\[aq] \[ti]> put $z compilation error: variable $z not found [ttz 2], line 1: put $z \[ti]> saved-ns = $nil \[ti]> eval &on-end=[ns]{ saved-ns = $ns } \[aq]z = lorem\[aq] \[ti]> put $saved-ns[z] \[u25B6] lorem \f[R] .fi .SS exec .IP .nf \f[C] exec $command? \f[R] .fi .PP Replace the Elvish process with an external \f[C]$command\f[R], defaulting to \f[C]elvish\f[R]. This decrements \f[C]$E:SHLVL\f[R] before starting the new process. .PP This command always raises an exception on Windows with the message \[lq]not supported on Windows\[rq]. .SS exit .IP .nf \f[C] exit $status? \f[R] .fi .PP Exit the Elvish process with \f[C]$status\f[R] (defaulting to 0). .SS external .IP .nf \f[C] external $program \f[R] .fi .PP Construct a callable value for the external program \f[C]$program\f[R]. Example: .IP .nf \f[C] \[ti]> x = (external man) \[ti]> $x ls # opens the manpage for ls \f[R] .fi .PP \[at]cf has-external search-external .SS fail .IP .nf \f[C] fail $v \f[R] .fi .PP Throws an exception; \f[C]$v\f[R] may be any type. If \f[C]$v\f[R] is already an exception, \f[C]fail\f[R] rethrows it. .IP .nf \f[C] \[ti]> fail bad Exception: bad [tty 9], line 1: fail bad \[ti]> put ?(fail bad) \[u25B6] ?(fail bad) \[ti]> fn f { fail bad } \[ti]> fail ?(f) Exception: bad Traceback: [tty 7], line 1: fn f { fail bad } [tty 8], line 1: fail ?(f) \f[R] .fi .SS fclose .IP .nf \f[C] fclose $file \f[R] .fi .PP Close a file opened with \f[C]fopen\f[R]. .PP \[at]cf fopen .SS float64 .IP .nf \f[C] float64 123 float64 NaN float64 Inf \f[R] .fi .PP Explicitly convert a string to a \f[C]float64\f[R] data type. .PP This command is seldom needed since commands that operate on numbers will convert a string to a number. See the discussion of the number data type. .SS fopen .IP .nf \f[C] fopen $filename \f[R] .fi .PP Open a file. Currently, \f[C]fopen\f[R] only supports opening a file for reading. File must be closed with \f[C]fclose\f[R] explicitly. Example: .IP .nf \f[C] \[ti]> cat a.txt This is a file. \[ti]> f = (fopen a.txt) \[ti]> cat < $f This is a file. \[ti]> fclose $f \f[R] .fi .PP \[at]cf fclose .SS from-json .IP .nf \f[C] from-json \f[R] .fi .PP Takes bytes stdin, parses it as JSON and puts the result on structured stdout. The input can contain multiple JSONs, which can, but do not have to, be separated with whitespaces. .PP Examples: .IP .nf \f[C] \[ti]> echo \[aq]\[dq]a\[dq]\[aq] | from-json \[u25B6] a \[ti]> echo \[aq][\[dq]lorem\[dq], \[dq]ipsum\[dq]]\[aq] | from-json \[u25B6] [lorem ipsum] \[ti]> echo \[aq]{\[dq]lorem\[dq]: \[dq]ipsum\[dq]}\[aq] | from-json \[u25B6] [&lorem=ipsum] \[ti]> # multiple JSONs running together echo \[aq]\[dq]a\[dq]\[dq]b\[dq][\[dq]x\[dq]]\[aq] | from-json \[u25B6] a \[u25B6] b \[u25B6] [x] \[ti]> # multiple JSONs separated by newlines echo \[aq]\[dq]a\[dq] {\[dq]k\[dq]: \[dq]v\[dq]}\[aq] | from-json \[u25B6] a \[u25B6] [&k=v] \f[R] .fi .PP \[at]cf to-json .SS from-lines .IP .nf \f[C] from-lines \f[R] .fi .PP Splits byte input into lines, and writes them to the value output. Value input is ignored. .IP .nf \f[C] \[ti]> { echo a; echo b } | from-lines \[u25B6] a \[u25B6] b \[ti]> { echo a; put b } | from-lines \[u25B6] a \f[R] .fi .PP \[at]cf to-lines .SS -gc .IP .nf \f[C] -gc \f[R] .fi .PP Force the Go garbage collector to run. .PP This is only useful for debug purposes. .SS get-env .IP .nf \f[C] get-env $name \f[R] .fi .PP Gets the value of an environment variable. Throws an exception if the environment variable does not exist. Examples: .IP .nf \f[C] \[ti]> get-env LANG \[u25B6] zh_CN.UTF-8 \[ti]> get-env NO_SUCH_ENV Exception: non-existent environment variable [tty], line 1: get-env NO_SUCH_ENV \f[R] .fi .PP \[at]cf has-env set-env unset-env .SS has-env .IP .nf \f[C] has-env $name \f[R] .fi .PP Test whether an environment variable exists. Examples: .IP .nf \f[C] \[ti]> has-env PATH \[u25B6] $true \[ti]> has-env NO_SUCH_ENV \[u25B6] $false \f[R] .fi .PP \[at]cf get-env set-env unset-env .SS has-external .IP .nf \f[C] has-external $command \f[R] .fi .PP Test whether \f[C]$command\f[R] names a valid external command. Examples (your output might differ): .IP .nf \f[C] \[ti]> has-external cat \[u25B6] $true \[ti]> has-external lalala \[u25B6] $false \f[R] .fi .PP \[at]cf external search-external .SS has-key .IP .nf \f[C] has-key $container $key \f[R] .fi .PP Determine whether \f[C]$key\f[R] is a key in \f[C]$container\f[R]. A key could be a map key or an index on a list or string. This includes a range of indexes. .PP Examples, maps: .IP .nf \f[C] \[ti]> has-key [&k1=v1 &k2=v2] k1 \[u25B6] $true \[ti]> has-key [&k1=v1 &k2=v2] v1 \[u25B6] $false \f[R] .fi .PP Examples, lists: .IP .nf \f[C] \[ti]> has-key [v1 v2] 0 \[u25B6] $true \[ti]> has-key [v1 v2] 1 \[u25B6] $true \[ti]> has-key [v1 v2] 2 \[u25B6] $false \[ti]> has-key [v1 v2] 0:2 \[u25B6] $true \[ti]> has-key [v1 v2] 0:3 \[u25B6] $false \f[R] .fi .PP Examples, strings: .IP .nf \f[C] \[ti]> has-key ab 0 \[u25B6] $true \[ti]> has-key ab 1 \[u25B6] $true \[ti]> has-key ab 2 \[u25B6] $false \[ti]> has-key ab 0:2 \[u25B6] $true \[ti]> has-key ab 0:3 \[u25B6] $false \f[R] .fi .SS has-prefix .IP .nf \f[C] has-prefix $string $prefix \f[R] .fi .PP Determine whether \f[C]$prefix\f[R] is a prefix of \f[C]$string\f[R]. Examples: .IP .nf \f[C] \[ti]> has-prefix lorem,ipsum lor \[u25B6] $true \[ti]> has-prefix lorem,ipsum foo \[u25B6] $false \f[R] .fi .PP This function is deprecated; use str:has-prefix instead. .SS has-suffix .IP .nf \f[C] has-suffix $string $suffix \f[R] .fi .PP Determine whether \f[C]$suffix\f[R] is a suffix of \f[C]$string\f[R]. Examples: .IP .nf \f[C] \[ti]> has-suffix a.html .txt \[u25B6] $false \[ti]> has-suffix a.html .html \[u25B6] $true \f[R] .fi .PP This function is deprecated; use str:has-suffix instead. .SS has-value .IP .nf \f[C] has-value $container $value \f[R] .fi .PP Determine whether \f[C]$value\f[R] is a value in \f[C]$container\f[R]. .PP Examples, maps: .IP .nf \f[C] \[ti]> has-value [&k1=v1 &k2=v2] v1 \[u25B6] $true \[ti]> has-value [&k1=v1 &k2=v2] k1 \[u25B6] $false \f[R] .fi .PP Examples, lists: .IP .nf \f[C] \[ti]> has-value [v1 v2] v1 \[u25B6] $true \[ti]> has-value [v1 v2] k1 \[u25B6] $false \f[R] .fi .PP Examples, strings: .IP .nf \f[C] \[ti]> has-value ab b \[u25B6] $true \[ti]> has-value ab c \[u25B6] $false \f[R] .fi .SS -ifaddrs .IP .nf \f[C] -ifaddrs \f[R] .fi .PP Output all IP addresses of the current host. .PP This should be part of a networking module instead of the builtin module. .SS is .IP .nf \f[C] is $values... \f[R] .fi .PP Determine whether all \f[C]$value\f[R]s have the same identity. Writes \f[C]$true\f[R] when given no or one argument. .PP The definition of identity is subject to change. Do not rely on its behavior. .IP .nf \f[C] \[ti]> is a a \[u25B6] $true \[ti]> is a b \[u25B6] $false \[ti]> is [] [] \[u25B6] $true \[ti]> is [a] [a] \[u25B6] $false \f[R] .fi .PP \[at]cf eq .PP Etymology: Python (https://docs.python.org/3/reference/expressions.html#is). .SS keys .IP .nf \f[C] keys $map \f[R] .fi .PP Put all keys of \f[C]$map\f[R] on the structured stdout. .PP Example: .IP .nf \f[C] \[ti]> keys [&a=foo &b=bar &c=baz] \[u25B6] a \[u25B6] c \[u25B6] b \f[R] .fi .PP Note that there is no guaranteed order for the keys of a map. .SS kind-of .IP .nf \f[C] kind-of $value... \f[R] .fi .PP Output the kinds of \f[C]$value\f[R]s. Example: .IP .nf \f[C] \[ti]> kind-of lorem [] [&] \[u25B6] string \[u25B6] list \[u25B6] map \f[R] .fi .PP The terminology and definition of \[lq]kind\[rq] is subject to change. .SS -log .IP .nf \f[C] -log $filename \f[R] .fi .PP Direct internal debug logs to the named file. .PP This is only useful for debug purposes. .SS make-map .IP .nf \f[C] make-map $input? \f[R] .fi .PP 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. .PP If the same key appears multiple times, the last value is used. .PP Examples: .IP .nf \f[C] \[ti]> make-map [[k v]] \[u25B6] [&k=v] \[ti]> make-map [[k v1] [k v2]] \[u25B6] [&k=v2] \[ti]> put [k1 v1] [k2 v2] | make-map \[u25B6] [&k1=v1 &k2=v2] \[ti]> put aA bB | make-map \[u25B6] [&a=A &b=B] \f[R] .fi .SS nop .IP .nf \f[C] nop &any-opt= $value... \f[R] .fi .PP Accepts arbitrary arguments and options and does exactly nothing. .PP Examples: .IP .nf \f[C] \[ti]> nop \[ti]> nop a b c \[ti]> nop &k=v \f[R] .fi .PP Etymology: Various languages, in particular NOP in assembly languages (https://en.wikipedia.org/wiki/NOP). .SS not .IP .nf \f[C] not $value \f[R] .fi .PP Boolean negation. Examples: .IP .nf \f[C] \[ti]> not $true \[u25B6] $false \[ti]> not $false \[u25B6] $true \[ti]> not $ok \[u25B6] $false \[ti]> not ?(fail error) \[u25B6] $true \f[R] .fi .PP \f[B]Note\f[R]: The related logical commands \f[C]and\f[R] and \f[C]or\f[R] are implemented as special commands instead, since they do not always evaluate all their arguments. The \f[C]not\f[R] command always evaluates its only argument, and is thus a normal command. .PP \[at]cf bool .SS not-eq .IP .nf \f[C] not-eq $values... \f[R] .fi .PP Determines whether every adjacent pair of \f[C]$value\f[R]s are not equal. Note that this does not imply that \f[C]$value\f[R]s are all distinct. Examples: .IP .nf \f[C] \[ti]> not-eq 1 2 3 \[u25B6] $true \[ti]> not-eq 1 2 1 \[u25B6] $true \[ti]> not-eq 1 1 2 \[u25B6] $false \f[R] .fi .PP \[at]cf eq .SS ns .IP .nf \f[C] ns $map \f[R] .fi .PP Constructs a namespace from \f[C]$map\f[R], using the keys as variable names and the values as their values. Examples: .IP .nf \f[C] \[ti]> n = (ns [&name=value]) \[ti]> put $n[name] \[u25B6] value \[ti]> n: = (ns [&name=value]) \[ti]> put $n:name \[u25B6] value \f[R] .fi .SS one .IP .nf \f[C] one $input-list? \f[R] .fi .PP Passes inputs to outputs, if there is only a single one. Otherwise raises an exception. .PP This function can be used in a similar way to \f[C]all\f[R], but is a better choice when you expect that there is exactly one output: .PP \[at]cf all .SS only-bytes .IP .nf \f[C] only-bytes \f[R] .fi .PP Passes byte input to output, and discards value inputs. .PP Example: .IP .nf \f[C] \[ti]> { put value; echo bytes } | only-bytes bytes \f[R] .fi .SS only-values .IP .nf \f[C] only-values \f[R] .fi .PP Passes value input to output, and discards byte inputs. .PP Example: .IP .nf \f[C] \[ti]> { put value; echo bytes } | only-values \[u25B6] value \f[R] .fi .SS ord .IP .nf \f[C] ord $string \f[R] .fi .PP This function is deprecated; use str:to-codepoints instead. .PP Output value of each codepoint in \f[C]$string\f[R], in hexadecimal. Examples: .IP .nf \f[C] \[ti]> ord a \[u25B6] 0x61 \[ti]> ord \[u4F60]\[u597D] \[u25B6] 0x4f60 \[u25B6] 0x597d \f[R] .fi .PP The output format is subject to change. .PP Etymology: Python (https://docs.python.org/3/library/functions.html#ord). .PP \[at]cf chr .SS order .IP .nf \f[C] order &reverse=$false $less-than=$nil $inputs? \f[R] .fi .PP Outputs the input values sorted in ascending order. The sort is guaranteed to be stable (https://en.wikipedia.org/wiki/Sorting_algorithm#Stability). .PP The \f[C]&reverse\f[R] option, if true, reverses the order of output. .PP The \f[C]&less-than\f[R] option, 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, \f[C]order\f[R] rethrows the exception without outputting any value. .PP If \f[C]&less-than\f[R] has value \f[C]$nil\f[R] (the default if not set), the following comparison algorithm is used: .IP \[bu] 2 Numbers are compared numerically. For the sake of sorting, \f[C]NaN\f[R] is treated as smaller than all other numbers. .IP \[bu] 2 Strings are compared lexicographically by bytes, which is equivalent to comparing by codepoints under UTF-8. .IP \[bu] 2 Lists are compared lexicographically by elements, if the elements at the same positions are comparable. .PP If the ordering between two elements are not defined by the conditions above, no value is outputted and an exception is thrown. .PP Examples: .IP .nf \f[C] \[ti]> put foo bar ipsum | order \[u25B6] bar \[u25B6] foo \[u25B6] ipsum \[ti]> order [(float64 10) (float64 1) (float64 5)] \[u25B6] (float64 1) \[u25B6] (float64 5) \[u25B6] (float64 10) \[ti]> order [[a b] [a] [b b] [a c]] \[u25B6] [a] \[u25B6] [a b] \[u25B6] [a c] \[u25B6] [b b] \[ti]> order &reverse [a c b] \[u25B6] c \[u25B6] b \[u25B6] a \[ti]> order &less-than=[a b]{ eq $a x } [l x o r x e x m] \[u25B6] x \[u25B6] x \[u25B6] x \[u25B6] l \[u25B6] o \[u25B6] r \[u25B6] e \[u25B6] m \f[R] .fi .PP Beware that strings that look like numbers are treated as strings, not numbers. To sort strings as numbers, use an explicit \f[C]&less-than\f[R] option: .IP .nf \f[C] \[ti]> order [5 1 10] \[u25B6] 1 \[u25B6] 10 \[u25B6] 5 \[ti]> order &less-than=[a b]{ < $a $b } [5 1 10] \[u25B6] 1 \[u25B6] 5 \[u25B6] 10 \f[R] .fi .SS path-* .IP .nf \f[C] path-abs $path path-base $path path-clean $path path-dir $path path-ext $path \f[R] .fi .PP See godoc of path/filepath (https://godoc.org/path/filepath). Go errors are turned into exceptions. .PP These functions are deprecated. Use the equivalent functions in the path: module. .SS peach .IP .nf \f[C] peach $f $input-list? \f[R] .fi .PP Call \f[C]$f\f[R] on all inputs, possibly in parallel. .PP Example (your output will differ): .IP .nf \f[C] \[ti]> range 1 7 | peach [x]{ + $x 10 } \[u25B6] 12 \[u25B6] 11 \[u25B6] 13 \[u25B6] 16 \[u25B6] 15 \[u25B6] 14 \f[R] .fi .PP 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 \f[C]run-parallel\f[R]. .PP \[at]cf each run-parallel .SS pipe .IP .nf \f[C] pipe \f[R] .fi .PP Create a new Unix pipe that can be used in redirections. .PP A pipe contains both the read FD and the write FD. When redirecting command input to a pipe with \f[C]<\f[R], the read FD is used. When redirecting command output to a pipe with \f[C]>\f[R], the write FD is used. It is not supported to redirect both input and output with \f[C]<>\f[R] to a pipe. .PP Pipes have an OS-dependent buffer, so writing to a pipe without an active reader does not necessarily block. Pipes \f[B]must\f[R] be explicitly closed with \f[C]prclose\f[R] and \f[C]pwclose\f[R]. .PP Putting values into pipes will cause those values to be discarded. .PP Examples (assuming the pipe has a large enough buffer): .IP .nf \f[C] \[ti]> p = (pipe) \[ti]> echo \[aq]lorem ipsum\[aq] > $p \[ti]> head -n1 < $p lorem ipsum \[ti]> put \[aq]lorem ipsum\[aq] > $p \[ti]> head -n1 < $p # blocks # $p should be closed with prclose and pwclose afterwards \f[R] .fi .PP \[at]cf prclose pwclose .SS pprint .IP .nf \f[C] pprint $value... \f[R] .fi .PP Pretty-print representations of Elvish values. Examples: .IP .nf \f[C] \[ti]> pprint [foo bar] [ foo bar ] \[ti]> pprint [&k1=v1 &k2=v2] [ &k2= v2 &k1= v1 ] \f[R] .fi .PP The output format is subject to change. .PP \[at]cf repr .SS prclose .IP .nf \f[C] prclose $pipe \f[R] .fi .PP Close the read end of a pipe. .PP \[at]cf pwclose pipe .SS print .IP .nf \f[C] print &sep=\[aq] \[aq] $value... \f[R] .fi .PP Like \f[C]echo\f[R], just without the newline. .PP \[at]cf echo .PP 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 \f[C]print\f[R]s do not print a trailing newline. .SS printf .IP .nf \f[C] printf $template $value... \f[R] .fi .PP Prints values to the byte stream according to a template. .PP Like \f[C]print\f[R], this command does not add an implicit newline; use an explicit \f[C]\[dq]\[rs]n\[dq]\f[R] in the formatting template instead. .PP See Go\[cq]s \f[C]fmt\f[R] (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. .PP Unlike Go, each formatting verb has a single associated internal type, and accepts any argument that can reasonably be converted to that type: .IP \[bu] 2 The verbs \f[C]%s\f[R], \f[C]%q\f[R] and \f[C]%v\f[R] convert the corresponding argument to a string in different ways: .RS 2 .IP \[bu] 2 \f[C]%s\f[R] uses to-string to convert a value to string. .IP \[bu] 2 \f[C]%q\f[R] uses repr to convert a value to string. .IP \[bu] 2 \f[C]%v\f[R] is equivalent to \f[C]%s\f[R], and \f[C]%#v\f[R] is equivalent to \f[C]%q\f[R]. .RE .IP \[bu] 2 The verb \f[C]%t\f[R] first convert the corresponding argument to a boolean using bool, and then uses its Go counterpart to format the boolean. .IP \[bu] 2 The verbs \f[C]%b\f[R], \f[C]%c\f[R], \f[C]%d\f[R], \f[C]%o\f[R], \f[C]%O\f[R], \f[C]%x\f[R], \f[C]%X\f[R] and \f[C]%U\f[R] first convert the corresponding argument to an integer using an internal algorithm, and use their Go counterparts to format the integer. .IP \[bu] 2 The verbs \f[C]%e\f[R], \f[C]%E\f[R], \f[C]%f\f[R], \f[C]%F\f[R], \f[C]%g\f[R] and \f[C]%G\f[R] first convert the corresponding argument to a floating-point number using float64, and then use their Go counterparts to format the number. .PP The special verb \f[C]%%\f[R] prints a literal \f[C]%\f[R] and consumes no argument. .PP Verbs not documented above are not supported. .PP Examples: .IP .nf \f[C] \[ti]> printf \[dq]%10s %.2f\[rs]n\[dq] Pi $math:pi Pi 3.14 \[ti]> printf \[dq]%-10s %.2f %s\[rs]n\[dq] Pi $math:pi $math:pi Pi 3.14 3.141592653589793 \[ti]> printf \[dq]%d\[rs]n\[dq] 0b11100111 231 \[ti]> printf \[dq]%08b\[rs]n\[dq] 231 11100111 \[ti]> printf \[dq]list is: %q\[rs]n\[dq] [foo bar \[aq]foo bar\[aq]] list is: [foo bar \[aq]foo bar\[aq]] \f[R] .fi .PP \f[B]Note\f[R]: Compared to the POSIX \f[C]printf\f[R] command (https://pubs.opengroup.org/onlinepubs/007908799/xcu/printf.html) found in other shells, there are 3 key differences: .IP \[bu] 2 The behavior of the formatting verbs are based on Go\[cq]s \f[C]fmt\f[R] (https://golang.org/pkg/fmt/) package instead of the POSIX specification. .IP \[bu] 2 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. .IP \[bu] 2 This command does not interpret escape sequences such as \f[C]\[rs]n\f[R]; just use double-quoted strings. .PP \[at]cf print echo pprint repr .SS put .IP .nf \f[C] put $value... \f[R] .fi .PP Takes arbitrary arguments and write them to the structured stdout. .PP Examples: .IP .nf \f[C] \[ti]> put a \[u25B6] a \[ti]> put lorem ipsum [a b] { ls } \[u25B6] lorem \[u25B6] ipsum \[u25B6] [a b] \[u25B6] \f[R] .fi .PP 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 \f[C]puts\f[R]. .SS pwclose .IP .nf \f[C] pwclose $pipe \f[R] .fi .PP Close the write end of a pipe. .PP \[at]cf prclose pipe .SS rand .IP .nf \f[C] rand \f[R] .fi .PP Output a pseudo-random number in the interval [0, 1). Example: .IP .nf \f[C] \[ti]> rand \[u25B6] 0.17843564133528436 \f[R] .fi .SS randint .IP .nf \f[C] randint $low $high \f[R] .fi .PP Output a pseudo-random integer in the interval [$low, $high). Example: .IP .nf \f[C] \[ti]> # Emulate dice randint 1 7 \[u25B6] 6 \f[R] .fi .SS range .IP .nf \f[C] range &step=1 $low? $high \f[R] .fi .PP Output \f[C]$low\f[R], \f[C]$low\f[R] + \f[C]$step\f[R], \&..., proceeding as long as smaller than \f[C]$high\f[R]. If not given, \f[C]$low\f[R] defaults to 0. .PP Examples: .IP .nf \f[C] \[ti]> range 4 \[u25B6] 0 \[u25B6] 1 \[u25B6] 2 \[u25B6] 3 \[ti]> range 1 6 &step=2 \[u25B6] 1 \[u25B6] 3 \[u25B6] 5 \f[R] .fi .PP Beware floating point oddities: .IP .nf \f[C] \[ti]> range 0 0.8 &step=.1 \[u25B6] 0 \[u25B6] 0.1 \[u25B6] 0.2 \[u25B6] 0.30000000000000004 \[u25B6] 0.4 \[u25B6] 0.5 \[u25B6] 0.6 \[u25B6] 0.7 \[u25B6] 0.7999999999999999 \f[R] .fi .PP Etymology: Python (https://docs.python.org/3/library/functions.html#func-range). .SS read-line .IP .nf \f[C] read-line \f[R] .fi .PP Reads a single line from byte input, and writes the line to the value output, stripping the line ending. A line can end with \f[C]\[dq]\[rs]r\[rs]n\[dq]\f[R], \f[C]\[dq]\[rs]n\[dq]\f[R], or end of file. Examples: .IP .nf \f[C] \[ti]> print line | read-line \[u25B6] line \[ti]> print \[dq]line\[rs]n\[dq] | read-line \[u25B6] line \[ti]> print \[dq]line\[rs]r\[rs]n\[dq] | read-line \[u25B6] line \[ti]> print \[dq]line-with-extra-cr\[rs]r\[rs]r\[rs]n\[dq] | read-line \[u25B6] \[dq]line-with-extra-cr\[rs]r\[dq] \f[R] .fi .SS read-upto .IP .nf \f[C] read-upto $delim \f[R] .fi .PP Reads byte input until \f[C]$delim\f[R] or end-of-file is encountered, and outputs the part of the input read as a string value. The output contains the trailing \f[C]$delim\f[R], unless \f[C]read-upto\f[R] terminated at end-of-file. .PP The \f[C]$delim\f[R] argument must be a single rune in the ASCII range. .PP Examples: .IP .nf \f[C] \[ti]> echo \[dq]a,b,c\[dq] | read-upto \[dq],\[dq] \[u25B6] \[aq]a,\[aq] \[ti]> echo \[dq]foo\[rs]nbar\[dq] | read-upto \[dq]\[rs]n\[dq] \[u25B6] \[dq]foo\[rs]n\[dq] \[ti]> echo \[dq]a.elv\[rs]x00b.elv\[dq] | read-upto \[dq]\[rs]x00\[dq] \[u25B6] \[dq]a.elv\[rs]x00\[dq] \[ti]> print \[dq]foobar\[dq] | read-upto \[dq]\[rs]n\[dq] \[u25B6] foobar \f[R] .fi .SS repeat .IP .nf \f[C] repeat $n $value \f[R] .fi .PP Output \f[C]$value\f[R] for \f[C]$n\f[R] times. Example: .IP .nf \f[C] \[ti]> repeat 0 lorem \[ti]> repeat 4 NAN \[u25B6] NAN \[u25B6] NAN \[u25B6] NAN \[u25B6] NAN \f[R] .fi .PP Etymology: Clojure (https://clojuredocs.org/clojure.core/repeat). .SS repr .IP .nf \f[C] repr $value... \f[R] .fi .PP Writes representation of \f[C]$value\f[R]s, separated by space and followed by a newline. Example: .IP .nf \f[C] \[ti]> repr [foo \[aq]lorem ipsum\[aq]] \[dq]aha\[rs]n\[dq] [foo \[aq]lorem ipsum\[aq]] \[dq]aha\[rs]n\[dq] \f[R] .fi .PP \[at]cf pprint .PP Etymology: Python (https://docs.python.org/3/library/functions.html#repr). .SS resolve .IP .nf \f[C] resolve $command \f[R] .fi .PP Output what \f[C]$command\f[R] resolves to in symbolic form. Command resolution is described in the language reference. .PP Example: .IP .nf \f[C] \[ti]> resolve echo \[u25B6] \[ti]> fn f { } \[ti]> resolve f \[u25B6] \[ti]> resolve cat \[u25B6] \f[R] .fi .SS return .PP Raises the special \[lq]return\[rq] exception. When raised inside a named function (defined by the \f[C]fn\f[R] keyword) it is captured by the function and causes the function to terminate. It is not captured by an anonymous function (aka lambda). .PP Because \f[C]return\f[R] raises an exception it can be caught by a \f[C]try\f[R] block. If not caught, either implicitly by a named function or explicitly, it causes a failure like any other uncaught exception. .PP See the discussion about flow commands and exceptions .PP \f[B]Note\f[R]: If you want to shadow the builtin \f[C]return\f[R] function with a local wrapper, do not define it with \f[C]fn\f[R] as \f[C]fn\f[R] swallows the special exception raised by return. Consider this example: .IP .nf \f[C] \[ti]> fn return { put return; builtin:return } \[ti]> fn test-return { put before; return; put after } \[ti]> test-return \[u25B6] before \[u25B6] return \[u25B6] after \f[R] .fi .PP Instead, shadow the function by directly assigning to \f[C]local:return\[ti]\f[R]: .IP .nf \f[C] \[ti]> local:return\[ti] = { put return; builtin:return } \[ti]> fn test-return { put before; return; put after } \[ti]> test-return \[u25B6] before \[u25B6] return \f[R] .fi .SS run-parallel .IP .nf \f[C] run-parallel $callable ... \f[R] .fi .PP Run several callables in parallel, and wait for all of them to finish. .PP If one or more callables throw exceptions, the other callables continue running, and a composite exception is thrown when all callables finish execution. .PP The behavior of \f[C]run-parallel\f[R] is consistent with the behavior of pipelines, except that it does not perform any redirections. .PP Here is an example that lets you pipe the stdout and stderr of a command to two different commands: .IP .nf \f[C] pout = (pipe) perr = (pipe) run-parallel { foo > $pout 2> $perr pwclose $pout pwclose $perr } { bar < $pout prclose $pout } { bar2 < $perr prclose $perr } \f[R] .fi .PP 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 \f[C]peach\f[R] instead. .PP \[at]cf peach .SS search-external .IP .nf \f[C] search-external $command \f[R] .fi .PP Output the full path of the external \f[C]$command\f[R]. Throws an exception when not found. Example (your output might vary): .IP .nf \f[C] \[ti]> search-external cat \[u25B6] /bin/cat \f[R] .fi .PP \[at]cf external has-external .SS set-env .IP .nf \f[C] set-env $name $value \f[R] .fi .PP Sets an environment variable to the given value. Example: .IP .nf \f[C] \[ti]> set-env X foobar \[ti]> put $E:X \[u25B6] foobar \f[R] .fi .PP \[at]cf get-env has-env unset-env .SS show .IP .nf \f[C] show $e \f[R] .fi .PP Shows the value to the output, which is assumed to be a VT-100-compatible terminal. .PP Currently, the only type of value that can be showed is exceptions, but this will likely expand in future. .PP Example: .IP .nf \f[C] \[ti]> e = ?(fail lorem-ipsum) \[ti]> show $e Exception: lorem-ipsum [tty 3], line 1: e = ?(fail lorem-ipsum) \f[R] .fi .SS sleep .IP .nf \f[C] sleep $duration \f[R] .fi .PP Pauses for at least the specified duration. The actual pause duration depends on the system. .PP 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 \f[C]peach\f[R]. .PP A duration can be a simple number (with optional fractional value) without an explicit unit suffix, with an implicit unit of seconds. .PP A duration can also be a string written as a sequence of decimal numbers, each with optional fraction, plus a unit suffix. For example, \[lq]300ms\[rq], \[lq]1.5h\[rq] or \[lq]1h45m7s\[rq]. Valid time units are \[lq]ns\[rq], \[lq]us\[rq] (or \[lq]\[mc]s\[rq]), \[lq]ms\[rq], \[lq]s\[rq], \[lq]m\[rq], \[lq]h\[rq]. .PP Passing a negative duration causes an exception; this is different from the typical BSD or GNU \f[C]sleep\f[R] command that silently exits with a success status without pausing when given a negative duration. .PP See the Go documentation (https://golang.org/pkg/time/#ParseDuration) for more information about how durations are parsed. .PP Examples: .IP .nf \f[C] \[ti]> sleep 0.1 # sleeps 0.1 seconds \[ti]> sleep 100ms # sleeps 0.1 seconds \[ti]> sleep 1.5m # sleeps 1.5 minutes \[ti]> sleep 1m30s # sleeps 1.5 minutes \[ti]> sleep -1 Exception: sleep duration must be >= zero [tty 8], line 1: sleep -1 \f[R] .fi .SS slurp .IP .nf \f[C] slurp \f[R] .fi .PP Reads bytes input into a single string, and put this string on structured stdout. .PP Example: .IP .nf \f[C] \[ti]> echo \[dq]a\[rs]nb\[dq] | slurp \[u25B6] \[dq]a\[rs]nb\[rs]n\[dq] \f[R] .fi .PP Etymology: Perl, as \f[C]File::Slurp\f[R] (http://search.cpan.org/~uri/File-Slurp-9999.19/lib/File/Slurp.pm). .SS -source .IP .nf \f[C] -source $filename \f[R] .fi .PP Equivalent to \f[C]eval (slurp <$filename)\f[R]. Deprecated. .SS src .IP .nf \f[C] src \f[R] .fi .PP Output a map-like value describing the current source being evaluated. The value contains the following fields: .IP \[bu] 2 \f[C]name\f[R], a unique name of the current source. If the source originates from a file, it is the full path of the file. .IP \[bu] 2 \f[C]code\f[R], the full body of the current source. .IP \[bu] 2 \f[C]is-file\f[R], whether the source originates from a file. .PP Examples: .IP .nf \f[C] \[ti]> put (src)[name code is-file] \[u25B6] \[aq][tty]\[aq] \[u25B6] \[aq]put (src)[name code is-file]\[aq] \[u25B6] $false \[ti]> echo \[aq]put (src)[name code is-file]\[aq] > show-src.elv \[ti]> elvish show-src.elv \[u25B6] /home/elf/show-src.elv \[u25B6] \[dq]put (src)[name code is-file]\[rs]n\[dq] \[u25B6] $true Note: this builtin always returns information of the source of the function calling \[ga]src\[ga]. Consider the following example: \[ga]\[ga]\[ga]elvish-transcript \[ti]> echo \[aq]fn show { put (src)[name] }\[aq] > \[ti]/.elvish/lib/src-fsutil.elv \[ti]> use src-util \[ti]> src-util:show \[u25B6] /home/elf/.elvish/lib/src-fsutil.elv \f[R] .fi .SS -stack .IP .nf \f[C] -stack \f[R] .fi .PP Print a stack trace. .PP This is only useful for debug purposes. .SS styled .IP .nf \f[C] styled $object $style-transformer... \f[R] .fi .PP Construct a styled text by applying the supplied transformers to the supplied object. \f[C]$object\f[R] can be either a string, a styled segment (see below), a styled text or an arbitrary concatenation of them. A \f[C]$style-transformer\f[R] is either: .IP \[bu] 2 The name of a builtin style transformer, which may be one of the following: .RS 2 .IP \[bu] 2 One of the attribute names \f[C]bold\f[R], \f[C]dim\f[R], \f[C]italic\f[R], \f[C]underlined\f[R], \f[C]blink\f[R] or \f[C]inverse\f[R] for setting the corresponding attribute. .IP \[bu] 2 An attribute name prefixed by \f[C]no-\f[R] for unsetting the attribute. .IP \[bu] 2 An attribute name prefixed by \f[C]toggle-\f[R] for toggling the attribute between set and unset. .RE .IP \[bu] 2 A color name for setting the text color, which may be one of the following: .RS 2 .IP \[bu] 2 One of the 8 basic ANSI colors: \f[C]black\f[R], \f[C]red\f[R], \f[C]green\f[R], \f[C]yellow\f[R], \f[C]blue\f[R], \f[C]magenta\f[R], \f[C]cyan\f[R] and \f[C]white\f[R]. .IP \[bu] 2 The bright variant of the 8 basic ANSI colors, with a \f[C]bright-\f[R] prefix. .IP \[bu] 2 Any color from the xterm 256-color palette, as \f[C]colorX\f[R] (such as \f[C]color12\f[R]). .IP \[bu] 2 A 24-bit RGB color written as \f[C]#RRGGBB\f[R] such as \f[C]\[aq]#778899\[aq]\f[R]. .RS 2 .PP \f[B]Note\f[R]: You need to quote such values since an unquoted \f[C]#\f[R] char introduces a comment. So use \f[C]\[aq]bg-#778899\[aq]\f[R] not \f[C]bg-#778899\f[R]. If you omit the quotes the text after the \f[C]#\f[R] char is ignored which will result in an error or unexpected behavior. .RE .RE .IP \[bu] 2 A color name prefixed by \f[C]bg-\f[R] to set the background color. .IP \[bu] 2 A color name prefixed by \f[C]fg-\f[R] to set the foreground color. This has the same effect as specifying the color name without the \f[C]fg-\f[R] prefix. .IP \[bu] 2 A lambda that receives a styled segment as the only argument and returns a single styled segment. .IP \[bu] 2 A function with the same properties as the lambda (provided via the \f[C]$transformer\[ti]\f[R] syntax). .PP 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. .PP A styled text is nothing more than a wrapper around a list of styled segments. They can be accessed by indexing into it. .IP .nf \f[C] s = (styled abc red)(styled def green) put $s[0] $s[1] \f[R] .fi .SS styled-segment .IP .nf \f[C] styled-segment $object &fg-color=default &bg-color=default &bold=$false &dim=$false &italic=$false &underlined=$false &blink=$false &inverse=$false \f[R] .fi .PP Constructs a styled segment and is a helper function for styled transformers. \f[C]$object\f[R] 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: .IP .nf \f[C] 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\[ti] \f[R] .fi .PP As just seen the properties of styled segments can be inspected by indexing into it. Valid indices are the same as the options to \f[C]styled-segment\f[R] plus \f[C]text\f[R]. .IP .nf \f[C] s = (styled-segment abc &bold) put $s[text] put $s[fg-color] put $s[bold] \f[R] .fi .SS take .IP .nf \f[C] take $n $input-list? \f[R] .fi .PP Retain the first \f[C]$n\f[R] input elements. If \f[C]$n\f[R] is larger than the number of input elements, the entire input is retained. Examples: .IP .nf \f[C] \[ti]> take 3 [a b c d e] \[u25B6] a \[u25B6] b \[u25B6] c \[ti]> use str \[ti]> str:split \[aq] \[aq] \[aq]how are you?\[aq] | take 1 \[u25B6] how \[ti]> range 2 | take 10 \[u25B6] 0 \[u25B6] 1 \f[R] .fi .PP Etymology: Haskell. .SS tilde-abbr .IP .nf \f[C] tilde-abbr $path \f[R] .fi .PP If \f[C]$path\f[R] represents a path under the home directory, replace the home directory with \f[C]\[ti]\f[R]. Examples: .IP .nf \f[C] \[ti]> echo $E:HOME /Users/foo \[ti]> tilde-abbr /Users/foo \[u25B6] \[aq]\[ti]\[aq] \[ti]> tilde-abbr /Users/foobar \[u25B6] /Users/foobar \[ti]> tilde-abbr /Users/foo/a/b \[u25B6] \[aq]\[ti]/a/b\[aq] \f[R] .fi .SS time .IP .nf \f[C] time &on-end=$nil $callable \f[R] .fi .PP Runs the callable, and call \f[C]$on-end\f[R] with the duration it took, as a number in seconds. If \f[C]$on-end\f[R] is \f[C]$nil\f[R] (the default), prints the duration in human-readable form. .PP If \f[C]$callable\f[R] throws an exception, the exception is propagated after the on-end or default printing is done. .PP If \f[C]$on-end\f[R] throws an exception, it is propagated, unless \f[C]$callable\f[R] has already thrown an exception. .PP Example: .IP .nf \f[C] \[ti]> time { sleep 1 } 1.006060647s \[ti]> time { sleep 0.01 } 1.288977ms \[ti]> t = \[aq]\[aq] \[ti]> time &on-end=[x]{ t = $x } { sleep 1 } \[ti]> put $t \[u25B6] (float64 1.000925004) \[ti]> time &on-end=[x]{ t = $x } { sleep 0.01 } \[ti]> put $t \[u25B6] (float64 0.011030208) \f[R] .fi .SS to-json .IP .nf \f[C] to-json \f[R] .fi .PP Takes structured stdin, convert it to JSON and puts the result on bytes stdout. .IP .nf \f[C] \[ti]> put a | to-json \[dq]a\[dq] \[ti]> put [lorem ipsum] | to-json [\[dq]lorem\[dq],\[dq]ipsum\[dq]] \[ti]> put [&lorem=ipsum] | to-json {\[dq]lorem\[dq]:\[dq]ipsum\[dq]} \f[R] .fi .PP \[at]cf from-json .SS to-lines .IP .nf \f[C] to-lines $input? \f[R] .fi .PP Writes each value input to a separate line in the byte output. Byte input is ignored. .IP .nf \f[C] \[ti]> put a b | to-lines a b \[ti]> to-lines [a b] a b \[ti]> { put a; echo b } | to-lines b a \f[R] .fi .PP \[at]cf from-lines .SS to-string .IP .nf \f[C] to-string $value... \f[R] .fi .PP Convert arguments to string values. .IP .nf \f[C] \[ti]> to-string foo [a] [&k=v] \[u25B6] foo \[u25B6] \[aq][a]\[aq] \[u25B6] \[aq][&k=v]\[aq] \f[R] .fi .SS unset-env .IP .nf \f[C] unset-env $name \f[R] .fi .PP Unset an environment variable. Example: .IP .nf \f[C] \[ti]> E:X = foo \[ti]> unset-env X \[ti]> has-env X \[u25B6] $false \[ti]> put $E:X \[u25B6] \[aq]\[aq] \f[R] .fi .PP \[at]cf has-env get-env set-env .SS use-mod .IP .nf \f[C] use-mod $use-spec \f[R] .fi .PP Imports a module, and outputs the namespace for the module. .PP Most code should use the use special command instead. .PP Examples: .IP .nf \f[C] \[ti]> echo \[aq]x = value\[aq] > a.elv \[ti]> put (use-mod ./a)[x] \[u25B6] value \f[R] .fi .SS wcswidth .IP .nf \f[C] wcswidth $string \f[R] .fi .PP Output the width of \f[C]$string\f[R] when displayed on the terminal. Examples: .IP .nf \f[C] \[ti]> wcswidth a \[u25B6] 1 \[ti]> wcswidth lorem \[u25B6] 5 \[ti]> wcswidth \[u4F60]\[u597D]\[uFF0C]\[u4E16]\[u754C] \[u25B6] 10 \f[R] .fi