OILS / doc / ref / chap-word-lang.md View on Github | oils.pub

299 lines, 183 significant
1---
2title: Word Language (Oils Reference)
3all_docs_url: ..
4body_css_class: width40
5default_highlighter: oils-sh
6preserve_anchor_case: yes
7---
8
9<div class="doc-ref-header">
10
11[Oils Reference](index.html) &mdash;
12Chapter **Word Language**
13
14</div>
15
16This chapter describes the word language for OSH and YSH. Words evaluate to
17strings, or arrays of strings.
18
19<span class="in-progress">(in progress)</span>
20
21<div id="dense-toc">
22</div>
23
24<h2 id="expression">Expressions to Words</h2>
25
26### expr-sub
27
28Try to turn an expression into a string. Examples:
29
30 $ echo $[3 * 2]
31 6
32
33 $ var s = 'foo'
34 $ echo $[s[1:]]
35 oo
36
37Some types can't be stringified, like Dict and List:
38
39 $ var d = {k: 42}
40
41 $ echo $[d]
42 fatal: expected Null, Bool, Int, Float, Eggex
43
44You can explicitly use `toJson8` or `toJson()`:
45
46 $ echo $[toJson8(d)]
47 {"k":42}
48
49(This is similar to `json write (d)`)
50
51### expr-splice
52
53Splicing puts the elements of a `List` into a string array context:
54
55 $ var foods = ['ale', 'bean', 'corn']
56 $ echo pizza @[foods[1:]] worm
57 pizza bean corn worm
58
59This syntax is enabled by `shopt --set` [parse_at][], which is part of YSH.
60
61[parse_at]: chap-option.html#ysh:upgrade
62
63### var-splice
64
65 $ var foods = ['ale', 'bean', 'corn']
66 echo @foods
67
68This syntax is enabled by `shopt --set` [parse_at][], which is part of YSH.
69
70
71<h2 id="formatting">Formatting Typed Data as Strings</h2>
72
73### ysh-printf
74
75Not done.
76
77 echo ${x %.3f}
78
79### ysh-format
80
81Not done.
82
83 echo ${x|html}
84
85## Quotes
86
87### osh-string
88
89- Single quotes
90- Double Quotes
91- C-style strings: `$'\n'`
92
93TODO: elaborate
94
95### ysh-string
96
97YSH strings in the word language are the same as in the expression language.
98
99See [ysh-string in chap-expr-lang](chap-expr-lang.html#ysh-string).
100
101### triple-quoted
102
103Triple-quoted in the word language are the same as in the expression language.
104
105See [triple-quoted in chap-expr-lang](chap-expr-lang.html#triple-quoted).
106
107### tagged-str
108
109Not done.
110
111## Substitutions
112
113### command-sub
114
115Executes a command and captures its stdout.
116
117OSH has shell-compatible command sub like `$(echo hi)`. If a trailing newline
118is returned, it's removed:
119
120 $ hostname
121 example.com
122
123 $ echo "/tmp/$(hostname)"
124 /tmp/example.com
125
126YSH has spliced command subs, enabled by `shopt --set parse_at`. The result is
127a **List** of strings, rather than a single string.
128
129 $ write -- @(echo foo; echo 'with spaces')
130 foo
131 with-spaces
132
133The command's stdout parsed as the "J8 Lines" format, where each line is
134either:
135
1361. An unquoted string, which must be valid UTF-8. Whitespace is allowed, but
137 not other ASCII control chars.
1382. A quoted J8 string (JSON style `""` or J8-style `b'' u'' ''`)
1393. An **ignored** empty line
140
141See [J8 Notation](../j8-notation.html) for more details.
142
143### var-sub
144
145Evaluates to the value of a variable:
146
147 $ x=X
148 $ echo $x ${x}
149 X X
150
151### arith-sub
152
153Shell has C-style arithmetic:
154
155 $ echo $(( 1 + 2*3 ))
156 7
157
158### tilde-sub
159
160Used as a shortcut for a user's home directory:
161
162 ~/src # my home dir
163 ~bob/src # user bob's home dir
164
165### proc-sub
166
167Open stdout as a named file in `/dev/fd`, which can be passed to a command:
168
169 diff <(sort L.txt) <(sort R.txt)
170
171Open stdin as a named file in `/dev/fd`:
172
173 seq 3 | tee >(sleep 1; tac)
174
175
176## Var Ops
177
178There are three types of braced variable expansions:
179
180 ${!name*} or ${!name@}
181 ${!name[@]} or ${!name[*]}
182 ${ops var ops}
183
184`name` needs to be a valid identifier. If the expansion matches the first
185form, the variable names starting with `name` are generated. Otherwise, if the
186expansion matches the second form, the keys of the indexed or associative array
187named `name` are generated. When the expansion does not much either the first
188or second forms, it is interpreted as the third form of the variable name
189surrounded by operators.
190
191
192### op-indirect
193
194The indirection operator `!` is a prefix operator, and it interprets the
195received string as a variable name `name`, an array element `name[key]`, or an
196arrat list `name[@]` / `name[*]` and reads its values.
197
198 $ a=1234
199 $ v=a
200 $ echo $v
201 a
202 $ echo ${!v}
203 1234
204
205### op-test
206
207Shell has boolean operations within `${}`. I use `:-` most frequently:
208
209 x=${1:-default}
210 osh=${OSH:-default}
211
212This idiom is also useful:
213
214 : ${LIB_OSH=stdlib/osh}
215
216### op-strip
217
218Remove prefixes or suffixes from strings:
219
220 echo ${y#prefix}
221 echo ${y##'prefix'}
222
223 echo ${y%suffix}
224 echo ${y%%'suffix'}
225
226The prefix and suffix can be glob patterns, but this usage is discouraged
227because it may be slow.
228
229### op-patsub
230
231Replace a substring or pattern.
232
233The character after the first `/` can be `/` to replace all occurrences:
234
235 $ x=food
236
237 $ echo ${x//o/--} # replace 1 o with 2 --
238 f----d
239
240It can be `#` or `%` for an anchored replacement:
241
242 $ echo ${x/#f/--} # left anchored f
243 --ood
244
245 $ echo ${x/%d/--} # right anchored d
246 foo--
247
248The pattern can also be a glob:
249
250 $ echo ${x//[a-z]/o} # replace 1 char with o
251 oooo
252
253 $ echo ${x//[a-z]+/o} # replace multiple chars
254 o
255
256### op-index
257
258 echo ${a[i+1]}
259
260### op-slice
261
262 echo ${a[@]:1:2}
263 echo ${@:1:2}
264
265### op-format
266
267${x@P} evaluates x as a prompt string, i.e. the string that would be printed if
268PS1=$x.
269
270---
271
272`${x@Q}` quotes the value of `x`, if necessary, so that it can be evaluated as
273a shell word.
274
275 $ x='<'
276 $ echo "value = $x, quoted = ${x@Q}."
277 value = <, quoted = '<'.
278
279 $ x=a
280 $ echo "value = $x, quoted = ${x@Q}."
281 value = a, quoted = a.
282
283In the second case, the string `a` doesn't need to be quoted.
284
285---
286
287Format operations like `@Q` generally treat **empty** variables differently
288than **unset** variables.
289
290That is, `${empty@Q}` is the string `''`, while `${unset@Q}` is an empty
291string:
292
293 $ x=''
294 $ echo "value = $x, quoted = ${x@Q}."
295 value = , quoted = ''.
296
297 $ unset -v x
298 $ echo "value = $x, quoted = ${x@Q}."
299 value = , quoted = .