Use c stdlib function to set up raw mode
Some checks failed
timw4mail/php-kilo/pipeline/head There was a failure building this commit

This commit is contained in:
Timothy Warren 2023-10-10 13:02:05 -04:00
parent fd478b697f
commit 998102816e
13 changed files with 76 additions and 45 deletions

2
kilo
View File

@ -3,6 +3,8 @@
namespace Aviat\Kilo; namespace Aviat\Kilo;
use Aviat\Kilo\Terminal\Termios;
require_once __DIR__ . '/src/Kilo.php'; require_once __DIR__ . '/src/Kilo.php';
// Remove the composer install requirement by // Remove the composer install requirement by

View File

@ -2,16 +2,11 @@
namespace Aviat\Kilo; namespace Aviat\Kilo;
use Aviat\Kilo\Type\TerminalSize; use Aviat\Kilo\Enum\{Color, Highlight, KeyType, RawKeyCode, SearchDirection};
use Aviat\Kilo\Enum\{ use Aviat\Kilo\Terminal\ANSI;
Color, use Aviat\Kilo\Terminal\Terminal;
Color256,
RawKeyCode,
KeyType,
Highlight,
SearchDirection
};
use Aviat\Kilo\Type\{Point, StatusMessage}; use Aviat\Kilo\Type\{Point, StatusMessage};
use Aviat\Kilo\Type\TerminalSize;
/** /**
* // Don't highlight this! * // Don't highlight this!

View File

@ -1,7 +1,8 @@
<?php declare(strict_types=1); <?php declare(strict_types=1);
namespace Aviat\Kilo; namespace Aviat\Kilo\Terminal;
use Aviat\Kilo\Enum;
use Aviat\Kilo\Enum\Color; use Aviat\Kilo\Enum\Color;
use Aviat\Kilo\Enum\Color256; use Aviat\Kilo\Enum\Color256;

View File

@ -1,6 +1,6 @@
<?php declare(strict_types=1); <?php declare(strict_types=1);
namespace Aviat\Kilo; namespace Aviat\Kilo\Terminal;
use Aviat\Kilo\Traits; use Aviat\Kilo\Traits;

View File

@ -1,9 +1,9 @@
<?php declare(strict_types=1); <?php declare(strict_types=1);
namespace Aviat\Kilo; namespace Aviat\Kilo\Terminal;
use Aviat\Kilo\Enum\RawKeyCode;
use Aviat\Kilo\Enum\KeyType; use Aviat\Kilo\Enum\KeyType;
use Aviat\Kilo\Enum\RawKeyCode;
use Aviat\Kilo\Type\TerminalSize; use Aviat\Kilo\Type\TerminalSize;
class Terminal { class Terminal {
@ -126,7 +126,6 @@ class Terminal {
/** /**
* Write to the stdout stream * Write to the stdout stream
* *
* @codeCoverageIgnore
* @param string $str * @param string $str
* @param int|NULL $len * @param int|NULL $len
* @return int|false * @return int|false
@ -154,7 +153,6 @@ class Terminal {
* See if tput exists for fallback terminal size detection * See if tput exists for fallback terminal size detection
* *
* @return bool * @return bool
* @codeCoverageIgnore
*/ */
private static function has_tput(): bool private static function has_tput(): bool
{ {

View File

@ -1,6 +1,6 @@
<?php declare(strict_types=1); <?php declare(strict_types=1);
namespace Aviat\Kilo; namespace Aviat\Kilo\Terminal;
use FFI; use FFI;
use FFI\CData; use FFI\CData;
@ -57,14 +57,9 @@ class Termios {
register_shutdown_function([static::class, 'disableRawMode']); register_shutdown_function([static::class, 'disableRawMode']);
$termios = clone $instance->originalTermios; $termios = clone $instance->originalTermios;
$termios->c_iflag &= ~(C::BRKINT | C::ICRNL | C::INPCK | C::ISTRIP | C::IXON);
$termios->c_oflag &= ~(C::OPOST);
$termios->c_cflag |= (C::CS8);
$termios->c_lflag &= ~( C::ECHO | C::ICANON | C::IEXTEN | C::ISIG );
$termios->c_cc[C::VMIN] = 0;
$termios->c_cc[C::VTIME] = 1;
// Turn on raw mode // Turn on raw mode
self::ffi()->cfmakeraw(FFI::addr($termios));
$res = self::ffi() $res = self::ffi()
->tcsetattr(C::STDIN_FILENO, C::TCSAFLUSH, FFI::addr($termios)); ->tcsetattr(C::STDIN_FILENO, C::TCSAFLUSH, FFI::addr($termios));

View File

@ -1,11 +1,14 @@
<?php declare(strict_types=1); <?php declare(strict_types=1);
namespace Aviat\Kilo; namespace Aviat\Kilo\Terminal;
use Throwable; use Throwable;
class TermiosException extends \UnexpectedValueException { class TermiosException extends \UnexpectedValueException {
public function __construct($message = 'Failed to apply terminal settings', $code = 0, Throwable $previous = NULL) public function __construct(
string $message = 'Failed to apply terminal settings',
int $code = 0,
Throwable $previous = NULL)
{ {
parent::__construct($message, $code, $previous); parent::__construct($message, $code, $previous);
} }

View File

@ -9,7 +9,7 @@
// PHP 'constants' for FFI integration // PHP 'constants' for FFI integration
// These seem to be the only define statements supported by the FFI integration // These seem to be the only define statements supported by the FFI integration
#define FFI_SCOPE "terminal" #define FFI_SCOPE "terminal"
#define FFI_LIB "libc.so.6" #define FFI_LIB "libc.so"
// Nonsense for a test with a single quote // Nonsense for a test with a single quote
// Ignored by PHP due to the octothorpe (#) // Ignored by PHP due to the octothorpe (#)
@ -55,6 +55,7 @@ struct termios
int tcgetattr (int fd, struct termios *termios_p); int tcgetattr (int fd, struct termios *termios_p);
int tcsetattr (int fd, int optional_actions, const struct termios *termios_p); int tcsetattr (int fd, int optional_actions, const struct termios *termios_p);
void cfmakeraw(struct termios *);
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
//! <sys/ioctl.h> //! <sys/ioctl.h>

View File

@ -2,8 +2,8 @@
namespace Aviat\Kilo\Tests; namespace Aviat\Kilo\Tests;
use Aviat\Kilo\ANSI;
use Aviat\Kilo\Enum\Color; use Aviat\Kilo\Enum\Color;
use Aviat\Kilo\Terminal\ANSI;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
class ANSITest extends TestCase { class ANSITest extends TestCase {

View File

@ -47,7 +47,7 @@ class EditorTest extends TestCase {
public function testOpen(): void public function testOpen(): void
{ {
$editor = MockEditor::mock('src/ffi.h'); $editor = MockEditor::mock('src/Terminal/ffi.h');
$state = json_encode($editor->__debugInfo(), JSON_THROW_ON_ERROR); $state = json_encode($editor->__debugInfo(), JSON_THROW_ON_ERROR);
$this->assertMatchesJsonSnapshot($state); $this->assertMatchesJsonSnapshot($state);

View File

@ -2,10 +2,9 @@
namespace Aviat\Kilo\Tests; namespace Aviat\Kilo\Tests;
use Aviat\Kilo\Terminal\Terminal;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
use Aviat\Kilo\Terminal;
class TerminalTest extends TestCase { class TerminalTest extends TestCase {
public function test_getWindowSize(): void public function test_getWindowSize(): void

View File

@ -2,7 +2,7 @@
namespace Aviat\Kilo\Tests; namespace Aviat\Kilo\Tests;
use Aviat\Kilo\{Termios, TermiosException}; use Aviat\Kilo\{Terminal\Termios, Terminal\TermiosException};
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
class TermiosTest extends TestCase { class TermiosTest extends TestCase {

View File

@ -103,7 +103,7 @@
} }
}, },
"tokens": [], "tokens": [],
"filename": "src\/ffi.h", "filename": "src\/Terminal\/ffi.h",
"rows": [ "rows": [
{ {
"render": "\/**", "render": "\/**",
@ -465,7 +465,7 @@
"idx": 10 "idx": 10
}, },
{ {
"render": "#define FFI_LIB \"libc.so.6\"", "render": "#define FFI_LIB \"libc.so\"",
"hl": [ "hl": [
"Keyword2", "Keyword2",
"Keyword2", "Keyword2",
@ -491,8 +491,6 @@
"String", "String",
"String", "String",
"String", "String",
"String",
"String",
"String" "String"
], ],
"idx": 11 "idx": 11
@ -1740,10 +1738,49 @@
], ],
"idx": 56 "idx": 56
}, },
{
"render": "void cfmakeraw(struct termios *);",
"hl": [
"Keyword2",
"Keyword2",
"Keyword2",
"Keyword2",
"Normal",
"Normal",
"Normal",
"Normal",
"Normal",
"Normal",
"Normal",
"Normal",
"Normal",
"Normal",
"Delimiter",
"Keyword1",
"Keyword1",
"Keyword1",
"Keyword1",
"Keyword1",
"Keyword1",
"Normal",
"Normal",
"Normal",
"Normal",
"Normal",
"Normal",
"Normal",
"Normal",
"Normal",
"Operator",
"Delimiter",
"Operator"
],
"idx": 57
},
{ {
"render": "", "render": "",
"hl": [], "hl": [],
"idx": 57 "idx": 58
}, },
{ {
"render": "\/\/ -----------------------------------------------------------------------------", "render": "\/\/ -----------------------------------------------------------------------------",
@ -1829,7 +1866,7 @@
"Comment", "Comment",
"Comment" "Comment"
], ],
"idx": 58 "idx": 59
}, },
{ {
"render": "\/\/! <sys\/ioctl.h>", "render": "\/\/! <sys\/ioctl.h>",
@ -1852,7 +1889,7 @@
"Comment", "Comment",
"Comment" "Comment"
], ],
"idx": 59 "idx": 60
}, },
{ {
"render": "\/\/ -----------------------------------------------------------------------------", "render": "\/\/ -----------------------------------------------------------------------------",
@ -1938,7 +1975,7 @@
"Comment", "Comment",
"Comment" "Comment"
], ],
"idx": 60 "idx": 61
}, },
{ {
"render": "struct winsize {", "render": "struct winsize {",
@ -1960,7 +1997,7 @@
"Normal", "Normal",
"Delimiter" "Delimiter"
], ],
"idx": 61 "idx": 62
}, },
{ {
"render": " unsigned short ws_row;", "render": " unsigned short ws_row;",
@ -1992,7 +2029,7 @@
"Normal", "Normal",
"Operator" "Operator"
], ],
"idx": 62 "idx": 63
}, },
{ {
"render": " unsigned short ws_col;", "render": " unsigned short ws_col;",
@ -2024,7 +2061,7 @@
"Normal", "Normal",
"Operator" "Operator"
], ],
"idx": 63 "idx": 64
}, },
{ {
"render": " unsigned short ws_xpixel;", "render": " unsigned short ws_xpixel;",
@ -2059,7 +2096,7 @@
"Normal", "Normal",
"Operator" "Operator"
], ],
"idx": 64 "idx": 65
}, },
{ {
"render": " unsigned short ws_ypixel;", "render": " unsigned short ws_ypixel;",
@ -2094,7 +2131,7 @@
"Normal", "Normal",
"Operator" "Operator"
], ],
"idx": 65 "idx": 66
}, },
{ {
"render": "};", "render": "};",
@ -2102,7 +2139,7 @@
"Delimiter", "Delimiter",
"Operator" "Operator"
], ],
"idx": 66 "idx": 67
}, },
{ {
"render": "int ioctl (int, int, ...);", "render": "int ioctl (int, int, ...);",
@ -2134,7 +2171,7 @@
"Delimiter", "Delimiter",
"Operator" "Operator"
], ],
"idx": 67 "idx": 68
} }
], ],
"dirty": false "dirty": false