1 #!/usr/bin/env bash
2
3 #### -A function prints functions
4 add () { expr 4 + 4; }
5 div () { expr 6 / 2; }
6 ek () { echo hello; }
7 __ec () { echo hi; }
8 _ab () { expr 10 % 3; }
9 compgen -A function
10 echo --
11 compgen -A function _
12 ## status: 0
13 ## STDOUT:
14 __ec
15 _ab
16 add
17 div
18 ek
19 --
20 __ec
21 _ab
22 ## END
23
24 #### Invalid syntax
25 compgen -A foo
26 echo status=$?
27 ## stdout: status=2
28
29 #### how compgen calls completion functions
30 foo_complete() {
31 # first, cur, prev
32 argv.py argv "$@"
33 argv.py COMP_WORDS "${COMP_WORDS[@]}"
34 argv.py COMP_CWORD "${COMP_CWORD}"
35 argv.py COMP_LINE "${COMP_LINE}"
36 argv.py COMP_POINT "${COMP_POINT}"
37 #return 124
38 COMPREPLY=(one two three)
39 }
40 compgen -F foo_complete foo a b c
41 ## STDOUT:
42 ['argv', 'compgen', 'foo', '']
43 ['COMP_WORDS']
44 ['COMP_CWORD', '-1']
45 ['COMP_LINE', '']
46 ['COMP_POINT', '0']
47 one
48 two
49 three
50 ## END
51
52 #### complete -o -F (git)
53 foo() { echo foo; }
54 wrapper=foo
55 complete -o default -o nospace -F $wrapper git
56 ## status: 0
57
58 #### compopt with invalid syntax
59 compopt -o invalid
60 echo status=$?
61 ## stdout: status=2
62
63 #### compopt fails when not in completion function
64 # NOTE: Have to be executing a completion function
65 compopt -o filenames +o nospace
66 ## status: 1
67
68 #### compgen -f on invalid dir
69 compgen -f /non-existing-dir/
70 ## status: 1
71 ## stdout-json: ""
72
73 #### compgen -f
74 mkdir -p $TMP/compgen
75 touch $TMP/compgen/{one,two,three}
76 cd $TMP/compgen
77 compgen -f | sort
78 echo --
79 compgen -f t | sort
80 ## STDOUT:
81 one
82 three
83 two
84 --
85 three
86 two
87 ## END
88
89 #### compgen -v with local vars
90 v1_global=0
91 f() {
92 local v2_local=0
93 compgen -v v
94 }
95 f
96 ## STDOUT:
97 v1_global
98 v2_local
99 ## END
100
101 #### compgen -v on unknown var
102 compgen -v __nonexistent__
103 ## status: 1
104 ## stdout-json: ""
105
106 #### compgen -v P
107 cd > /dev/null # for some reason in bash, this makes PIPESTATUS appear!
108 compgen -v P | grep -E '^PATH|PWD' | sort
109 ## STDOUT:
110 PATH
111 PWD
112 ## END
113
114 #### compgen with actions: function / variable / file
115 mkdir -p $TMP/compgen2
116 touch $TMP/compgen2/PA_FILE_{1,2}
117 cd $TMP/compgen2 # depends on previous test above!
118 PA_FUNC() { echo P; }
119 Q_FUNC() { echo Q; }
120 compgen -A function -A variable -A file PA
121 ## STDOUT:
122 PA_FUNC
123 PATH
124 PA_FILE_1
125 PA_FILE_2
126 ## END
127
128 #### compgen with actions: alias, setopt
129 alias v_alias='ls'
130 alias v_alias2='ls'
131 alias a1='ls'
132 compgen -A alias -A setopt v
133 ## STDOUT:
134 v_alias
135 v_alias2
136 verbose
137 vi
138 ## END
139
140 #### compgen with actions: shopt
141 compgen -A shopt -P [ -S ] nu
142 ## STDOUT:
143 [nullglob]
144 ## END
145
146 #### compgen with action and suffix: helptopic
147 compgen -A helptopic -S ___ fa
148 ## STDOUT:
149 false___
150 ## END
151
152 #### compgen -A directory
153 # omit portable-files.mk
154 compgen -A directory p
155 ## STDOUT:
156 pylib
157 ## END
158
159 #### compgen -A file
160 compgen -A file b
161 ## STDOUT:
162 bin
163 benchmarks
164 build
165 ## END
166
167 #### compgen -A user
168 # no assertion because this isn't hermetic
169 compgen -A user
170 ## status: 0
171
172 #### compgen -W 'one two three'
173 compgen -W 'one two three'
174 echo --
175 compgen -W 'w1 w2 three' -A directory w
176 echo --
177 compgen -A directory -W 'w1 w2 three' w # order doesn't matter
178 ## STDOUT:
179 one
180 two
181 three
182 --
183 web
184 w1
185 w2
186 --
187 web
188 w1
189 w2
190 ## END
191
192 #### compgen -A command completes external commands
193 # NOTE: this test isn't hermetic
194 compgen -A command xarg
195 echo status=$?
196 ## STDOUT:
197 xargs
198 status=0
199 ## END
200
201 #### compgen -A command completes functions and aliases
202 myfunc() { echo ; }
203 myfunc2() { echo ; }
204 alias myalias=foo
205 compgen -A command my
206 echo status=$?
207 ## STDOUT:
208 myalias
209 myfunc
210 myfunc2
211 status=0
212 ## END
213
214 #### compgen -A command completes builtins and keywords
215 compgen -A command eva
216 echo status=$?
217 compgen -A command whil
218 echo status=$?
219 ## STDOUT:
220 eval
221 status=0
222 while
223 status=0
224 ## END
225
226 #### complete with nonexistent function
227 complete -F invalidZZ -D
228 echo status=$?
229 ## stdout: status=2
230 ## BUG bash stdout: status=0
231
232 #### complete with no action
233 complete foo
234 echo status=$?
235 ## stdout: status=2
236 ## BUG bash stdout: status=0
237
238 #### -o filenames and -o nospace have no effect with compgen
239 # they are POSTPROCESSING.
240 compgen -o filenames -o nospace -W 'bin build'
241 ## STDOUT:
242 bin
243 build
244 ## END
245
246 #### -o plusdirs and -o dirnames with compgen
247 compgen -o plusdirs -W 'a b1 b2' b | sort
248 echo ---
249 compgen -o dirnames b | sort
250 ## STDOUT:
251 b1
252 b2
253 benchmarks
254 bin
255 build
256 ---
257 benchmarks
258 bin
259 build
260 ## END
261
262 #### compgen -o default completes files and dirs
263 compgen -o default p
264 ## STDOUT:
265 portable-rules.mk
266 pylib
267 ## END
268
269 #### compgen doesn't respect -X for user-defined functions
270 func() {
271 COMPREPLY=(one two three bin)
272 }
273 compgen -X '@(two|bin)' -F func
274 ## STDOUT:
275 one
276 two
277 three
278 bin
279 ## END
280
281 #### compgen doesn't respect -X with -W either
282 # this CHANGED between bash 4.3 and 4.4 apparently? That is odd. bash 4.4
283 # removed the filter.
284 compgen -X '@(two|bin)' -W 'one two three bin'
285 ## STDOUT:
286 one
287 two
288 three
289 bin
290 ## END