From 2ec568579823c991b919fa3a2c8583a8db21cb81 Mon Sep 17 00:00:00 2001 From: Robin Haberkorn Date: Wed, 30 Jul 2025 23:58:32 +0300 Subject: implemented ^T command: allows typing by code and getting characters from stdin or the user * n:^T always prints bytes (cf. :^A) * ^T without arguments returns a codepoint or byte from stdin. In interactive mode, this currentply places a cursor in the message line and waits for a keypress. --- src/interface-curses/interface.c | 54 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 3 deletions(-) (limited to 'src/interface-curses/interface.c') diff --git a/src/interface-curses/interface.c b/src/interface-curses/interface.c index e461b3c..d92eade 100644 --- a/src/interface-curses/interface.c +++ b/src/interface-curses/interface.c @@ -134,6 +134,9 @@ teco_console_ctrl_handler(DWORD type) static gint teco_xterm_version(void) G_GNUC_UNUSED; +static void teco_interface_refresh(void); +static gint teco_interface_blocking_getch(void); + #define UNNAMED_FILE "(Unnamed)" /** @@ -915,6 +918,50 @@ teco_interface_msg_clear(void) teco_curses_clrtobot(teco_interface.msg_window); } +teco_int_t +teco_interface_getch(gboolean widechar) +{ + if (!teco_interface.cmdline_window) /* batch mode */ + return teco_interface_stdio_getch(widechar); + + teco_interface_refresh(); + + /* + * Signal that we accept input by drawing a real cursor in the message bar. + */ + wmove(teco_interface.msg_window, 0, 0); + curs_set(1); + wrefresh(teco_interface.msg_window); + + gchar buf[4]; + gint i = 0; + gint32 cp; + + do { + cp = teco_interface_blocking_getch(); + if (cp == TECO_CTL_KEY('C')) + teco_interrupted = TRUE; + if (cp == TECO_CTL_KEY('C') || cp == TECO_CTL_KEY('D')) { + cp = -1; + break; + } + if (cp < 0 || cp > 0xFF) + continue; + + if (!widechar || !cp) + break; + + /* doesn't work as expected when passed a null byte */ + buf[i] = cp; + cp = g_utf8_get_char_validated(buf, ++i); + if (i >= sizeof(buf) || cp != -2) + i = 0; + } while (cp < 0); + + curs_set(0); + return cp; +} + void teco_interface_show_view(teco_view_t *view) { @@ -1933,6 +1980,9 @@ teco_interface_getmouse(GError **error) static gint teco_interface_blocking_getch(void) { + if (!g_queue_is_empty(teco_interface.input_queue)) + return GPOINTER_TO_INT(g_queue_pop_head(teco_interface.input_queue)); + #if NCURSES_MOUSE_VERSION >= 2 #ifdef __PDCURSES__ /* @@ -1991,9 +2041,7 @@ teco_interface_event_loop_iter(void) GError **error = &teco_interface.event_loop_error; - gint key = g_queue_is_empty(teco_interface.input_queue) - ? teco_interface_blocking_getch() - : GPOINTER_TO_INT(g_queue_pop_head(teco_interface.input_queue)); + gint key = teco_interface_blocking_getch(); const teco_view_t *last_view = teco_interface_current_view; sptr_t last_vpos = teco_interface_ssm(SCI_GETFIRSTVISIBLELINE, 0, 0); -- cgit v1.2.3