Skip to content

Commit 2554be8

Browse files
committed
fix(cli): fix Down arrow exiting fhelp/fhist/fparam — use select() timeout to disambiguate ESC sequences
1 parent f4b9ba2 commit 2554be8

1 file changed

Lines changed: 25 additions & 11 deletions

File tree

src/cli/CLIcore/CLIcore/CLIcore_help.c

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1968,6 +1968,28 @@ errno_t help_module()
19681968
#include <readline/history.h>
19691969
#endif
19701970

1971+
#include <sys/select.h>
1972+
1973+
/**
1974+
* @brief Wait up to ms milliseconds for stdin to have data.
1975+
*
1976+
* Returns 1 if data is ready, 0 on timeout.
1977+
* Used to disambiguate a bare ESC from ESC-sequence prefixes
1978+
* (arrow keys, PgUp/PgDn) inside raw-mode TUI prompts.
1979+
*/
1980+
static int tui_stdin_wait_ms(int ms)
1981+
{
1982+
fd_set fds;
1983+
struct timeval tv;
1984+
1985+
FD_ZERO(&fds);
1986+
FD_SET(STDIN_FILENO, &fds);
1987+
tv.tv_sec = 0;
1988+
tv.tv_usec = ms * 1000;
1989+
return select(STDIN_FILENO + 1,
1990+
&fds, NULL, NULL, &tv) > 0;
1991+
}
1992+
19711993
// Simple Levenshtein distance for fuzzy matching
19721994
static int fuzzy_match_score(const char *query, const char *target)
19731995
{
@@ -2062,9 +2084,7 @@ int cli_fhelp(void)
20622084
// Input loop
20632085
char c = getchar();
20642086
if (c == 27) { // Escape seq
2065-
int byteswaiting;
2066-
ioctl(STDIN_FILENO, FIONREAD, &byteswaiting);
2067-
if (byteswaiting > 0) {
2087+
if (tui_stdin_wait_ms(50)) {
20682088
char seq[2];
20692089
seq[0] = getchar();
20702090
seq[1] = getchar();
@@ -2207,10 +2227,7 @@ int cli_fhist(void)
22072227
// Input loop
22082228
char c = getchar();
22092229
if (c == 27) { // Escape seq
2210-
// check if there is an escape sequence waiting
2211-
int byteswaiting;
2212-
ioctl(STDIN_FILENO, FIONREAD, &byteswaiting);
2213-
if (byteswaiting > 0) {
2230+
if (tui_stdin_wait_ms(50)) {
22142231
char seq[2];
22152232
seq[0] = getchar();
22162233
seq[1] = getchar();
@@ -2350,10 +2367,7 @@ int cli_fparam(void)
23502367
// Input loop
23512368
char c = getchar();
23522369
if (c == 27) { // Escape seq
2353-
// check if there is an escape sequence waiting
2354-
int byteswaiting;
2355-
ioctl(STDIN_FILENO, FIONREAD, &byteswaiting);
2356-
if (byteswaiting > 0) {
2370+
if (tui_stdin_wait_ms(50)) {
23572371
char seq[2];
23582372
seq[0] = getchar();
23592373
seq[1] = getchar();

0 commit comments

Comments
 (0)