Created
June 28, 2022 06:37
-
-
Save adsr/d9bae670f5b3d823afb483a01360ec6a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
declare(strict_types=1); | |
$libreadline_so = __DIR__ . '/vendor/readline/shlib/libreadline.so.8.1'; | |
$readline_h = <<<'EOD' | |
int rl_catch_signals; | |
int rl_catch_sigwinch; | |
int rl_change_environment; | |
int rl_point; | |
char *rl_display_prompt; | |
char *rl_line_buffer; | |
void *rl_deprep_term_function; | |
void *rl_prep_term_function; | |
int (*rl_bind_key)(int, int (*)(int, int)); | |
int (*rl_getc_function)(void *); | |
int (*rl_input_available_hook)(); | |
void (*rl_redisplay_function)(); | |
int rl_forward_char(int, int); | |
int rl_backward_char(int, int); | |
void rl_callback_handler_install(const char *, void (*)(char *)); | |
void rl_callback_handler_remove(); | |
void rl_callback_read_char(); | |
EOD; | |
$readline = FFI::cdef($readline_h, $libreadline_so); | |
[ $termbox, $termbox_defines ] = require __DIR__ . '/vendor/termbox2/tests/test_ffi.php'; | |
$termbox->tb_init(); | |
$input = null; | |
$input_avail = false; | |
$readline->rl_catch_signals = 0; | |
$readline->rl_catch_sigwinch = 0; | |
$readline->rl_change_environment = 0; | |
$readline->rl_deprep_term_function = null; | |
$readline->rl_prep_term_function = null; | |
$readline->rl_getc_function = function ($ignore) use (&$input_avail, &$input) { | |
fwrite(STDERR, "rl_getc_function input=$input\n"); | |
$input_avail = false; | |
return $input; | |
}; | |
$readline->rl_input_available_hook = function () use ($input_avail) { | |
fwrite(STDERR, "rl_input_available_hook input_avail=$input_avail\n"); | |
return $input_avail; | |
}; | |
$rl_redisplay_function = function () use ($termbox, $readline) { | |
$line_buffer = FFI::string($readline->rl_line_buffer); | |
fwrite(STDERR, "rl_redisplay_function rl_line_buffer=$line_buffer\n"); | |
$termbox->tb_clear(); | |
$termbox->tb_printf(0, $termbox->tb_height() - 1, 0, 0, "%s", $line_buffer); | |
$termbox->tb_set_cursor($readline->rl_point, $termbox->tb_height() - 1); | |
$termbox->tb_present(); | |
}; | |
$readline->rl_redisplay_function = $rl_redisplay_function; | |
$readline->rl_callback_handler_install("> ", function ($line) { | |
$line = FFI::string($line); | |
fwrite(STDERR, "line=$line\n"); | |
}); | |
while (true) { | |
$event = $termbox->new('struct tb_event'); | |
$termbox->tb_poll_event(FFI::addr($event)); | |
if ($event->ch || $event->key < 0x80) { | |
if ($event->ch === ord('q')) { | |
break; | |
} | |
$input = $event->ch ?: $event->key; | |
$input_avail = true; | |
fwrite(STDERR, "tb_poll_event input=$input\n"); | |
$readline->rl_callback_read_char(); | |
} else if ($event->key === $termbox_defines['TB_KEY_ARROW_LEFT']) { | |
$readline->rl_backward_char(1, 0); | |
$rl_redisplay_function(); | |
} else if ($event->key === $termbox_defines['TB_KEY_ARROW_RIGHT']) { | |
$readline->rl_forward_char(1, 0); | |
$rl_redisplay_function(); | |
} | |
} | |
/* | |
TB_KEY_HOME | |
TB_KEY_END | |
TB_KEY_PGUP | |
TB_KEY_PGDN | |
TB_KEY_ARROW_UP | |
TB_KEY_ARROW_DOWN | |
TB_KEY_ARROW_LEFT | |
TB_KEY_ARROW_RIGHT | |
*/ | |
$readline->rl_callback_handler_remove(); | |
$termbox->tb_shutdown(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment