.\" Automatically generated by Pandoc 2.2.1 .\" .TH "elvish\-builtin" "7" "Feb 08, 2019" "Elvish 0.12" "Miscellaneous Information Manual" .hy .SH Introduction .PP The builtin module contains facilities that are potentially useful to all users. It occupies the \f[C]builtin:\f[] namespace. You rarely have to explicitly specify the namespace though, since it is one of the namespaces consulted when resolving unqualified names. .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[] command takes two arguments and are described as: .IP .nf \f[C] repeat\ $n\ $v \f[] .fi .PP Optional arguments are represented with a trailing \f[C]?\f[], while variadic arguments with a trailing \f[C]\&...\f[]. For instance, the \f[C]count\f[] command takes an optional list: .IP .nf \f[C] count\ $input\-list? \f[] .fi .PP While the \f[C]put\f[] command takes an arbitrary number of arguments: .IP .nf \f[C] put\ $values... \f[] .fi .PP Options are given along with their default values. For instance, the \f[C]echo\f[] command takes an \f[C]sep\f[] option and arbitrary arguments: .IP .nf \f[C] echo\ &sep=\[aq]\ \[aq]\ $value... \f[] .fi .PP (When you calling functions, options are always optional.) .SS Supplying Input .PP Some builtin functions, e.g. \f[C]count\f[] and \f[C]each\f[], can take their input in one of two ways: .IP "1." 3 From pipe: .RS 4 .IP .nf \f[C] ~>\ put\ lorem\ ipsum\ |\ count\ #\ count\ number\ of\ inputs 2 ~>\ put\ 10\ 100\ |\ each\ [x]{\ +\ 1\ $x\ }\ #\ apply\ function\ to\ each\ input ▶\ 11 ▶\ 101 \f[] .fi .PP Byte pipes are also possible; one line becomes one input: .IP .nf \f[C] ~>\ echo\ "a\\nb\\nc"\ |\ count\ #\ count\ number\ of\ lines ▶\ 3 \f[] .fi .RE .IP "2." 3 From an argument \-\- an iterable value: .RS 4 .IP .nf \f[C] ~>\ count\ [lorem\ ipsum]\ #\ count\ number\ of\ elements\ in\ argument 2 ~>\ each\ [x]{\ +\ 1\ $x\ }\ [10\ 100]\ #\ apply\ to\ each\ element\ in\ argument ▶\ 11 ▶\ 101 \f[] .fi .PP Strings, and in future, other sequence types are also possible: .IP .nf \f[C] ~>\ count\ lorem ▶\ 5 \f[] .fi .RE .PP When documenting such commands, the optional argument is always written as \f[C]$input\-list?\f[]. On the other hand, a trailing \f[C]$input\-list?\f[] 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[]: You should prefer the first form, unless using it requires explicit \f[C]put\f[] commands. Avoid \f[C]count\ [(some\-command)]\f[] or \f[C]each\ $some\-func\ [(some\-command)]\f[]; they are, most of the time, equivalent to \f[C]some\-command\ |\ count\f[] or \f[C]some\-command\ |\ each\ $some\-func\f[]. .PP \f[B]Rationale\f[]: An alternative way to design this is to make (say) \f[C]count\f[] 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[]; 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[] will wait for inputs. Hence it is required to put the input in a list: \f[C]count\ [*]\f[] unambiguously supplies input in the argument, even if there is no file. .SS Numerical Commands .PP Commands that operate on numbers are quite flexible about the format of the numbers. Integers can be specified as decimals (e.g. \f[C]233\f[]) or hexadecimals (e.g. \f[C]0xE9\f[]) and floating\-point numbers can be specified using the scientific notation (e.g. \f[C]2.33e2\f[]). These are different strings, but equal when considered as commands. .PP Elvish has no special syntax or data type for numbers. Instead, they are just strings. For this reason, builtin commands for strings and numbers are completely separate. For instance, the numerical equality command is \f[C]==\f[], while the string equality command is \f[C]==s\f[]. Another example is the \f[C]+\f[] builtin, which only operates on numbers and does not function as a string concatenation commands. .SS Predicates .PP Predicates are functions that write exactly one output that is either \f[C]$true\f[] or \f[C]$false\f[]. They are described like "Determine ..." or "Test ...". See \f[C]is\f[] for one example. .SS "Do Not Use" Functions and Variables .PP The name of some variables and functions have a leading \f[C]\-\f[]. 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 Builtin Functions .SS + \- * / .IP .nf \f[C] +\ $summand... \-\ $minuend\ $subtrahend... *\ $factor... /\ $dividend\ $divisor... \f[] .fi .PP Basic arithmetic operations of adding, substraction, multiplication and division respectively. .PP All of them can take multiple arguments: .IP .nf \f[C] ~>\ +\ 2\ 5\ 7\ #\ 2\ +\ 5\ +\ 7 ▶\ 14 ~>\ \-\ 2\ 5\ 7\ #\ 2\ \-\ 5\ \-\ 7 ▶\ \-10 ~>\ *\ 2\ 5\ 7\ #\ 2\ *\ 5\ *\ 7 ▶\ 70 ~>\ /\ 2\ 5\ 7\ #\ 2\ /\ 5\ /\ 7 ▶\ 0.05714285714285715 \f[] .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[] outputs 0, and \f[C]*\f[] outputs 1. You can think that they both have a "hidden" argument of 0 or 1, which does not alter their behaviors (in mathematical terms, 0 and 1 are identity elements (https://en.wikipedia.org/wiki/Identity_element) of addition and multiplication, respectively). .IP \[bu] 2 \f[C]\-\f[] throws an exception. .IP \[bu] 2 \f[C]/\f[] becomes a synonym for \f[C]cd\ /\f[], due to the implicit cd feature. (The implicit cd feature will probably change to avoid this oddity). .SS % .IP .nf \f[C] %\ $dividend\ $divisor \f[] .fi .PP Output the remainder after dividing \f[C]$dividend\f[] by \f[C]$divisor\f[]. Both must be integers. Example: .IP .nf \f[C] ~>\ %\ 23\ 7 ▶\ 2 \f[] .fi .SS ^ .IP .nf \f[C] ^\ $base\ $exponent \f[] .fi .PP Output the result of raising \f[C]$base\f[] to the power of \f[C]$exponent\f[]. Examples: .IP .nf \f[C] ~>\ ^\ 2\ 10 ▶\ 1024 ~>\ ^\ 2\ 0.5 ▶\ 1.4142135623730951 \f[] .fi .SS < <= == != > >= .IP .nf \f[C] <\ \ $number...\ #\ less <=\ $number...\ #\ less\ or\ equal ==\ $number...\ #\ equal !=\ $number...\ #\ not\ equal >\ \ $number...\ #\ greater >=\ $number...\ #\ greater\ or\ equal \f[] .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[]. .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] ~>\ ==\ 3\ 3.0 ▶\ $true ~>\ <\ 3\ 4 ▶\ $true ~>\ <\ 3\ 4\ 10 ▶\ $true ~>\ <\ 6\ 9\ 1 ▶\ $false \f[] .fi .PP As a consequence of rule 3, the \f[C]!=\f[] command outputs \f[C]$true\f[] as long as any \f[I]adjacent\f[] pair of numbers are not equal, even if some numbers that are not adjacent are equal: .IP .nf \f[C] ~>\ !=\ 5\ 5\ 4 ▶\ $false ~>\ !=\ 5\ 6\ 5 ▶\ $true \f[] .fi .SS s >=s .IP .nf \f[C] s\ \ $string...\ #\ greater >=s\ $string...\ #\ greater\ or\ equal \f[] .fi .PP String comparisons. They behave similarly to their number counterparts when given multiple arguments. Examples: .IP .nf \f[C] ~>\ >s\ lorem\ ipsum ▶\ $true ~>\ ==s\ 1\ 1.0 ▶\ $false ~>\ >s\ 8\ 12 ▶\ $true \f[] .fi .SS all .IP .nf \f[C] all \f[] .fi .PP Pass inputs, both bytes and values, to the output. .PP This is an identity function in pipelines: \f[C]a\ |\ all\ |\ b\f[] is equivalent to \f[C]a\ |\ b\f[]. It is mainly useful for turning inputs into arguments, like: .IP .nf \f[C] ~>\ put\ \[aq]lorem,ipsum\[aq]\ |\ splits\ ,\ (all) ▶\ lorem ▶\ ipsum \f[] .fi .PP Or capturing all inputs in a variable: .IP .nf \f[C] ~>\ x\ =\ [(all)] foo bar (Press\ ^D) ~>\ put\ $x ▶\ [foo\ bar] \f[] .fi .SS assoc .IP .nf \f[C] assoc\ $container\ $k\ $v \f[] .fi .PP Output a slighly modified version of \f[C]$container\f[], such that its value at \f[C]$k\f[] is \f[C]$v\f[]. Applies to both lists and to maps. .PP When \f[C]$container\f[] is a list, \f[C]$k\f[] may be a negative index. However, slice is not yet supported. .IP .nf \f[C] ~>\ 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] \f[] .fi .PP Etymology: Clojure (https://clojuredocs.org/clojure.core/assoc). .PP $cf dissoc .SS bool .IP .nf \f[C] bool\ $value \f[] .fi .PP Convert a value to boolean. In Elvish, only \f[C]$false\f[] and errors are booleanly false. Everything else, including 0, empty strings and empty lists, is booleanly true: .IP .nf \f[C] ~>\ bool\ $true ▶\ $true ~>\ bool\ $false ▶\ $false ~>\ bool\ $ok ▶\ $true ~>\ bool\ ?(fail\ haha) ▶\ $false ~>\ bool\ \[aq]\[aq] ▶\ $true ~>\ bool\ [] ▶\ $true ~>\ bool\ abc ▶\ $true \f[] .fi .PP $cf not .SS cd .IP .nf \f[C] cd\ $dirname \f[] .fi .PP Change directory. .PP Note that Elvish\[aq]s \f[C]cd\f[] does not support \f[C]cd\ \-\f[]. .SS constantly .IP .nf \f[C] constantly\ $value... \f[] .fi .PP Output a function that takes no arguments and outputs \f[C]$value\f[]s when called. Examples: .IP .nf \f[C] ~>\ f=(constantly\ lorem\ ipsum) ~>\ $f ▶\ lorem ▶\ ipsum \f[] .fi .PP The above example is actually equivalent to simply \f[C]f\ =\ []{\ put\ lorem\ ipsum\ }\f[]; it is most useful when the argument is \f[B]not\f[] a literal value, e.g. .IP .nf \f[C] ~>\ f\ =\ (constantly\ (uname)) ~>\ $f ▶\ Darwin ~>\ $f ▶\ Darwin \f[] .fi .PP The above code only calls \f[C]uname\f[] once, while if you do \f[C]f\ =\ []{\ put\ (uname)\ }\f[], every time you invoke \f[C]$f\f[], \f[C]uname\f[] will be called. .PP Etymology: Clojure (https://clojuredocs.org/clojure.core/constantly). .SS count .IP .nf \f[C] count\ $input\-list? \f[] .fi .PP Count the number of inputs. .PP Examples: .IP .nf \f[C] ~>\ count\ lorem\ #\ count\ bytes\ in\ a\ string ▶\ 5 ~>\ count\ [lorem\ ipsum] ▶\ 2 ~>\ range\ 100\ |\ count ▶\ 100 ~>\ seq\ 100\ |\ count ▶\ 100 \f[] .fi .SS dir\-history .IP .nf \f[C] dir\-history \f[] .fi .PP Return a list containing the directory history. Each element is a map with two keys: \f[C]path\f[] and \f[C]score\f[]. The list is sorted by descending score. .PP Example: .IP .nf \f[C] ~>\ dir\-history\ |\ take\ 1 ▶\ [&path=/Users/foo/.elvish\ &score=96.79928] \f[] .fi .SS dissoc .IP .nf \f[C] dissoc\ $map\ $k \f[] .fi .PP Output a slightly modified version of \f[C]$map\f[], with the key \f[C]$k\f[] removed. If \f[C]$map\f[] does not contain \f[C]$k\f[] as a key, the same map is returned. .IP .nf \f[C] ~>\ dissoc\ [&foo=bar\ &lorem=ipsum]\ foo ▶\ [&lorem=ipsum] ~>\ dissoc\ [&foo=bar\ &lorem=ipsum]\ k ▶\ [&lorem=ipsum\ &foo=bar] \f[] .fi .PP $cf assoc .SS drop .IP .nf \f[C] drop\ $n\ $input\-list? \f[] .fi .PP Drop the first \f[C]$n\f[] elements of the input. If \f[C]$n\f[] is larger than the number of input elements, the entire input is dropped. .PP Example: .IP .nf \f[C] ~>\ drop\ 2\ [a\ b\ c\ d\ e] ▶\ c ▶\ d ▶\ e ~>\ splits\ \[aq]\ \[aq]\ \[aq]how\ are\ you?\[aq]\ |\ drop\ 1 ▶\ are ▶\ \[aq]you?\[aq] ~>\ range\ 2\ |\ drop\ 10 \f[] .fi .PP Etymology: Haskell. .PP $cf take .SS each .IP .nf \f[C] each\ $f\ $input\-list? \f[] .fi .PP Call \f[C]$f\f[] on all inputs. Examples: .IP .nf \f[C] ~>\ range\ 5\ 8\ |\ each\ [x]{\ ^\ $x\ 2\ } ▶\ 25 ▶\ 36 ▶\ 49 ~>\ each\ [x]{\ put\ $x[:3]\ }\ [lorem\ ipsum] ▶\ lor ▶\ ips \f[] .fi .PP $cf peach .PP Etymology: Various languages, as \f[C]for\ each\f[]. 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[] .fi .PP For each input, call \f[C]$f\f[] with the input followed by all its fields. .PP It should behave the same as the following functions: .IP .nf \f[C] fn\ eawk\ [f\ \@rest]{ \ \ each\ [line]{ \ \ \ \ \@fields\ =\ (re:split\ \[aq][\ \\t]+\[aq] \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (re:replace\ \[aq]^[\ \\t]+|[\ \\t]+$\[aq]\ \[aq]\[aq]\ $line)) \ \ \ \ $f\ $line\ $\@fields \ \ }\ $\@rest } \f[] .fi .PP This command allows you to write code very similar to \f[C]awk\f[] scripts using anonymous functions. Example: .IP .nf \f[C] ~>\ echo\ \[aq]\ lorem\ ipsum \ \ \ 1\ 2\[aq]\ |\ awk\ \[aq]{\ print\ $1\ }\[aq] lorem 1 ~>\ echo\ \[aq]\ lorem\ ipsum \ \ \ 1\ 2\[aq]\ |\ eawk\ [line\ a\ b]{\ put\ $a\ } ▶\ lorem ▶\ 1 \f[] .fi .SS echo .IP .nf \f[C] echo\ &sep=\[aq]\ \[aq]\ $value... \f[] .fi .PP Print all arguments, joined by the \f[C]sep\f[] option, and followed by a newline. .PP Examples: .IP .nf \f[C] ~>\ echo\ Hello\ \ \ elvish Hello\ elvish ~>\ echo\ "Hello\ \ \ elvish" Hello\ \ \ elvish ~>\ echo\ &sep=,\ lorem\ ipsum lorem,ipsum \f[] .fi .PP Notes: The \f[C]echo\f[] builtin does not treat \f[C]\-e\f[] or \f[C]\-n\f[] specially. For instance, \f[C]echo\ \-n\f[] just prints \f[C]\-n\f[]. Use double\-quoted strings to print special characters, and \f[C]print\f[] to suppress the trailing newline. .PP $cf print .PP Etymology: Bourne sh. .SS eq .IP .nf \f[C] eq\ $values... \f[] .fi .PP Determine whether all \f[C]$value\f[]s are structurally equivalent. Writes \f[C]$true\f[] when given no or one argument. .IP .nf \f[C] ~>\ eq\ a\ a ▶\ $true ~>\ eq\ [a]\ [a] ▶\ $true ~>\ eq\ [&k=v]\ [&k=v] ▶\ $true ~>\ eq\ a\ [b] ▶\ $false \f[] .fi .PP $cf is not\-eq .PP Etymology: Perl (https://perldoc.perl.org/perlop.html#Equality-Operators). .SS exec .IP .nf \f[C] exec\ $command? \f[] .fi .PP Replace the Elvish process with an external \f[C]$command\f[], defaulting to \f[C]elvish\f[]. .SS exit .IP .nf \f[C] exit\ $status? \f[] .fi .PP Exit the Elvish process with \f[C]$status\f[] (defaulting to 0). .SS explode .IP .nf \f[C] explode\ $iterable \f[] .fi .PP Put all elements of \f[C]$iterable\f[] on the structured stdout. Like \f[C]flatten\f[] in functional languages. Equivalent to \f[C][li]{\ put\ $\@li\ }\f[]. .PP Example: .IP .nf \f[C] ~>\ explode\ [a\ b\ [x]] ▶\ a ▶\ b ▶\ [x] \f[] .fi .PP Etymology: PHP (http://php.net/manual/en/function.explode.php). PHP\[aq]s \f[C]explode\f[] is actually equivalent to Elvish\[aq]s \f[C]splits\f[], but the author liked the name too much to not use it. .SS external .IP .nf \f[C] external\ $program \f[] .fi .PP Construct a callable value for the external program \f[C]$program\f[]. Example: .IP .nf \f[C] ~>\ x\ =\ (external\ man) ~>\ $x\ ls\ #\ opens\ the\ manpage\ for\ ls \f[] .fi .PP $cf has\-external search\-external .SS fail .IP .nf \f[C] fail\ $message \f[] .fi .PP Throw an exception. .IP .nf \f[C] ~>\ fail\ bad Exception:\ bad Traceback: \ \ [interactive],\ line\ 1: \ \ \ \ fail\ bad ~>\ put\ ?(fail\ bad) ▶\ ?(fail\ bad) \f[] .fi .PP \f[B]Note\f[]: Exceptions are now only allowed to carry string messages. You cannot do \f[C]fail\ [&cause=xxx]\f[] (this will, ironically, throw a different exception complaining that you cannot throw a map). This is subject to change. Builtins will likely also throw structured exceptions in future. .SS fclose .IP .nf \f[C] fclose\ $file \f[] .fi .PP Close a file opened with \f[C]fopen\f[]. .PP $cf fopen .SS fopen .IP .nf \f[C] fopen\ $filename \f[] .fi .PP Open a file. Currently, \f[C]fopen\f[] only supports opening a file for reading. File must be closed with \f[C]fclose\f[] explicitly. Example: .IP .nf \f[C] ~>\ cat\ a.txt This\ is a\ file. ~>\ f\ =\ (fopen\ a.txt) ~>\ cat\ <\ $f This\ is a\ file. ~>\ fclose\ $f \f[] .fi .PP $cf fclose .SS from\-json .IP .nf \f[C] from\-json \f[] .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] ~>\ echo\ \[aq]"a"\[aq]\ |\ from\-json ▶\ a ~>\ echo\ \[aq]["lorem",\ "ipsum"]\[aq]\ |\ from\-json ▶\ [lorem\ ipsum] ~>\ echo\ \[aq]{"lorem":\ "ipsum"}\[aq]\ |\ from\-json ▶\ [&lorem=ipsum] ~>\ #\ multiple\ JSONs\ running\ together \ \ \ echo\ \[aq]"a""b"["x"]\[aq]\ |\ from\-json ▶\ a ▶\ b ▶\ [x] ~>\ #\ multiple\ JSONs\ separated\ by\ newlines \ \ \ echo\ \[aq]"a" \ \ \ {"k":\ "v"}\[aq]\ |\ from\-json ▶\ a ▶\ [&k=v] \f[] .fi .PP $cf to\-json .SS has\-external .IP .nf \f[C] has\-external\ $command \f[] .fi .PP Test whether \f[C]$command\f[] names a valid external command. Examples (your output might differ): .IP .nf \f[C] ~>\ has\-external\ cat ▶\ $true ~>\ has\-external\ lalala ▶\ $false \f[] .fi .PP $cf external search\-external .SS has\-prefix .IP .nf \f[C] has\-prefix\ $string\ $prefix \f[] .fi .PP Determine whether \f[C]$prefix\f[] is a prefix of \f[C]$string\f[]. Examples: .IP .nf \f[C] ~>\ has\-prefix\ lorem,ipsum\ lor ▶\ $true ~>\ has\-prefix\ lorem,ipsum\ foo ▶\ $false \f[] .fi .SS has\-suffix .IP .nf \f[C] has\-suffix\ $string\ $suffix \f[] .fi .PP Determine whether \f[C]$suffix\f[] is a suffix of \f[C]$string\f[]. Examples: .IP .nf \f[C] ~>\ has\-suffix\ a.html\ .txt ▶\ $false ~>\ has\-suffix\ a.html\ .html ▶\ $true \f[] .fi .SS is .IP .nf \f[C] is\ $values... \f[] .fi .PP Determine whether all \f[C]$value\f[]s have the same identity. Writes \f[C]$true\f[] 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] ~>\ is\ a\ a ▶\ $true ~>\ is\ a\ b ▶\ $false ~>\ is\ []\ [] ▶\ $true ~>\ is\ [a]\ [a] ▶\ $false \f[] .fi .PP $cf eq .PP Etymology: Python (https://docs.python.org/3/reference/expressions.html#is). .SS joins .IP .nf \f[C] joins\ $sep\ $input\-list? \f[] .fi .PP Join inputs with \f[C]$sep\f[]. Examples: .IP .nf \f[C] ~>\ put\ lorem\ ipsum\ |\ joins\ , ▶\ lorem,ipsum ~>\ joins\ ,\ [lorem\ ipsum] ▶\ lorem,ipsum \f[] .fi .PP The suffix "s" means "string" and also serves to avoid colliding with the well\-known join (https://en.wikipedia.org/wiki/join_(Unix)) utility. .PP Etymology: Various languages as \f[C]join\f[], in particular Python (https://docs.python.org/3.6/library/stdtypes.html#str.join). .PP $cf splits .SS keys .IP .nf \f[C] keys\ $map \f[] .fi .PP Put all keys of \f[C]$map\f[] on the structured stdout. .PP Example: .IP .nf \f[C] ~>\ keys\ [&a=foo\ &b=bar\ &c=baz] ▶\ a ▶\ c ▶\ b \f[] .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[] .fi .PP Output the kinds of \f[C]$value\f[]s. Example: .IP .nf \f[C] ~>\ kind\-of\ lorem\ []\ [&] ▶\ string ▶\ list ▶\ map \f[] .fi .PP The terminology and definition of "kind" is subject to change. .SS nop .IP .nf \f[C] nop\ &any\-opt=\ $value... \f[] .fi .PP Accepts arbitrary arguments and options and does exactly nothing. .PP Examples: .IP .nf \f[C] ~>\ nop ~>\ nop\ a\ b\ c ~>\ nop\ &k=v \f[] .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[] .fi .PP Boolean negation. Examples: .IP .nf \f[C] ~>\ not\ $true ▶\ $false ~>\ not\ $false ▶\ $true ~>\ not\ $ok ▶\ $false ~>\ not\ ?(fail\ error) ▶\ $true \f[] .fi .PP \f[B]NOTE\f[]: \f[C]and\f[] and \f[C]or\f[] are implemented as special commands. .PP $cf bool .SS not\-eq .IP .nf \f[C] not\-eq\ $values... \f[] .fi .PP Determines whether every adjacent pair of \f[C]$value\f[]s are not equal. Note that this does not imply that \f[C]$value\f[]s are all distinct. Examples: .IP .nf \f[C] ~>\ not\-eq\ 1\ 2\ 3 ▶\ $true ~>\ not\-eq\ 1\ 2\ 1 ▶\ $true ~>\ not\-eq\ 1\ 1\ 2 ▶\ $false \f[] .fi .PP $cf eq .SS ord .IP .nf \f[C] ord\ $string \f[] .fi .PP Output value of each codepoint in \f[C]$string\f[], in hexadecimal. Examples: .IP .nf \f[C] ~>\ ord\ aA ▶\ 0x61 ▶\ 0x41 ~>\ ord\ 你好 ▶\ 0x4f60 ▶\ 0x597d \f[] .fi .PP The output format is subject to change. .PP Etymology: Python (https://docs.python.org/3/library/functions.html#ord). .SS path\-* .IP .nf \f[C] path\-abs\ $path path\-base\ $path path\-clean\ $path path\-dir\ $path path\-ext\ $path \f[] .fi .PP See godoc of path/filepath (https://godoc.org/path/filepath). Go errors are turned into exceptions. .SS peach .IP .nf \f[C] peach\ $f\ $input\-list? \f[] .fi .PP Call \f[C]$f\f[] on all inputs, possibly in parallel. .PP Example (your output will differ): .IP .nf \f[C] ~>\ range\ 1\ 7\ |\ peach\ [x]{\ +\ $x\ 10\ } ▶\ 12 ▶\ 11 ▶\ 13 ▶\ 16 ▶\ 15 ▶\ 14 \f[] .fi .PP This command is intended for homogenous processing of possibly unbound data. If you need to do a fixed number of heterogenous things in parallel, use \f[C]run\-parallel\f[]. .PP $cf each run\-parallel .SS pipe .IP .nf \f[C] pipe \f[] .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[], the read FD is used. When redirecting command output to a pipe with \f[C]>\f[], the write FD is used. It is not supported to redirect both input and output with \f[C]<>\f[] 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[] be explicitly closed with \f[C]prclose\f[] and \f[C]pwclose\f[]. .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] ~>\ p\ =\ (pipe) ~>\ echo\ \[aq]lorem\ ipsum\[aq]\ >\ $p ~>\ head\ \-n1\ <\ $p lorem\ ipsum ~>\ put\ \[aq]lorem\ ipsum\[aq]\ >\ $p ~>\ head\ \-n1\ <\ $p #\ blocks #\ $p\ should\ be\ closed\ with\ prclose\ and\ pwclose\ afterwards \f[] .fi .PP $cf prclose pwclose .SS prclose .IP .nf \f[C] prclose\ $pipe \f[] .fi .PP Close the read end of a pipe. .PP $cf pwclose pipe .SS put .IP .nf \f[C] put\ $value... \f[] .fi .PP Takes arbitrary arguments and write them to the structured stdout. .PP Examples: .IP .nf \f[C] ~>\ put\ a ▶\ a ~>\ put\ lorem\ ipsum\ [a\ b]\ {\ ls\ } ▶\ lorem ▶\ ipsum ▶\ [a\ b] ▶\ \f[] .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[]. .SS pprint .IP .nf \f[C] pprint\ $value... \f[] .fi .PP Pretty\-print representations of Elvish values. Examples: .IP .nf \f[C] ~>\ pprint\ [foo\ bar] [ \ foo \ bar ] ~>\ pprint\ [&k1=v1\ &k2=v2] [ \ &k2= \ \ v2 \ &k1= \ \ v1 ] \f[] .fi .PP The output format is subject to change. .PP $cf repr .SS print .IP .nf \f[C] print\ &sep=\[aq]\ \[aq]\ $value... \f[] .fi .PP Like \f[C]echo\f[], just without the newline. .PP $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[]s do not print a trailing newline. .SS pwclose .IP .nf \f[C] pwclose\ $pipe \f[] .fi .PP Close the write end of a pipe. .PP $cf prclose pipe .SS range .IP .nf \f[C] range\ &step=1\ $low?\ $high \f[] .fi .PP Output \f[C]$low\f[], \f[C]$low\f[] + \f[C]$step\f[], ..., proceeding as long as smaller than \f[C]$high\f[]. If not given, \f[C]$low\f[] defaults to 0. .PP Examples: .IP .nf \f[C] ~>\ range\ 4 ▶\ 0 ▶\ 1 ▶\ 2 ▶\ 3 ~>\ range\ 1\ 6\ &step=2 ▶\ 1 ▶\ 3 ▶\ 5 \f[] .fi .PP Beware floating point oddities: .IP .nf \f[C] ~>\ range\ 0\ 0.8\ &step=.1 ▶\ 0 ▶\ 0.1 ▶\ 0.2 ▶\ 0.30000000000000004 ▶\ 0.4 ▶\ 0.5 ▶\ 0.6 ▶\ 0.7 ▶\ 0.7999999999999999 \f[] .fi .PP Etymology: Python (https://docs.python.org/3/library/functions.html#func-range). .SS rand .IP .nf \f[C] rand \f[] .fi .PP Output a pseudo\-random number in the interval [0, 1). Example: .IP .nf \f[C] ~>\ rand ▶\ 0.17843564133528436 \f[] .fi .SS randint .IP .nf \f[C] randint\ $low\ $high \f[] .fi .PP Output a pseudo\-random integer in the interval [$low, $high). Example: .IP .nf \f[C] ~>\ #\ Emulate\ dice \ \ \ randint\ 1\ 7 ▶\ 6 \f[] .fi .SS repeat .IP .nf \f[C] repeat\ $n\ $value \f[] .fi .PP Output \f[C]$value\f[] for \f[C]$n\f[] times. Example: .IP .nf \f[C] ~>\ repeat\ 0\ lorem ~>\ repeat\ 4\ NAN ▶\ NAN ▶\ NAN ▶\ NAN ▶\ NAN \f[] .fi .PP Etymology: Clojure (https://clojuredocs.org/clojure.core/repeat). .SS replaces .IP .nf \f[C] replaces\ &max=\-1\ $old\ $repl\ $source \f[] .fi .PP Replace all occurrences of \f[C]$old\f[] with \f[C]$repl\f[] in \f[C]$source\f[]. If \f[C]$max\f[] is non\-negative, it determines the max number of substitutions. .PP \f[B]Note\f[]: \f[C]replaces\f[] does not support searching by regular expressions, \f[C]$old\f[] is always interpreted as a plain string. Use re:replace (re.html#replace) if you need to search by regex. .SS repr .IP .nf \f[C] repr\ $value... \f[] .fi .PP Writes representation of \f[C]$value\f[]s, separated by space and followed by a newline. Example: .IP .nf \f[C] ~>\ repr\ [foo\ \[aq]lorem\ ipsum\[aq]]\ "aha\\n" [foo\ \[aq]lorem\ ipsum\[aq]]\ "aha\\n" \f[] .fi .PP $cf pprint .PP Etymology: Python (https://docs.python.org/3/library/functions.html#repr). .SS resolve .IP .nf \f[C] resolve\ $command \f[] .fi .PP Resolve \f[C]$command\f[]. Command resolution is described in the language reference (/ref/language.html). (TODO: actually describe it there.) .PP Example: .IP .nf \f[C] ~>\ resolve\ echo ▶\ ~>\ fn\ f\ {\ } ~>\ resolve\ f ▶\ ~>\ resolve\ cat ▶\ \f[] .fi .SS run\-parallel .IP .nf \f[C] run\-parallel\ $callable\ ... \f[] .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[] 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[] .fi .PP This command is intended for doing a fixed number of heterogenous things in parallel. If you need homogenous parallel processing of possibly unbound data, use \f[C]peach\f[] instead. .PP $cf peach .SS search\-external .IP .nf \f[C] search\-external\ $command \f[] .fi .PP Output the full path of the external \f[C]$command\f[]. Throws an exception when not found. Example (your output might vary): .IP .nf \f[C] ~>\ search\-external\ cat ▶\ /bin/cat \f[] .fi .PP $cf external has\-external .SS slurp .IP .nf \f[C] slurp \f[] .fi .PP Reads bytes input into a single string, and put this string on structured stdout. .PP Example: .IP .nf \f[C] ~>\ echo\ "a\\nb"\ |\ slurp ▶\ "a\\nb\\n" \f[] .fi .PP Etymology: Perl, as \f[C]File::Slurp\f[] (http://search.cpan.org/~uri/File-Slurp-9999.19/lib/File/Slurp.pm). .SS splits .IP .nf \f[C] splits\ $sep\ $string \f[] .fi .PP Split \f[C]$string\f[] by \f[C]$sep\f[]. If \f[C]$sep\f[] is an empty string, split it into codepoints. .IP .nf \f[C] ~>\ splits\ ,\ lorem,ipsum ▶\ lorem ▶\ ipsum ~>\ splits\ \[aq]\[aq]\ 你好 ▶\ 你 ▶\ 好 \f[] .fi .PP \f[B]Note\f[]: \f[C]splits\f[] does not support splitting by regular expressions, \f[C]$sep\f[] is always interpreted as a plain string. Use re:split (re.html#split) if you need to split by regex. .PP Etymology: Various languages as \f[C]split\f[], in particular Python (https://docs.python.org/3.6/library/stdtypes.html#str.split). .PP $cf joins .SS src .IP .nf \f[C] src \f[] .fi .PP Output a map\-like value describing the current source being evaluated. The value contains the following fields: .IP \[bu] 2 \f[C]type\f[], which can be one of \f[C]interactive\f[], \f[C]script\f[] or \f[C]module\f[]; .IP \[bu] 2 \f[C]name\f[], which is set to the name under which a script is executed or a module is imported. It is an empty string when \f[C]type\f[] = \f[C]interactive\f[]; .IP \[bu] 2 \f[C]path\f[], which is the path to the current source. It is an empty string when \f[C]type\f[] = \f[C]interactive\f[]; .IP \[bu] 2 \f[C]code\f[], which is the full body of the current source. .PP Examples: .IP .nf \f[C] ~>\ put\ (src)[type\ name\ path\ code] ▶\ interactive ▶\ \[aq]\[aq] ▶\ \[aq]\[aq] ▶\ \[aq]put\ (src)[type\ name\ path\ code]\[aq] ~>\ echo\ \[aq]put\ (src)[type\ name\ path\ code]\[aq]\ >\ foo.elv ~>\ elvish\ foo.elv ▶\ script ▶\ foo.elv ▶\ /home/xiaq/foo.elv ▶\ "put\ (src)[type\ name\ path\ code]\\n" ~>\ echo\ \[aq]put\ (src)[type\ name\ path\ code]\[aq]\ >\ ~/.elvish/lib/m.elv ~>\ use\ m ▶\ module ▶\ m ▶\ /home/xiaq/.elvish/lib/m.elv ▶\ "put\ (src)[type\ name\ path\ code]\\n" \f[] .fi .PP Note: this builtin always returns information of the source of the \f[B]calling function\f[]. Example: .IP .nf \f[C] ~>\ echo\ \[aq]fn\ f\ {\ put\ (src)[type\ name\ path\ code]\ }\[aq]\ >\ ~/.elvish/lib/n.elv ~>\ use\ n ~>\ n:f ▶\ module ▶\ n ▶\ /home/xiaq/.elvish/lib/n.elv ▶\ "fn\ f\ {\ put\ (src)[type\ name\ path\ code]\ }\\n" \f[] .fi .SS styled .IP .nf \f[C] styled\ $object\ $style\-transformer... \f[] .fi .PP Construct a styled text by applying the supplied transformers to the supplied object. \f[C]$object\f[] 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[] is either: .IP \[bu] 2 The name of a builtin style transformer .RS 2 .IP \[bu] 2 On of the attribute names \f[C]bold\f[], \f[C]dim\f[], \f[C]italic\f[], \f[C]underlined\f[], \f[C]blink\f[] or \f[C]inverse\f[] for setting the corresponding attribute .IP \[bu] 2 An attribute name prefixed by \f[C]no\-\f[] for unsetting the attribute .IP \[bu] 2 An attribute name prefixed by \f[C]toggle\-\f[] for toggling the attribute between set and unset .IP \[bu] 2 One of the color names \f[C]black\f[], \f[C]red\f[], \f[C]green\f[], \f[C]yellow\f[], \f[C]blue\f[], \f[C]magenta\f[], \f[C]cyan\f[], \f[C]lightgray\f[], \f[C]gray\f[], \f[C]lightred\f[], \f[C]lightgreen\f[], \f[C]lightyellow\f[], \f[C]lightblue\f[], \f[C]lightmagenta\f[], \f[C]lightcyan\f[] or \f[C]white\f[] for setting the text color .IP \[bu] 2 A color name prefixed by \f[C]bg\-\f[] to set the background color .RE .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~\f[] 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[] .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[] .fi .PP Constructs a styled segment and is a helper function for styled transformers. \f[C]$object\f[] 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~ \f[] .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[] plus \f[C]text\f[]. .IP .nf \f[C] s\ =\ (styled\-segment\ abc\ &bold) put\ $s[text] put\ $s[fg\-color] put\ $s[bold] \f[] .fi .SS take .IP .nf \f[C] take\ $n\ $input\-list? \f[] .fi .PP Retain the first \f[C]$n\f[] input elements. If \f[C]$n\f[] is larger than the number of input elements, the entire input is retained. Examples: .IP .nf \f[C] ~>\ take\ 3\ [a\ b\ c\ d\ e] ▶\ a ▶\ b ▶\ c ~>\ splits\ \[aq]\ \[aq]\ \[aq]how\ are\ you?\[aq]\ |\ take\ 1 ▶\ how ~>\ range\ 2\ |\ take\ 10 ▶\ 0 ▶\ 1 \f[] .fi .PP Etymology: Haskell. .SS tilde\-abbr .IP .nf \f[C] tilde\-abbr\ $path \f[] .fi .PP If \f[C]$path\f[] represents a path under the home directory, replace the home directory with \f[C]~\f[]. Examples: .IP .nf \f[C] ~>\ echo\ $E:HOME /Users/foo ~>\ tilde\-abbr\ /Users/foo ▶\ \[aq]~\[aq] ~>\ tilde\-abbr\ /Users/foobar ▶\ /Users/foobar ~>\ tilde\-abbr\ /Users/foo/a/b ▶\ \[aq]~/a/b\[aq] \f[] .fi .SS to\-json .IP .nf \f[C] to\-json \f[] .fi .PP Takes structured stdin, convert it to JSON and puts the result on bytes stdout. .IP .nf \f[C] ~>\ put\ a\ |\ to\-json "a" ~>\ put\ [lorem\ ipsum]\ |\ to\-json ["lorem","ipsum"] ~>\ put\ [&lorem=ipsum]\ |\ to\-json {"lorem":"ipsum"} \f[] .fi .PP $cf from\-json .SS to\-string .IP .nf \f[C] to\-string\ $value... \f[] .fi .PP Convert arguments to string values. .IP .nf \f[C] ~>\ to\-string\ foo\ [a]\ [&k=v] ▶\ foo ▶\ \[aq][a]\[aq] ▶\ \[aq][&k=v]\[aq] \f[] .fi .SS wcswidth .IP .nf \f[C] wcswidth\ $string \f[] .fi .PP Output the width of \f[C]$string\f[] when displayed on the terminal. Examples: .IP .nf \f[C] ~>\ wcswidth\ a ▶\ 1 ~>\ wcswidth\ lorem ▶\ 5 ~>\ wcswidth\ 你好,世界 ▶\ 10 \f[] .fi .SS \-gc .IP .nf \f[C] \-gc \f[] .fi .PP Force the Go garbage collector to run. .PP This is only useful for debug purposes. .SS \-ifaddrs .IP .nf \f[C] \-ifaddrs \f[] .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 \-log .IP .nf \f[C] \-log\ $filename \f[] .fi .PP Direct internal debug logs to the named file. .PP This is only useful for debug purposes. .SS \-stack .IP .nf \f[C] \-stack \f[] .fi .PP Print a stack trace. .PP This is only useful for debug purposes. .SS \-source .IP .nf \f[C] \-source\ $filename \f[] .fi .PP Read the named file, and evaluate it in the current scope. .PP Examples: .IP .nf \f[C] ~>\ cat\ x.elv echo\ \[aq]executing\ x.elv\[aq] foo\ =\ bar ~>\ \-source\ x.elv executing\ x.elv ~>\ echo\ $foo bar \f[] .fi .PP Note that while in the example, you can reference \f[C]$foo\f[] after sourcing \f[C]x.elv\f[], putting the \f[C]\-source\f[] command and reference to \f[C]$foo\f[] in the \f[B]same code chunk\f[] (e.g. by using Alt\-Enter to insert a literal Enter, or using \f[C];\f[]) is invalid: .IP .nf \f[C] ~>\ #\ A\ new\ Elvish\ session ~>\ cat\ x.elv echo\ \[aq]executing\ x.elv\[aq] foo\ =\ bar ~>\ \-source\ x.elv;\ echo\ $foo Compilation\ error:\ variable\ $foo\ not\ found \ \ [interactive],\ line\ 1: \ \ \ \ \-source\ x.elv;\ echo\ $foo \f[] .fi .PP This is because the reading of the file is done in the evaluation phase, while the check for variables happens at the compilation phase (before evaluation). So the compiler has no evidence showing that \f[C]$foo\f[] is actually valid, and will complain. (See here (/learn/unique-semantics.html#execution-phases) for a more detailed description of execution phases.) .PP To work around this, you can add a forward declaration for \f[C]$foo\f[]: .IP .nf \f[C] ~>\ #\ Another\ new\ session ~>\ cat\ x.elv echo\ \[aq]executing\ x.elv\[aq] foo\ =\ bar ~>\ foo\ =\ \[aq]\[aq];\ \-source\ x.elv;\ echo\ $foo executing\ x.elv bar \f[] .fi .SS \-time .IP .nf \f[C] \-time\ $callable \f[] .fi .PP Run the callable, and write the time used to run it. Example: .IP .nf \f[C] ~>\ \-time\ {\ sleep\ 1\ } 1.006060647s \f[] .fi .PP When the callable also produces outputs, they are a bit tricky to separate from the output of \f[C]\-time\f[]. The easiest workaround is to redirect the output into a temporary file: .IP .nf \f[C] ~>\ f\ =\ (mktemp) ~>\ \-time\ {\ {\ echo\ output;\ sleep\ 1\ }\ >\ $f\ } 1.005589823s ~>\ cat\ $f output ~>\ rm\ $f \f[] .fi .SH Builtin Variables .SS $_ .PP A blackhole variable. .PP Values assigned to it will be discarded. Trying to use its value (like \f[C]put\ $_\f[]) causes an exception. .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[]: .IP .nf \f[C] ~>\ 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> \f[] .fi .PP $cf before\-chdir .SS $args .PP A list containing command\-line arguments. Analogous to \f[C]argv\f[] in some other languages. Examples: .IP .nf \f[C] ~>\ echo\ \[aq]put\ $args\[aq]\ >\ args.elv ~>\ elvish\ args.elv\ foo\ \-bar ▶\ [foo\ \-bar] ~>\ elvish\ \-c\ \[aq]put\ $args\[aq]\ foo\ \-bar ▶\ [foo\ \-bar] \f[] .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[] command. .PP $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 $cf after\-chdir .SS $false .PP The boolean false value. .SS $ok .PP The special value used by \f[C]?()\f[] to signal absence of exceptions. .SS $value\-out\-indicator .PP A string put before value outputs (such as those of of \f[C]put\f[]). Defaults to \f[C]\[aq]▶\ \[aq]\f[]. Example: .IP .nf \f[C] ~>\ put\ lorem\ ipsum ▶\ lorem ▶\ ipsum ~>\ value\-out\-indicator\ =\ \[aq]val>\ \[aq] ~>\ put\ lorem\ ipsum val>\ lorem val>\ ipsum \f[] .fi .PP Note that you almost always want some trailing whitespace for readability. .SS $paths .PP A list of search paths, kept in sync with \f[C]$E:PATH\f[]. It is easier to use than \f[C]$E:PATH\f[]. .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[]. This variable is most useful in temporary assignment. .PP Example: .IP .nf \f[C] ##\ Updates\ all\ git\ repositories for\ x\ [*/]\ { \ \ \ \ pwd=$x\ { \ \ \ \ \ \ \ \ if\ ?(test\ \-d\ .git)\ { \ \ \ \ \ \ \ \ \ \ \ \ git\ pull \ \ \ \ \ \ \ \ } \ \ \ \ } } \f[] .fi .PP Etymology: the \f[C]pwd\f[] command. .SS $true .PP The boolean true value.