@@ -198,6 +198,7 @@ protected function writeError(OutputInterface $output, \Exception $error)
198
198
*/
199
199
private function autocomplete (OutputInterface $ output , Question $ question , $ inputStream , callable $ autocomplete ): string
200
200
{
201
+ $ fullChoice = '' ;
201
202
$ ret = '' ;
202
203
203
204
$ i = 0 ;
@@ -224,6 +225,7 @@ private function autocomplete(OutputInterface $output, Question $question, $inpu
224
225
} elseif ("\177" === $ c ) { // Backspace Character
225
226
if (0 === $ numMatches && 0 !== $ i ) {
226
227
--$ i ;
228
+ $ fullChoice = substr ($ fullChoice , 0 , -1 );
227
229
// Move cursor backwards
228
230
$ output ->write ("\033[1D " );
229
231
}
@@ -260,8 +262,10 @@ private function autocomplete(OutputInterface $output, Question $question, $inpu
260
262
if ($ numMatches > 0 && -1 !== $ ofs ) {
261
263
$ ret = (string ) $ matches [$ ofs ];
262
264
// Echo out remaining chars for current match
263
- $ output ->write (substr ($ ret , $ i ));
264
- $ i = \strlen ($ ret );
265
+ $ remainingCharacters = substr ($ ret , \strlen (trim ($ this ->mostRecentlyEnteredValue ($ fullChoice ))));
266
+ $ output ->write ($ remainingCharacters );
267
+ $ fullChoice .= $ remainingCharacters ;
268
+ $ i = \strlen ($ fullChoice );
265
269
266
270
$ matches = array_filter (
267
271
$ autocomplete ($ ret ),
@@ -287,14 +291,21 @@ function ($match) use ($ret) {
287
291
288
292
$ output ->write ($ c );
289
293
$ ret .= $ c ;
294
+ $ fullChoice .= $ c ;
290
295
++$ i ;
291
296
297
+ $ tempRet = $ ret ;
298
+
299
+ if ($ question instanceof ChoiceQuestion && $ question ->isMultiselect ()) {
300
+ $ tempRet = $ this ->mostRecentlyEnteredValue ($ fullChoice );
301
+ }
302
+
292
303
$ numMatches = 0 ;
293
304
$ ofs = 0 ;
294
305
295
306
foreach ($ autocomplete ($ ret ) as $ value ) {
296
307
// If typed characters match the beginning chunk of value (e.g. [AcmeDe]moBundle)
297
- if (0 === strpos ($ value , $ ret )) {
308
+ if (0 === strpos ($ value , $ tempRet )) {
298
309
$ matches [$ numMatches ++] = $ value ;
299
310
}
300
311
}
@@ -306,8 +317,9 @@ function ($match) use ($ret) {
306
317
if ($ numMatches > 0 && -1 !== $ ofs ) {
307
318
// Save cursor position
308
319
$ output ->write ("\0337 " );
309
- // Write highlighted text
310
- $ output ->write ('<hl> ' .OutputFormatter::escapeTrailingBackslash (substr ($ matches [$ ofs ], $ i )).'</hl> ' );
320
+ // Write highlighted text, complete the partially entered response
321
+ $ charactersEntered = \strlen (trim ($ this ->mostRecentlyEnteredValue ($ fullChoice )));
322
+ $ output ->write ('<hl> ' .OutputFormatter::escapeTrailingBackslash (substr ($ matches [$ ofs ], $ charactersEntered )).'</hl> ' );
311
323
// Restore cursor position
312
324
$ output ->write ("\0338 " );
313
325
}
@@ -316,7 +328,24 @@ function ($match) use ($ret) {
316
328
// Reset stty so it behaves normally again
317
329
shell_exec (sprintf ('stty %s ' , $ sttyMode ));
318
330
319
- return $ ret ;
331
+ return $ fullChoice ;
332
+ }
333
+
334
+ private function mostRecentlyEnteredValue ($ entered )
335
+ {
336
+ $ tempEntered = $ entered ;
337
+
338
+ // Determine the most recent value that the user entered
339
+ if (false !== strpos ($ entered , ', ' )) {
340
+ $ choices = explode (', ' , $ entered );
341
+ $ lastChoice = trim ($ choices [\count ($ choices ) - 1 ]);
342
+
343
+ if (\strlen ($ lastChoice ) > 0 ) {
344
+ $ tempEntered = $ lastChoice ;
345
+ }
346
+ }
347
+
348
+ return $ tempEntered ;
320
349
}
321
350
322
351
/**
0 commit comments