@@ -198,6 +198,7 @@ protected function writeError(OutputInterface $output, \Exception $error)
198198 */
199199 private function autocomplete (OutputInterface $ output , Question $ question , $ inputStream , callable $ autocomplete ): string
200200 {
201+ $ fullChoice = '' ;
201202 $ ret = '' ;
202203
203204 $ i = 0 ;
@@ -224,6 +225,7 @@ private function autocomplete(OutputInterface $output, Question $question, $inpu
224225 } elseif ("\177" === $ c ) { // Backspace Character
225226 if (0 === $ numMatches && 0 !== $ i ) {
226227 --$ i ;
228+ $ fullChoice = substr ($ fullChoice , 0 , -1 );
227229 // Move cursor backwards
228230 $ output ->write ("\033[1D " );
229231 }
@@ -260,8 +262,10 @@ private function autocomplete(OutputInterface $output, Question $question, $inpu
260262 if ($ numMatches > 0 && -1 !== $ ofs ) {
261263 $ ret = (string ) $ matches [$ ofs ];
262264 // 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 );
265269
266270 $ matches = array_filter (
267271 $ autocomplete ($ ret ),
@@ -287,14 +291,21 @@ function ($match) use ($ret) {
287291
288292 $ output ->write ($ c );
289293 $ ret .= $ c ;
294+ $ fullChoice .= $ c ;
290295 ++$ i ;
291296
297+ $ tempRet = $ ret ;
298+
299+ if ($ question instanceof ChoiceQuestion && $ question ->isMultiselect ()) {
300+ $ tempRet = $ this ->mostRecentlyEnteredValue ($ fullChoice );
301+ }
302+
292303 $ numMatches = 0 ;
293304 $ ofs = 0 ;
294305
295306 foreach ($ autocomplete ($ ret ) as $ value ) {
296307 // 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 )) {
298309 $ matches [$ numMatches ++] = $ value ;
299310 }
300311 }
@@ -306,8 +317,9 @@ function ($match) use ($ret) {
306317 if ($ numMatches > 0 && -1 !== $ ofs ) {
307318 // Save cursor position
308319 $ 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> ' );
311323 // Restore cursor position
312324 $ output ->write ("\0338 " );
313325 }
@@ -316,7 +328,24 @@ function ($match) use ($ret) {
316328 // Reset stty so it behaves normally again
317329 shell_exec (sprintf ('stty %s ' , $ sttyMode ));
318330
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 ;
320349 }
321350
322351 /**
0 commit comments