protected function splitCommand()
{
$this->words = array();
$this->wordIndex = null;
$cursor = 0;
$breaks = preg_quote($this->wordBreaks);
if (!preg_match_all("/([^{$breaks}]*)([{$breaks}]*)/", $this->commandLine, $matches)) {
return;
}
// Groups:
// 1: Word
// 2: Break characters
foreach ($matches[0] as $index => $wholeMatch) {
// Determine which word the cursor is in
$cursor += strlen($wholeMatch);
$word = $matches[1][$index];
$breaks = $matches[2][$index];
if ($this->wordIndex === null && $cursor >= $this->charIndex) {
$this->wordIndex = $index;
// Find the user's cursor position relative to the end of this word
// The end of the word is the internal cursor minus any break characters that were captured
$cursorWordOffset = $this->charIndex - ($cursor - strlen($breaks));
if ($cursorWordOffset < 0) {
// Cursor is inside the word - truncate the word at the cursor
// (This emulates normal BASH completion behaviour I've observed, though I'm not entirely sure if it's useful)
$word = substr($word, 0, strlen($word) + $cursorWordOffset);
} elseif ($cursorWordOffset > 0) {
// Cursor is in the break-space after a word
// Push an empty word at the cursor to allow completion of new terms at the cursor, ignoring words ahead
$this->wordIndex++;
$this->words[] = $word;
$this->words[] = '';
continue;
}
}
if ($word !== '') {
$this->words[] = $word;
}
}
if ($this->wordIndex > count($this->words) - 1) {
$this->wordIndex = count($this->words) - 1;
}
}