@@ -157,93 +157,7 @@ fn complete_arg(
157
157
{
158
158
completions. extend ( complete_arg_value ( arg. to_value ( ) , positional, current_dir) ) ;
159
159
}
160
-
161
- if arg. is_empty ( ) {
162
- completions. extend ( longs_and_visible_aliases ( cmd) ) ;
163
- completions. extend ( hidden_longs_aliases ( cmd) ) ;
164
-
165
- let dash_or_arg = if arg. is_empty ( ) {
166
- "-" . into ( )
167
- } else {
168
- arg. to_value_os ( ) . to_string_lossy ( )
169
- } ;
170
- completions. extend (
171
- shorts_and_visible_aliases ( cmd)
172
- . into_iter ( )
173
- . map ( |comp| comp. add_prefix ( dash_or_arg. to_string ( ) ) ) ,
174
- ) ;
175
- } else if arg. is_stdio ( ) {
176
- // HACK: Assuming knowledge of is_stdio
177
- let dash_or_arg = if arg. is_empty ( ) {
178
- "-" . into ( )
179
- } else {
180
- arg. to_value_os ( ) . to_string_lossy ( )
181
- } ;
182
- completions. extend (
183
- shorts_and_visible_aliases ( cmd)
184
- . into_iter ( )
185
- . map ( |comp| comp. add_prefix ( dash_or_arg. to_string ( ) ) ) ,
186
- ) ;
187
-
188
- completions. extend ( longs_and_visible_aliases ( cmd) ) ;
189
- completions. extend ( hidden_longs_aliases ( cmd) ) ;
190
- } else if arg. is_escape ( ) {
191
- // HACK: Assuming knowledge of is_escape
192
- completions. extend ( longs_and_visible_aliases ( cmd) ) ;
193
- completions. extend ( hidden_longs_aliases ( cmd) ) ;
194
- } else if let Some ( ( flag, value) ) = arg. to_long ( ) {
195
- if let Ok ( flag) = flag {
196
- if let Some ( value) = value {
197
- if let Some ( arg) = cmd. get_arguments ( ) . find ( |a| a. get_long ( ) == Some ( flag) )
198
- {
199
- completions. extend (
200
- complete_arg_value ( value. to_str ( ) . ok_or ( value) , arg, current_dir)
201
- . into_iter ( )
202
- . map ( |comp| comp. add_prefix ( format ! ( "--{flag}=" ) ) ) ,
203
- ) ;
204
- }
205
- } else {
206
- completions. extend ( longs_and_visible_aliases ( cmd) . into_iter ( ) . filter (
207
- |comp| comp. get_value ( ) . starts_with ( format ! ( "--{flag}" ) . as_str ( ) ) ,
208
- ) ) ;
209
- completions. extend ( hidden_longs_aliases ( cmd) . into_iter ( ) . filter ( |comp| {
210
- comp. get_value ( ) . starts_with ( format ! ( "--{flag}" ) . as_str ( ) )
211
- } ) ) ;
212
- }
213
- }
214
- } else if let Some ( short) = arg. to_short ( ) {
215
- if !short. is_negative_number ( ) {
216
- // Find the first takes_values option.
217
- let ( leading_flags, takes_value_opt, mut short) = parse_shortflags ( cmd, short) ;
218
-
219
- // Clone `short` to `peek_short` to peek whether the next flag is a `=`.
220
- if let Some ( opt) = takes_value_opt {
221
- let mut peek_short = short. clone ( ) ;
222
- let has_equal = if let Some ( Ok ( '=' ) ) = peek_short. next_flag ( ) {
223
- short. next_flag ( ) ;
224
- true
225
- } else {
226
- false
227
- } ;
228
-
229
- let value = short. next_value_os ( ) . unwrap_or ( OsStr :: new ( "" ) ) ;
230
- completions. extend (
231
- complete_arg_value ( value. to_str ( ) . ok_or ( value) , opt, current_dir)
232
- . into_iter ( )
233
- . map ( |comp| {
234
- let sep = if has_equal { "=" } else { "" } ;
235
- comp. add_prefix ( format ! ( "-{leading_flags}{sep}" ) )
236
- } ) ,
237
- ) ;
238
- } else {
239
- completions. extend (
240
- shorts_and_visible_aliases ( cmd)
241
- . into_iter ( )
242
- . map ( |comp| comp. add_prefix ( format ! ( "-{leading_flags}" ) ) ) ,
243
- ) ;
244
- }
245
- }
246
- }
160
+ completions. extend ( complete_option ( arg, cmd, current_dir) ) ;
247
161
}
248
162
ParseState :: Pos ( ..) => {
249
163
if let Some ( positional) = cmd
@@ -297,6 +211,104 @@ fn complete_arg(
297
211
Ok ( completions)
298
212
}
299
213
214
+ fn complete_option (
215
+ arg : & clap_lex:: ParsedArg < ' _ > ,
216
+ cmd : & clap:: Command ,
217
+ current_dir : Option < & std:: path:: Path > ,
218
+ ) -> Vec < CompletionCandidate > {
219
+ let mut completions = Vec :: < CompletionCandidate > :: new ( ) ;
220
+ if arg. is_empty ( ) {
221
+ completions. extend ( longs_and_visible_aliases ( cmd) ) ;
222
+ completions. extend ( hidden_longs_aliases ( cmd) ) ;
223
+
224
+ let dash_or_arg = if arg. is_empty ( ) {
225
+ "-" . into ( )
226
+ } else {
227
+ arg. to_value_os ( ) . to_string_lossy ( )
228
+ } ;
229
+ completions. extend (
230
+ shorts_and_visible_aliases ( cmd)
231
+ . into_iter ( )
232
+ . map ( |comp| comp. add_prefix ( dash_or_arg. to_string ( ) ) ) ,
233
+ ) ;
234
+ } else if arg. is_stdio ( ) {
235
+ // HACK: Assuming knowledge of is_stdio
236
+ let dash_or_arg = if arg. is_empty ( ) {
237
+ "-" . into ( )
238
+ } else {
239
+ arg. to_value_os ( ) . to_string_lossy ( )
240
+ } ;
241
+ completions. extend (
242
+ shorts_and_visible_aliases ( cmd)
243
+ . into_iter ( )
244
+ . map ( |comp| comp. add_prefix ( dash_or_arg. to_string ( ) ) ) ,
245
+ ) ;
246
+
247
+ completions. extend ( longs_and_visible_aliases ( cmd) ) ;
248
+ completions. extend ( hidden_longs_aliases ( cmd) ) ;
249
+ } else if arg. is_escape ( ) {
250
+ // HACK: Assuming knowledge of is_escape
251
+ completions. extend ( longs_and_visible_aliases ( cmd) ) ;
252
+ completions. extend ( hidden_longs_aliases ( cmd) ) ;
253
+ } else if let Some ( ( flag, value) ) = arg. to_long ( ) {
254
+ if let Ok ( flag) = flag {
255
+ if let Some ( value) = value {
256
+ if let Some ( arg) = cmd. get_arguments ( ) . find ( |a| a. get_long ( ) == Some ( flag) ) {
257
+ completions. extend (
258
+ complete_arg_value ( value. to_str ( ) . ok_or ( value) , arg, current_dir)
259
+ . into_iter ( )
260
+ . map ( |comp| comp. add_prefix ( format ! ( "--{flag}=" ) ) ) ,
261
+ ) ;
262
+ }
263
+ } else {
264
+ completions. extend (
265
+ longs_and_visible_aliases ( cmd)
266
+ . into_iter ( )
267
+ . filter ( |comp| comp. get_value ( ) . starts_with ( format ! ( "--{flag}" ) . as_str ( ) ) ) ,
268
+ ) ;
269
+ completions. extend (
270
+ hidden_longs_aliases ( cmd)
271
+ . into_iter ( )
272
+ . filter ( |comp| comp. get_value ( ) . starts_with ( format ! ( "--{flag}" ) . as_str ( ) ) ) ,
273
+ ) ;
274
+ }
275
+ }
276
+ } else if let Some ( short) = arg. to_short ( ) {
277
+ if !short. is_negative_number ( ) {
278
+ // Find the first takes_values option.
279
+ let ( leading_flags, takes_value_opt, mut short) = parse_shortflags ( cmd, short) ;
280
+
281
+ // Clone `short` to `peek_short` to peek whether the next flag is a `=`.
282
+ if let Some ( opt) = takes_value_opt {
283
+ let mut peek_short = short. clone ( ) ;
284
+ let has_equal = if let Some ( Ok ( '=' ) ) = peek_short. next_flag ( ) {
285
+ short. next_flag ( ) ;
286
+ true
287
+ } else {
288
+ false
289
+ } ;
290
+
291
+ let value = short. next_value_os ( ) . unwrap_or ( OsStr :: new ( "" ) ) ;
292
+ completions. extend (
293
+ complete_arg_value ( value. to_str ( ) . ok_or ( value) , opt, current_dir)
294
+ . into_iter ( )
295
+ . map ( |comp| {
296
+ let sep = if has_equal { "=" } else { "" } ;
297
+ comp. add_prefix ( format ! ( "-{leading_flags}{sep}" ) )
298
+ } ) ,
299
+ ) ;
300
+ } else {
301
+ completions. extend (
302
+ shorts_and_visible_aliases ( cmd)
303
+ . into_iter ( )
304
+ . map ( |comp| comp. add_prefix ( format ! ( "-{leading_flags}" ) ) ) ,
305
+ ) ;
306
+ }
307
+ }
308
+ }
309
+ completions
310
+ }
311
+
300
312
fn complete_arg_value (
301
313
value : Result < & str , & OsStr > ,
302
314
arg : & clap:: Arg ,
0 commit comments