Ejemplo n.º 1
0
 /**
  * Autocompletes a question.
  *
  * @param OutputInterface $output
  * @param Question        $question
  *
  * @return string
  */
 private function autocomplete(OutputInterface $output, Question $question, $inputStream)
 {
     $autocomplete = $question->getAutocompleterValues();
     $ret = '';
     $i = 0;
     $ofs = -1;
     $matches = $autocomplete;
     $numMatches = count($matches);
     $sttyMode = shell_exec('stty -g');
     // Disable icanon (so we can fread each keypress) and echo (we'll do echoing here instead)
     shell_exec('stty -icanon -echo');
     // Add highlighted text style
     $output->getFormatter()->setStyle('hl', new OutputFormatterStyle('black', 'white'));
     // Read a keypress
     while (!feof($inputStream)) {
         $c = fread($inputStream, 1);
         // Backspace Character
         if ("" === $c) {
             if (0 === $numMatches && 0 !== $i) {
                 --$i;
                 // Move cursor backwards
                 $output->write("");
             }
             if ($i === 0) {
                 $ofs = -1;
                 $matches = $autocomplete;
                 $numMatches = count($matches);
             } else {
                 $numMatches = 0;
             }
             // Pop the last character off the end of our string
             $ret = substr($ret, 0, $i);
         } elseif ("" === $c) {
             // Did we read an escape sequence?
             $c .= fread($inputStream, 2);
             // A = Up Arrow. B = Down Arrow
             if (isset($c[2]) && ('A' === $c[2] || 'B' === $c[2])) {
                 if ('A' === $c[2] && -1 === $ofs) {
                     $ofs = 0;
                 }
                 if (0 === $numMatches) {
                     continue;
                 }
                 $ofs += 'A' === $c[2] ? -1 : 1;
                 $ofs = ($numMatches + $ofs) % $numMatches;
             }
         } elseif (ord($c) < 32) {
             if ("\t" === $c || "\n" === $c) {
                 if ($numMatches > 0 && -1 !== $ofs) {
                     $ret = $matches[$ofs];
                     // Echo out remaining chars for current match
                     $output->write(substr($ret, $i));
                     $i = strlen($ret);
                 }
                 if ("\n" === $c) {
                     $output->write($c);
                     break;
                 }
                 $numMatches = 0;
             }
             continue;
         } else {
             $output->write($c);
             $ret .= $c;
             ++$i;
             $numMatches = 0;
             $ofs = 0;
             foreach ($autocomplete as $value) {
                 // If typed characters match the beginning chunk of value (e.g. [AcmeDe]moBundle)
                 if (0 === strpos($value, $ret) && $i !== strlen($value)) {
                     $matches[$numMatches++] = $value;
                 }
             }
         }
         // Erase characters from cursor to end of line
         $output->write("");
         if ($numMatches > 0 && -1 !== $ofs) {
             // Save cursor position
             $output->write("7");
             // Write highlighted text
             $output->write('<hl>' . substr($matches[$ofs], $i) . '</hl>');
             // Restore cursor position
             $output->write("8");
         }
     }
     // Reset stty so it behaves normally again
     shell_exec(sprintf('stty %s', $sttyMode));
     return $ret;
 }
Ejemplo n.º 2
0
 private function autocomplete(OutputInterface $output, Question $question, $inputStream)
 {
     $autocomplete = $question->getAutocompleterValues();
     $ret = '';
     $i = 0;
     $ofs = -1;
     $matches = $autocomplete;
     $numMatches = count($matches);
     $sttyMode = shell_exec('stty -g');
     shell_exec('stty -icanon -echo');
     $output->getFormatter()->setStyle('hl', new OutputFormatterStyle('black', 'white'));
     while (!feof($inputStream)) {
         $c = fread($inputStream, 1);
         if ("" === $c) {
             if (0 === $numMatches && 0 !== $i) {
                 --$i;
                 $output->write("");
             }
             if ($i === 0) {
                 $ofs = -1;
                 $matches = $autocomplete;
                 $numMatches = count($matches);
             } else {
                 $numMatches = 0;
             }
             $ret = substr($ret, 0, $i);
         } elseif ("" === $c) {
             $c .= fread($inputStream, 2);
             if (isset($c[2]) && ('A' === $c[2] || 'B' === $c[2])) {
                 if ('A' === $c[2] && -1 === $ofs) {
                     $ofs = 0;
                 }
                 if (0 === $numMatches) {
                     continue;
                 }
                 $ofs += 'A' === $c[2] ? -1 : 1;
                 $ofs = ($numMatches + $ofs) % $numMatches;
             }
         } elseif (ord($c) < 32) {
             if ("\t" === $c || "\n" === $c) {
                 if ($numMatches > 0 && -1 !== $ofs) {
                     $ret = $matches[$ofs];
                     $output->write(substr($ret, $i));
                     $i = strlen($ret);
                 }
                 if ("\n" === $c) {
                     $output->write($c);
                     break;
                 }
                 $numMatches = 0;
             }
             continue;
         } else {
             $output->write($c);
             $ret .= $c;
             ++$i;
             $numMatches = 0;
             $ofs = 0;
             foreach ($autocomplete as $value) {
                 if (0 === strpos($value, $ret) && $i !== strlen($value)) {
                     $matches[$numMatches++] = $value;
                 }
             }
         }
         $output->write("");
         if ($numMatches > 0 && -1 !== $ofs) {
             $output->write("7");
             $output->write('<hl>' . substr($matches[$ofs], $i) . '</hl>');
             $output->write("8");
         }
     }
     shell_exec(sprintf('stty %s', $sttyMode));
     return $ret;
 }