@@ -96,7 +96,7 @@ pub struct CompleteEnv<'s, F> {
96
96
shells : Shells < ' s > ,
97
97
}
98
98
99
- impl < ' s , F : FnOnce ( ) -> clap:: Command > CompleteEnv < ' s , F > {
99
+ impl < ' s , F : Fn ( ) -> clap:: Command > CompleteEnv < ' s , F > {
100
100
/// Complete a [`clap::Command`]
101
101
///
102
102
/// # Example
@@ -174,7 +174,7 @@ impl<'s, F: FnOnce() -> clap::Command> CompleteEnv<'s, F> {
174
174
}
175
175
}
176
176
177
- impl < ' s , F : FnOnce ( ) -> clap:: Command > CompleteEnv < ' s , F > {
177
+ impl < ' s , F : Fn ( ) -> clap:: Command > CompleteEnv < ' s , F > {
178
178
/// Process the completion request and exit
179
179
///
180
180
/// **Warning:** `stdout` should not be written to before this has had a
@@ -217,8 +217,34 @@ impl<'s, F: FnOnce() -> clap::Command> CompleteEnv<'s, F> {
217
217
// completion logic.
218
218
std:: env:: remove_var ( self . var ) ;
219
219
220
+ let shell = self . shell ( std:: path:: Path :: new ( & name) ) ?;
221
+
222
+ let mut cmd = ( self . factory ) ( ) ;
223
+ cmd. build ( ) ;
224
+
225
+ let completer = args. remove ( 0 ) ;
226
+ let escape_index = args
227
+ . iter ( )
228
+ . position ( |a| * a == "--" )
229
+ . map ( |i| i + 1 )
230
+ . unwrap_or ( args. len ( ) ) ;
231
+ args. drain ( 0 ..escape_index) ;
232
+ if args. is_empty ( ) {
233
+ let mut buf = Vec :: new ( ) ;
234
+ self . write_registration ( & cmd, current_dir, shell, completer, & mut buf) ?;
235
+ std:: io:: stdout ( ) . write_all ( & buf) ?;
236
+ } else {
237
+ let mut buf = Vec :: new ( ) ;
238
+ shell. write_complete ( & mut cmd, args, current_dir, & mut buf) ?;
239
+ std:: io:: stdout ( ) . write_all ( & buf) ?;
240
+ }
241
+
242
+ Ok ( true )
243
+ }
244
+
245
+ fn shell ( & self , name : & std:: path:: Path ) -> Result < & dyn EnvCompleter , std:: io:: Error > {
220
246
// Strip off the parent dir in case `$SHELL` was used
221
- let name = std :: path :: Path :: new ( & name) . file_stem ( ) . unwrap_or ( & name) ;
247
+ let name = name. file_stem ( ) . unwrap_or ( name. as_os_str ( ) ) ;
222
248
// lossy won't match but this will delegate to unknown
223
249
// error
224
250
let name = name. to_string_lossy ( ) ;
@@ -238,46 +264,38 @@ impl<'s, F: FnOnce() -> clap::Command> CompleteEnv<'s, F> {
238
264
format ! ( "unknown shell `{name}`, expected one of {shells}" ) ,
239
265
)
240
266
} ) ?;
267
+ Ok ( shell)
268
+ }
241
269
242
- let mut cmd = ( self . factory ) ( ) ;
243
- cmd. build ( ) ;
244
-
245
- let completer = args. remove ( 0 ) ;
246
- let escape_index = args
247
- . iter ( )
248
- . position ( |a| * a == "--" )
249
- . map ( |i| i + 1 )
250
- . unwrap_or ( args. len ( ) ) ;
251
- args. drain ( 0 ..escape_index) ;
252
- if args. is_empty ( ) {
253
- let name = cmd. get_name ( ) ;
254
- let bin = self
255
- . bin
256
- . as_deref ( )
257
- . or_else ( || cmd. get_bin_name ( ) )
258
- . unwrap_or_else ( || cmd. get_name ( ) ) ;
259
- let completer = if let Some ( completer) = self . completer . as_deref ( ) {
260
- completer. to_owned ( )
261
- } else {
262
- let mut completer = std:: path:: PathBuf :: from ( completer) ;
263
- if let Some ( current_dir) = current_dir {
264
- if 1 < completer. components ( ) . count ( ) {
265
- completer = current_dir. join ( completer) ;
266
- }
270
+ fn write_registration (
271
+ & self ,
272
+ cmd : & clap:: Command ,
273
+ current_dir : Option < & std:: path:: Path > ,
274
+ shell : & dyn EnvCompleter ,
275
+ completer : OsString ,
276
+ buf : & mut dyn std:: io:: Write ,
277
+ ) -> Result < ( ) , std:: io:: Error > {
278
+ let name = cmd. get_name ( ) ;
279
+ let bin = self
280
+ . bin
281
+ . as_deref ( )
282
+ . or_else ( || cmd. get_bin_name ( ) )
283
+ . unwrap_or_else ( || cmd. get_name ( ) ) ;
284
+ let completer = if let Some ( completer) = self . completer . as_deref ( ) {
285
+ completer. to_owned ( )
286
+ } else {
287
+ let mut completer = std:: path:: PathBuf :: from ( completer) ;
288
+ if let Some ( current_dir) = current_dir {
289
+ if 1 < completer. components ( ) . count ( ) {
290
+ completer = current_dir. join ( completer) ;
267
291
}
268
- completer. to_string_lossy ( ) . into_owned ( )
269
- } ;
292
+ }
293
+ completer. to_string_lossy ( ) . into_owned ( )
294
+ } ;
270
295
271
- let mut buf = Vec :: new ( ) ;
272
- shell. write_registration ( self . var , name, bin, & completer, & mut buf) ?;
273
- std:: io:: stdout ( ) . write_all ( & buf) ?;
274
- } else {
275
- let mut buf = Vec :: new ( ) ;
276
- shell. write_complete ( & mut cmd, args, current_dir, & mut buf) ?;
277
- std:: io:: stdout ( ) . write_all ( & buf) ?;
278
- }
296
+ shell. write_registration ( self . var , name, bin, & completer, buf) ?;
279
297
280
- Ok ( true )
298
+ Ok ( ( ) )
281
299
}
282
300
}
283
301
0 commit comments