Fix issues with rendering and input handling
This commit is contained in:
parent
5ced2d1f09
commit
e9cdc17322
7
kilo
7
kilo
@ -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;
|
||||||
|
@ -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,67 +130,35 @@ 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])
|
return Key::HOME_KEY;
|
||||||
{
|
|
||||||
case '1':
|
|
||||||
case '7':
|
|
||||||
return Key::HOME_KEY;
|
|
||||||
|
|
||||||
case '4':
|
case "\x1bOF":
|
||||||
case '8':
|
case "\x1b[4~":
|
||||||
return Key::END_KEY;
|
case "\x1b[8~":
|
||||||
|
case "\x1b[F":
|
||||||
|
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -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;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user