1 |
## oils_failures_allowed: 3
|
2 |
## compare_shells: bash
|
3 |
|
4 |
|
5 |
|
6 |
set -e
|
7 |
|
8 |
complete
|
9 |
|
10 |
complete -W 'foo bar' mycommand
|
11 |
|
12 |
complete -p
|
13 |
|
14 |
complete -F myfunc other
|
15 |
|
16 |
complete
|
17 |
|
18 |
## STDOUT:
|
19 |
complete -W 'foo bar' mycommand
|
20 |
complete -W 'foo bar' mycommand
|
21 |
complete -F myfunc other
|
22 |
## END
|
23 |
|
24 |
|
25 |
|
26 |
#complete -F f cmd
|
27 |
|
28 |
# Alias for complete -p
|
29 |
complete > /dev/null # ignore OSH output for now
|
30 |
echo status=$?
|
31 |
|
32 |
# But this is an error
|
33 |
complete -F f
|
34 |
echo status=$?
|
35 |
|
36 |
## STDOUT:
|
37 |
status=0
|
38 |
status=2
|
39 |
## END
|
40 |
|
41 |
|
42 |
complete -F invalidZZ -D
|
43 |
echo status=$?
|
44 |
## stdout: status=2
|
45 |
## BUG bash stdout: status=0
|
46 |
|
47 |
|
48 |
complete foo
|
49 |
echo status=$?
|
50 |
## stdout: status=2
|
51 |
## BUG bash stdout: status=0
|
52 |
|
53 |
|
54 |
add () { expr 4 + 4; }
|
55 |
div () { expr 6 / 2; }
|
56 |
ek () { echo hello; }
|
57 |
__ec () { echo hi; }
|
58 |
_ab () { expr 10 % 3; }
|
59 |
compgen -A function
|
60 |
echo --
|
61 |
compgen -A function _
|
62 |
## status: 0
|
63 |
## STDOUT:
|
64 |
__ec
|
65 |
_ab
|
66 |
add
|
67 |
div
|
68 |
ek
|
69 |
--
|
70 |
__ec
|
71 |
_ab
|
72 |
## END
|
73 |
|
74 |
|
75 |
compgen -A foo
|
76 |
echo status=$?
|
77 |
## stdout: status=2
|
78 |
|
79 |
|
80 |
foo_complete() {
|
81 |
# first, cur, prev
|
82 |
argv.py argv "$@"
|
83 |
argv.py COMP_WORDS "${COMP_WORDS[@]}"
|
84 |
argv.py COMP_CWORD "${COMP_CWORD}"
|
85 |
argv.py COMP_LINE "${COMP_LINE}"
|
86 |
argv.py COMP_POINT "${COMP_POINT}"
|
87 |
#return 124
|
88 |
COMPREPLY=(one two three)
|
89 |
}
|
90 |
compgen -F foo_complete foo a b c
|
91 |
## STDOUT:
|
92 |
['argv', 'compgen', 'foo', '']
|
93 |
['COMP_WORDS']
|
94 |
['COMP_CWORD', '-1']
|
95 |
['COMP_LINE', '']
|
96 |
['COMP_POINT', '0']
|
97 |
one
|
98 |
two
|
99 |
three
|
100 |
## END
|
101 |
|
102 |
|
103 |
foo() { echo foo; }
|
104 |
wrapper=foo
|
105 |
complete -o default -o nospace -F $wrapper git
|
106 |
## status: 0
|
107 |
|
108 |
|
109 |
compopt -o invalid
|
110 |
echo status=$?
|
111 |
## stdout: status=2
|
112 |
|
113 |
|
114 |
# NOTE: Have to be executing a completion function
|
115 |
compopt -o filenames +o nospace
|
116 |
## status: 1
|
117 |
|
118 |
|
119 |
compgen -f /non-existing-dir/
|
120 |
## status: 1
|
121 |
## stdout-json: ""
|
122 |
|
123 |
|
124 |
mkdir -p $TMP/compgen
|
125 |
touch $TMP/compgen/{one,two,three}
|
126 |
cd $TMP/compgen
|
127 |
compgen -f | sort
|
128 |
echo --
|
129 |
compgen -f t | sort
|
130 |
## STDOUT:
|
131 |
one
|
132 |
three
|
133 |
two
|
134 |
--
|
135 |
three
|
136 |
two
|
137 |
## END
|
138 |
|
139 |
|
140 |
v1_global=0
|
141 |
f() {
|
142 |
local v2_local=0
|
143 |
compgen -v v
|
144 |
}
|
145 |
f
|
146 |
## STDOUT:
|
147 |
v1_global
|
148 |
v2_local
|
149 |
## END
|
150 |
|
151 |
|
152 |
compgen -v __nonexistent__
|
153 |
## status: 1
|
154 |
## stdout-json: ""
|
155 |
|
156 |
|
157 |
cd > /dev/null # for some reason in bash, this makes PIPESTATUS appear!
|
158 |
compgen -v P | grep -E '^PATH|PWD' | sort
|
159 |
## STDOUT:
|
160 |
PATH
|
161 |
PWD
|
162 |
## END
|
163 |
|
164 |
|
165 |
export v1_global=0
|
166 |
f() {
|
167 |
local v2_local=0
|
168 |
export v2_local
|
169 |
compgen -e v
|
170 |
}
|
171 |
f
|
172 |
## STDOUT:
|
173 |
v1_global
|
174 |
v2_local
|
175 |
## END
|
176 |
|
177 |
|
178 |
unexported=0
|
179 |
compgen -e unexported
|
180 |
## status: 1
|
181 |
## stdout-json: ""
|
182 |
|
183 |
|
184 |
compgen -e __nonexistent__
|
185 |
## status: 1
|
186 |
## stdout-json: ""
|
187 |
|
188 |
|
189 |
cd > /dev/null # for some reason in bash, this makes PIPESTATUS appear!
|
190 |
compgen -e P | grep -E '^PATH|PWD' | sort
|
191 |
## STDOUT:
|
192 |
PATH
|
193 |
PWD
|
194 |
## END
|
195 |
|
196 |
|
197 |
mkdir -p $TMP/compgen2
|
198 |
touch $TMP/compgen2/{PA,Q}_FILE
|
199 |
cd $TMP/compgen2 # depends on previous test above!
|
200 |
PA_FUNC() { echo P; }
|
201 |
Q_FUNC() { echo Q; }
|
202 |
compgen -A function -A variable -A file PA
|
203 |
## STDOUT:
|
204 |
PA_FUNC
|
205 |
PATH
|
206 |
PA_FILE
|
207 |
## END
|
208 |
|
209 |
|
210 |
alias v_alias='ls'
|
211 |
alias v_alias2='ls'
|
212 |
alias a1='ls'
|
213 |
compgen -A alias -A setopt v
|
214 |
## STDOUT:
|
215 |
v_alias
|
216 |
v_alias2
|
217 |
verbose
|
218 |
vi
|
219 |
## END
|
220 |
|
221 |
|
222 |
compgen -A shopt -P [ -S ] nu
|
223 |
## STDOUT:
|
224 |
[nullglob]
|
225 |
## END
|
226 |
|
227 |
|
228 |
compgen -A helptopic -S ___ fal
|
229 |
## STDOUT:
|
230 |
false___
|
231 |
## END
|
232 |
|
233 |
|
234 |
cd $REPO_ROOT
|
235 |
compgen -A directory c | sort
|
236 |
## STDOUT:
|
237 |
client
|
238 |
core
|
239 |
cpp
|
240 |
## END
|
241 |
|
242 |
|
243 |
cd $REPO_ROOT
|
244 |
compgen -A file o | sort
|
245 |
## STDOUT:
|
246 |
oil-version.txt
|
247 |
opy
|
248 |
osh
|
249 |
## END
|
250 |
|
251 |
|
252 |
# no assertion because this isn't hermetic
|
253 |
compgen -A user
|
254 |
## status: 0
|
255 |
|
256 |
|
257 |
# NOTE: this test isn't hermetic
|
258 |
compgen -A command xarg | uniq
|
259 |
echo status=$?
|
260 |
## STDOUT:
|
261 |
xargs
|
262 |
status=0
|
263 |
## END
|
264 |
|
265 |
|
266 |
our_func() { echo ; }
|
267 |
our_func2() { echo ; }
|
268 |
alias our_alias=foo
|
269 |
|
270 |
compgen -A command our_
|
271 |
echo status=$?
|
272 |
|
273 |
# Introduce another function. Note that we're missing test coverage for
|
274 |
# 'complete', i.e. bug #1064.
|
275 |
our_func3() { echo ; }
|
276 |
|
277 |
compgen -A command our_
|
278 |
echo status=$?
|
279 |
|
280 |
## STDOUT:
|
281 |
our_alias
|
282 |
our_func
|
283 |
our_func2
|
284 |
status=0
|
285 |
our_alias
|
286 |
our_func
|
287 |
our_func2
|
288 |
our_func3
|
289 |
status=0
|
290 |
## END
|
291 |
|
292 |
|
293 |
compgen -A command eva
|
294 |
echo status=$?
|
295 |
compgen -A command whil
|
296 |
echo status=$?
|
297 |
## STDOUT:
|
298 |
eval
|
299 |
status=0
|
300 |
while
|
301 |
status=0
|
302 |
## END
|
303 |
|
304 |
|
305 |
|
306 |
# bash adds ]] and } and coproc
|
307 |
|
308 |
# Use bash as an oracle
|
309 |
bash -c 'compgen -k' | sort > bash.txt
|
310 |
|
311 |
# osh vs. bash, or bash vs. bash
|
312 |
$SH -c 'compgen -k' | sort > this-shell.txt
|
313 |
|
314 |
#comm bash.txt this-shell.txt
|
315 |
|
316 |
# show lines in both files
|
317 |
comm -12 bash.txt this-shell.txt | egrep -v 'coproc|select'
|
318 |
|
319 |
## STDOUT:
|
320 |
!
|
321 |
[[
|
322 |
]]
|
323 |
case
|
324 |
do
|
325 |
done
|
326 |
elif
|
327 |
else
|
328 |
esac
|
329 |
fi
|
330 |
for
|
331 |
function
|
332 |
if
|
333 |
in
|
334 |
then
|
335 |
time
|
336 |
until
|
337 |
while
|
338 |
{
|
339 |
}
|
340 |
## END
|
341 |
|
342 |
|
343 |
|
344 |
# YSH has a superset of keywords:
|
345 |
# const var
|
346 |
# setvar setglobal
|
347 |
# proc func typed
|
348 |
# call = # hm = is not here
|
349 |
|
350 |
compgen -k | sort | egrep '^(const|var|setvar|setglobal|proc|func|typed|call|=)$'
|
351 |
echo --
|
352 |
|
353 |
## STDOUT:
|
354 |
=
|
355 |
call
|
356 |
const
|
357 |
func
|
358 |
proc
|
359 |
setglobal
|
360 |
setvar
|
361 |
typed
|
362 |
var
|
363 |
--
|
364 |
## END
|
365 |
|
366 |
## N-I bash STDOUT:
|
367 |
--
|
368 |
## END
|
369 |
|
370 |
|
371 |
compgen -k do | sort
|
372 |
echo status=$?
|
373 |
compgen -k el | sort
|
374 |
echo status=$?
|
375 |
## STDOUT:
|
376 |
do
|
377 |
done
|
378 |
status=0
|
379 |
elif
|
380 |
else
|
381 |
status=0
|
382 |
## END
|
383 |
|
384 |
|
385 |
# they are POSTPROCESSING.
|
386 |
compgen -o filenames -o nospace -W 'bin build'
|
387 |
## STDOUT:
|
388 |
bin
|
389 |
build
|
390 |
## END
|
391 |
|
392 |
|
393 |
cd $REPO_ROOT
|
394 |
compgen -o plusdirs -W 'a b1 b2' b | sort
|
395 |
echo ---
|
396 |
compgen -o dirnames b | sort
|
397 |
## STDOUT:
|
398 |
b1
|
399 |
b2
|
400 |
benchmarks
|
401 |
bin
|
402 |
build
|
403 |
builtin
|
404 |
---
|
405 |
benchmarks
|
406 |
bin
|
407 |
build
|
408 |
builtin
|
409 |
## END
|
410 |
|
411 |
|
412 |
cd $REPO_ROOT
|
413 |
compgen -o default spec/t | sort
|
414 |
## STDOUT:
|
415 |
spec/testdata
|
416 |
spec/tilde.test.sh
|
417 |
spec/toysh-posix.test.sh
|
418 |
spec/toysh.test.sh
|
419 |
spec/type-compat.test.sh
|
420 |
## END
|
421 |
|
422 |
|
423 |
# WORKAROUND: wrap in bash -i -c because non-interactive bash behaves
|
424 |
# differently!
|
425 |
case $SH in
|
426 |
*bash|*osh)
|
427 |
$SH --rcfile /dev/null -i -c '
|
428 |
shopt -s extglob
|
429 |
fun() {
|
430 |
COMPREPLY=(one two three bin)
|
431 |
}
|
432 |
compgen -X "@(two|bin)" -F fun
|
433 |
echo --
|
434 |
compgen -X "!@(two|bin)" -F fun
|
435 |
'
|
436 |
esac
|
437 |
## STDOUT:
|
438 |
one
|
439 |
three
|
440 |
--
|
441 |
two
|
442 |
bin
|
443 |
## END
|
444 |
|
445 |
|
446 |
# WORKAROUND: wrap in bash -i -c because non-interactive bash behaves
|
447 |
# differently!
|
448 |
case $SH in
|
449 |
*bash|*osh)
|
450 |
$SH --rcfile /dev/null -i -c 'shopt -s extglob; compgen -X "@(two|bin)" -W "one two three bin"'
|
451 |
esac
|
452 |
## STDOUT:
|
453 |
one
|
454 |
three
|
455 |
## END
|
456 |
|
457 |
|
458 |
cd $TMP
|
459 |
touch spam.py spam.sh
|
460 |
compgen -f -- sp | sort
|
461 |
echo --
|
462 |
# WORKAROUND: wrap in bash -i -c because non-interactive bash behaves
|
463 |
# differently!
|
464 |
case $SH in
|
465 |
*bash|*osh)
|
466 |
$SH --rcfile /dev/null -i -c 'shopt -s extglob; compgen -f -X "!*.@(py)" -- sp'
|
467 |
esac
|
468 |
## STDOUT:
|
469 |
spam.py
|
470 |
spam.sh
|
471 |
--
|
472 |
spam.py
|
473 |
## END
|
474 |
|
475 |
|
476 |
# There is an obsolete comment in bash_completion that claims the opposite.
|
477 |
cd $TMP
|
478 |
touch 'foo bar'
|
479 |
touch "foo'bar"
|
480 |
compgen -f "foo b"
|
481 |
compgen -f "foo'"
|
482 |
## STDOUT:
|
483 |
foo bar
|
484 |
foo'bar
|
485 |
## END
|
486 |
|
487 |
|
488 |
cd $REPO_ROOT
|
489 |
compgen -W 'one two three'
|
490 |
echo --
|
491 |
compgen -W 'w1 w2 three' -A directory w
|
492 |
echo --
|
493 |
compgen -A directory -W 'w1 w2 three' w # order doesn't matter
|
494 |
## STDOUT:
|
495 |
one
|
496 |
two
|
497 |
three
|
498 |
--
|
499 |
web
|
500 |
w1
|
501 |
w2
|
502 |
--
|
503 |
web
|
504 |
w1
|
505 |
w2
|
506 |
## END
|
507 |
|
508 |
|
509 |
IFS=':%'
|
510 |
compgen -W '$(echo "spam:eggs%ham cheese")'
|
511 |
## STDOUT:
|
512 |
spam
|
513 |
eggs
|
514 |
ham cheese
|
515 |
## END
|
516 |
|
517 |
|
518 |
IFS=':%'
|
519 |
compgen -W 'spam:eggs%ham cheese\:colon'
|
520 |
## STDOUT:
|
521 |
spam
|
522 |
eggs
|
523 |
ham cheese:colon
|
524 |
## END
|
525 |
|
526 |
|
527 |
# bash doesn't detect as many errors because it lacks static parsing.
|
528 |
compgen -W '${'
|
529 |
echo status=$?
|
530 |
complete -W '${' foo
|
531 |
echo status=$?
|
532 |
## STDOUT:
|
533 |
status=2
|
534 |
status=2
|
535 |
## END
|
536 |
## BUG bash STDOUT:
|
537 |
status=1
|
538 |
status=0
|
539 |
## END
|
540 |
|
541 |
|
542 |
compgen -W 'foo $(( 1 / 0 )) bar'
|
543 |
echo status=$?
|
544 |
## STDOUT:
|
545 |
status=1
|
546 |
## END
|
547 |
|
548 |
|
549 |
_foo() {
|
550 |
COMPREPLY=( foo bar )
|
551 |
COMPREPLY+=( $(( 1 / 0 )) ) # FATAL, but we still have candidates
|
552 |
}
|
553 |
compgen -F _foo foo
|
554 |
echo status=$?
|
555 |
## STDOUT:
|
556 |
status=1
|
557 |
## END
|
558 |
|
559 |
|
560 |
# Bug fix due to '' being falsey in Python
|
561 |
compgen -W '' -- foo
|
562 |
echo status=$?
|
563 |
## stdout: status=1
|
564 |
|
565 |
|
566 |
compgen -A builtin g
|
567 |
## STDOUT:
|
568 |
getopts
|
569 |
## END
|
570 |
|
571 |
|
572 |
|
573 |
f() { echo foo; echo bar; }
|
574 |
|
575 |
# Bash prints warnings: -C option may not work as you expect
|
576 |
# -F option may not work as you expect
|
577 |
#
|
578 |
# https://unix.stackexchange.com/questions/117987/compgen-warning-c-option-not-working-as-i-expected
|
579 |
#
|
580 |
# compexport fixes this problem, because it invokves ShellFuncAction, whcih
|
581 |
# sets COMP_ARGV, COMP_WORDS, etc.
|
582 |
#
|
583 |
# Should we print a warning?
|
584 |
|
585 |
compgen -C f b
|
586 |
echo compgen=$?
|
587 |
|
588 |
complete -C f b
|
589 |
echo complete=$?
|
590 |
|
591 |
## STDOUT:
|
592 |
foo
|
593 |
bar
|
594 |
compgen=0
|
595 |
complete=0
|
596 |
## END
|