Fix issues with rendering and input handling

This commit is contained in:
Timothy Warren 2019-10-21 15:37:20 -04:00
parent 5ced2d1f09
commit e9cdc17322
3 changed files with 33 additions and 71 deletions

7
kilo
View File

@ -26,14 +26,7 @@ function main(int $argc, array $argv): int
while (true) while (true)
{ {
$editor->refreshScreen(); $editor->refreshScreen();
// Spin while waiting for a keypress
$char = $editor->processKeypress(); $char = $editor->processKeypress();
while ($char === '')
{
$char = $editor->processKeypress();
}
if ($char === NULL) if ($char === NULL)
{ {
break; break;

View File

@ -22,10 +22,10 @@ trait MagicProperties {
} }
class Key { class Key {
public const ARROW_LEFT = 'a';//'ARROW_LEFT'; public const ARROW_LEFT = 'ARROW_LEFT';
public const ARROW_RIGHT = 'd';//ARROW_RIGHT'; public const ARROW_RIGHT = 'ARROW_RIGHT';
public const ARROW_UP = 'w';//'ARROW_UP'; public const ARROW_UP = 'ARROW_UP';
public const ARROW_DOWN = 's';//'ARROW_DOWN'; public const ARROW_DOWN = 'ARROW_DOWN';
public const DEL_KEY = 'DEL'; public const DEL_KEY = 'DEL';
public const HOME_KEY = 'HOME'; public const HOME_KEY = 'HOME';
public const END_KEY = 'END'; public const END_KEY = 'END';
@ -130,68 +130,36 @@ class Editor {
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
protected function readKey(): string protected function readKey(): string
{ {
$c = read_stdin(1); $c = read_stdin();
if ($c === '\x1b') // @TODO Make this more DRY
switch ($c)
{ {
$seq = read_stdin(); case "\x1b[A": return Key::ARROW_UP;
case "\x1b[B": return Key::ARROW_DOWN;
case "\x1b[C": return Key::ARROW_RIGHT;
case "\x1b[D": return Key::ARROW_LEFT;
if (strlen($seq) < 3) case "\x1b[3~": return Key::DEL_KEY;
{
return '\x1b';
}
if (strpos($seq, '[') === 0) case "\x1b[5~": return Key::PAGE_UP;
{ case "\x1b[6~": return Key::PAGE_DOWN;
$seq1 = (int)$seq[1];
if ($seq1 >= 0 && $seq1 <= 9) case "\x1bOH":
{ case "\x1b[1~":
if (strpos($seq, '~') === 2) case "\x1b[7~":
{ case "\x1b[H":
switch ($seq[1])
{
case '1':
case '7':
return Key::HOME_KEY; return Key::HOME_KEY;
case '4': case "\x1bOF":
case '8': case "\x1b[4~":
case "\x1b[8~":
case "\x1b[F":
return Key::END_KEY; return Key::END_KEY;
case '3': return Key::DEL_KEY; default: return $c;
case '5': return Key::PAGE_UP;
case '6': return Key::PAGE_DOWN;
} }
} }
}
else
{
switch ($seq[1])
{
case 'A': return Key::ARROW_UP;
case 'B': return Key::ARROW_DOWN;
case 'C': return Key::ARROW_RIGHT;
case 'D': return Key::ARROW_LEFT;
case 'H': return Key::HOME_KEY;
case 'F': return Key::END_KEY;
}
}
}
else if (strpos($seq, 'O') === 0)
{
switch ($seq[1])
{
case 'H': return Key::HOME_KEY;
case 'F': return Key::END_KEY;
}
}
return '\x1b';
}
return $c;
}
/** /**
* @TODO fix * @TODO fix
@ -304,7 +272,8 @@ class Editor {
while (($line = fgets($handle)) !== FALSE) while (($line = fgets($handle)) !== FALSE)
{ {
$this->appendRow($line); // Remove line endings when reading the file
$this->appendRow(rtrim($line));
} }
fclose($handle); fclose($handle);
@ -552,7 +521,7 @@ class Editor {
case Key::END_KEY: case Key::END_KEY:
if ($this->cursorY < $this->numRows) if ($this->cursorY < $this->numRows)
{ {
$this->cursorX = $this->rows[$this->cursorY]->size; $this->cursorX = $this->rows[$this->cursorY]->size - 1;
} }
break; break;
@ -593,7 +562,6 @@ class Editor {
if ($this->cursorY > $this->numRows) if ($this->cursorY > $this->numRows)
{ {
$this->cursorY = $this->numRows; $this->cursorY = $this->numRows;
} }
} }

View File

@ -21,11 +21,12 @@ function enableRawMode(): void
die('tcgetattr'); die('tcgetattr');
} }
$termios = $ffi->new('struct termios'); // So, the only thing that seems to really matter here is that c_oflag is 0...
$termios->c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON); $termios = clone $original_termios;
$termios->c_oflag &= ~(OPOST); $termios->c_iflag = $termios->c_iflag & ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
$termios->c_oflag = 0; // $termios->c_oflag && ~(OPOST);
$termios->c_cflag |= (CS8); $termios->c_cflag |= (CS8);
$termios->c_lflag &= ~(_ECHO | ICANON | IEXTEN | ISIG); $termios->c_lflag = $termios->c_lflag & ~(_ECHO | ICANON | IEXTEN | ISIG);
$termios->c_cc[VMIN] = 0; $termios->c_cc[VMIN] = 0;
$termios->c_cc[VTIME] = 1; $termios->c_cc[VTIME] = 1;