From 932548ef4b440d1537b097d1317e7723c5534f51 Mon Sep 17 00:00:00 2001 From: Přemysl Janouch Date: Sat, 18 Apr 2015 16:03:50 +0200 Subject: degesch: make readline work better By randomly poking at it until it stops being a little shit. Still no Meta keys. --- degesch.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 56 insertions(+), 13 deletions(-) diff --git a/degesch.c b/degesch.c index e09f4cb..4c5afbb 100644 --- a/degesch.c +++ b/degesch.c @@ -446,7 +446,7 @@ static void app_readline_hide (struct app_readline_state *state) { state->saved_point = rl_point; - state->saved_point = rl_mark; + state->saved_mark = rl_mark; state->saved_line = rl_copy_text (0, rl_end); rl_set_prompt (""); rl_replace_line ("", 0); @@ -464,6 +464,16 @@ app_readline_restore (struct app_readline_state *state, const char *prompt) free (state->saved_line); } +static void +app_readline_erase_to_bol (const char *prompt) +{ + rl_set_prompt (""); + rl_replace_line ("", 0); + rl_point = rl_mark = 0; + rl_redisplay (); + rl_set_prompt (prompt); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - typedef int (*terminal_printer_fn) (int); @@ -1045,10 +1055,10 @@ initiate_quit (struct app_context *ctx) { // First get rid of readline if (ctx->readline_prompt_shown) - rl_crlf (); - - rl_callback_handler_remove (); - ctx->readline_prompt_shown = false; + { + app_readline_erase_to_bol (ctx->readline_prompt); + ctx->readline_prompt_shown = false; + } // Initiate a connection close buffer_send_status (ctx, ctx->global_buffer, "shutting down"); @@ -1441,6 +1451,37 @@ on_readline_next_buffer (int count, int key) return 0; } +static int +on_readline_return (int count, int key) +{ + (void) count; + (void) key; + + struct app_context *ctx = g_ctx; + + // Let readline pass the line to our input handler + rl_done = 1; + + // Save readline state + int saved_point = rl_point; + int saved_mark = rl_mark; + char *saved_line = rl_copy_text (0, rl_end); + + // Erase the entire line from screen + rl_set_prompt (""); + rl_replace_line ("", 0); + rl_redisplay (); + ctx->readline_prompt_shown = false; + + // Restore readline state + rl_set_prompt (ctx->readline_prompt); + rl_replace_line (saved_line, 0); + rl_point = saved_point; + rl_mark = saved_mark; + free (saved_line); + return 0; +} + static int init_readline (void) { @@ -1464,6 +1505,8 @@ init_readline (void) rl_bind_keyseq ("\\M-p", rl_named_function ("previous-history")); rl_bind_keyseq ("\\M-n", rl_named_function ("next-history")); + rl_bind_key (RETURN, on_readline_return); + return 0; } @@ -2233,9 +2276,6 @@ on_tty_readable (const struct pollfd *fd, struct app_context *ctx) static void on_readline_input (char *line) { - // Otherwise the prompt is shown at all times - g_ctx->readline_prompt_shown = false; - if (line) { if (*line) @@ -2245,11 +2285,15 @@ on_readline_input (char *line) free (line); } else - // Anything better to do? - rl_crlf (); + { + app_readline_erase_to_bol (g_ctx->readline_prompt); + rl_ding (); + } - // initiate_quit() disables readline; we just wait then - if (!g_ctx->quitting) + if (g_ctx->quitting) + rl_callback_handler_remove (); + else + // initiate_quit() disables readline; we just wait then g_ctx->readline_prompt_shown = true; } @@ -2584,7 +2628,6 @@ main (int argc, char *argv[]) if (ctx.readline_prompt_shown) rl_callback_handler_remove (); - putchar ('\n'); app_context_free (&ctx); free_terminal (); -- cgit v1.2.3-70-g09d2