diff --git a/degesch.c b/degesch.c index a2a0d23..de04bea 100644 --- a/degesch.c +++ b/degesch.c @@ -1532,6 +1532,9 @@ struct app_context struct input input; ///< User interface + struct poller_idle input_event; ///< Pending input event + struct str_vector pending_input; ///< Pending input lines + int *nick_palette; ///< A 256-color palette for nicknames size_t nick_palette_len; ///< Number of entries in nick_palette @@ -1609,6 +1612,7 @@ app_context_init (struct app_context *self) free (encoding); input_init (&self->input); + str_vector_init (&self->pending_input); str_init (&self->input_buffer); self->nick_palette = @@ -1647,6 +1651,7 @@ app_context_free (struct app_context *self) iconv_close (self->term_to_utf8); input_free (&self->input); + str_vector_free (&self->pending_input); str_free (&self->input_buffer); free (self->editor_filename); @@ -11067,15 +11072,17 @@ on_readline_input (char *line) if (*line) add_history (line); - // Normally, the text is deleted _afterwards_ - rl_replace_line ("", false); - process_input (ctx, line); - free (line); + // readline always erases the input line after returning from here, + // but we don't want that in order to allow correct buffer switching + str_vector_add_owned (&ctx->pending_input, line); + poller_idle_set (&ctx->input_event); } else { + // Prevent readline from showing the prompt twice for w/e reason input_hide (&ctx->input); input_restore (&ctx->input); + input_ding (&ctx->input); } @@ -11324,10 +11331,9 @@ on_editline_return (EditLine *editline, int key) // process_input() expects a multibyte string const LineInfo *info_mb = el_line (editline); - char copy[info_mb->lastchar - info_mb->buffer + 1]; - memcpy (copy, info_mb->buffer, sizeof copy - 1); - copy[sizeof copy - 1] = '\0'; - process_input (ctx, copy); + str_vector_add_owned (&ctx->pending_input, + xstrndup (info_mb->buffer, info_mb->lastchar - info_mb->buffer)); + poller_idle_set (&ctx->input_event); el_cursor (editline, len - point); el_wdeletestr (editline, len); @@ -11873,6 +11879,15 @@ on_date_change_timer (struct app_context *ctx) rearm_date_change_timer (ctx); } +static void +on_pending_input (struct app_context *ctx) +{ + poller_idle_reset (&ctx->input_event); + for (size_t i = 0; i < ctx->pending_input.len; i++) + process_input (ctx, ctx->pending_input.vector[i]); + str_vector_reset (&ctx->pending_input); +} + static void init_poller_events (struct app_context *ctx) { @@ -11899,6 +11914,10 @@ init_poller_events (struct app_context *ctx) poller_timer_init (&ctx->autoaway_tmr, &ctx->poller); ctx->autoaway_tmr.dispatcher = (poller_timer_fn) on_autoaway_timer; ctx->autoaway_tmr.user_data = ctx; + + poller_idle_init (&ctx->input_event, &ctx->poller); + ctx->input_event.dispatcher = (poller_idle_fn) on_pending_input; + ctx->input_event.user_data = ctx; } // --- Tests -------------------------------------------------------------------