Enable arrow keys to browse matched autocomplete options
This commit is contained in:
parent
31ff3db517
commit
a4d711cb2a
@ -86,10 +86,13 @@ class DialogHelper extends Helper
|
|||||||
}
|
}
|
||||||
$ret = trim($ret);
|
$ret = trim($ret);
|
||||||
} else {
|
} else {
|
||||||
$i = 0;
|
|
||||||
$currentMatched = false;
|
|
||||||
$ret = '';
|
$ret = '';
|
||||||
|
|
||||||
|
$i = 0;
|
||||||
|
$matches = array();
|
||||||
|
$numMatches = 0;
|
||||||
|
$ofs = 0;
|
||||||
|
|
||||||
// Disable icanon (so we can fread each keypress) and echo (we'll do echoing here instead)
|
// Disable icanon (so we can fread each keypress) and echo (we'll do echoing here instead)
|
||||||
shell_exec('stty -icanon -echo');
|
shell_exec('stty -icanon -echo');
|
||||||
|
|
||||||
@ -98,25 +101,9 @@ class DialogHelper extends Helper
|
|||||||
|
|
||||||
// Read a keypress
|
// Read a keypress
|
||||||
while ($c = fread($inputStream, 1)) {
|
while ($c = fread($inputStream, 1)) {
|
||||||
// Did we read an escape sequence?
|
|
||||||
if ("\033" === $c) {
|
|
||||||
$c .= fread($inputStream, 2);
|
|
||||||
|
|
||||||
// Escape sequences for arrow keys
|
|
||||||
if ('A' === $c[2] || 'B' === $c[2] || 'C' === $c[2] || 'D' === $c[2]) {
|
|
||||||
// todo
|
|
||||||
}
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Backspace Character
|
// Backspace Character
|
||||||
if ("\177" === $c) {
|
if ("\177" === $c) {
|
||||||
if ($i === 0) {
|
if (0 === $numMatches && 0 !== $i) {
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (false === $currentMatched) {
|
|
||||||
$i--;
|
$i--;
|
||||||
// Move cursor backwards
|
// Move cursor backwards
|
||||||
$output->write("\033[1D");
|
$output->write("\033[1D");
|
||||||
@ -126,16 +113,35 @@ class DialogHelper extends Helper
|
|||||||
$output->write("\033[K");
|
$output->write("\033[K");
|
||||||
$ret = substr($ret, 0, $i);
|
$ret = substr($ret, 0, $i);
|
||||||
|
|
||||||
$currentMatched = false;
|
$matches = array();
|
||||||
|
$numMatches = 0;
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Did we read an escape sequence?
|
||||||
|
if ("\033" === $c) {
|
||||||
|
$c .= fread($inputStream, 2);
|
||||||
|
|
||||||
|
if ('A' === $c[2] || 'B' === $c[2]) {
|
||||||
|
if (0 === $i) {
|
||||||
|
$matches = $autocomplete;
|
||||||
|
$numMatches = count($matches);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 === $numMatches) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$ofs += ('A' === $c[2]) ? -1 : 1;
|
||||||
|
$ofs = ($numMatches + $ofs) % $numMatches;
|
||||||
|
}
|
||||||
|
} else if (ord($c) < 32) {
|
||||||
if ("\t" === $c || "\n" === $c) {
|
if ("\t" === $c || "\n" === $c) {
|
||||||
if (false !== $currentMatched) {
|
if ($numMatches > 0) {
|
||||||
|
$ret = $matches[$ofs];
|
||||||
// Echo out completed match
|
// Echo out completed match
|
||||||
$output->write(substr($autocomplete[$currentMatched], strlen($ret)));
|
$output->write(substr($ret, $i));
|
||||||
$ret = $autocomplete[$currentMatched];
|
|
||||||
$i = strlen($ret);
|
$i = strlen($ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,45 +150,40 @@ class DialogHelper extends Helper
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
$currentMatched = false;
|
$matches = array();
|
||||||
|
$numMatches = 0;
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ord($c) < 32) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
} else {
|
||||||
|
|
||||||
$output->write($c);
|
$output->write($c);
|
||||||
$ret .= $c;
|
$ret .= $c;
|
||||||
$i++;
|
$i++;
|
||||||
|
|
||||||
// Erase characters from cursor to end of line
|
$matches = array();
|
||||||
$output->write("\033[K");
|
$numMatches = 0;
|
||||||
|
$ofs = 0;
|
||||||
|
|
||||||
foreach ($autocomplete as $j => $value) {
|
foreach ($autocomplete as $value) {
|
||||||
// Get a substring of the current autocomplete item based on number of chars typed (e.g. AcmeDemoBundle = Acme)
|
// Get a substring of the current autocomplete item based on number of chars typed (e.g. AcmeDemoBundle = Acme)
|
||||||
$matchTest = substr($value, 0, $i);
|
$matchTest = substr($value, 0, $i);
|
||||||
|
|
||||||
if ($ret === $matchTest) {
|
if ($ret === $matchTest && $i !== strlen($value)) {
|
||||||
if ($i === strlen($value)) {
|
$matches[$numMatches++] = $value;
|
||||||
$currentMatched = false;
|
}
|
||||||
break;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Erase characters from cursor to end of line
|
||||||
|
$output->write("\033[K");
|
||||||
|
|
||||||
|
if ($numMatches > 0) {
|
||||||
// Save cursor position
|
// Save cursor position
|
||||||
$output->write("\0337");
|
$output->write("\0337");
|
||||||
|
// Write highlighted text
|
||||||
$output->write('<hl>' . substr($value, $i) . '</hl>');
|
$output->write('<hl>' . substr($matches[$ofs], $i) . '</hl>');
|
||||||
|
|
||||||
// Restore cursor position
|
// Restore cursor position
|
||||||
$output->write("\0338");
|
$output->write("\0338");
|
||||||
|
|
||||||
$currentMatched = $j;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
$currentMatched = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user