From 91db8e6e5477013ee034afd3d6bfa48faed5e2b8 Mon Sep 17 00:00:00 2001 From: Přemysl Eric Janouch Date: Mon, 29 Aug 2022 10:29:49 +0200 Subject: xC: use the correct way of resetting libedit The only remaining major annoyance is incremental search seemingly not giving back control. --- xC.c | 51 +++++++++++++-------------------------------------- 1 file changed, 13 insertions(+), 38 deletions(-) diff --git a/xC.c b/xC.c index c784bba..74f34e3 100644 --- a/xC.c +++ b/xC.c @@ -761,7 +761,6 @@ struct input_el { struct input super; ///< Parent class EditLine *editline; ///< The EditLine object - FILE *null; ///< Output redirect bool active; ///< Are we a thing? char *prompt; ///< The prompt we use @@ -1027,39 +1026,16 @@ input_el__restore (struct input_el *self) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// XXX: Editline keeping its own history position (look for "eventno" there). -// Invoking ed-next-history through our bind from app_editline_init() seems -// like the only viable hack to get consistent history behaviour. +// Editline keeping its own history position (look for "eventno" there). +// This is the only sane way of resetting it. static void -input_el__bottom (struct input_el *self) +input_el__start_over (struct input_el *self) { - // First, we need to redirect output to avoid ringing the terminal bell. - // Assuming that the line has just been erased but not redisplayed - // by caller, we need to CC_REFRESH first. - input_el__redisplay (self); - - FILE *out = NULL; - el_wget (self->editline, EL_GETFP, 1, &out); - el_wset (self->editline, EL_SETFP, 1, self->null); + wchar_t x[] = { L'g' & 31, 0 }; + el_wpush (self->editline, x); - // Invoke hist_get() to make the history pointer's cursor match "eventno". - int down = 1, dummy_count = 0; - el_wpush (self->editline, L"\x1bn"); + int dummy_count = 0; (void) el_wgets (self->editline, &dummy_count); - - // It doesn't seem like we can just retrieve the position. - HistEventW ev; - while (!history_w (self->current->history, &ev, H_PREV)) - down++; - while (down--) - { - el_wpush (self->editline, L"\x1bn"); - (void) el_wgets (self->editline, &dummy_count); - } - - // Otherwise input may survive our erasing, reproducer: a^Rb^[^N - input_el_clear_line (self); - el_wset (self->editline, EL_SETFP, 1, out); } static void @@ -1075,7 +1051,7 @@ input_el_buffer_switch (void *input, input_buffer_t input_buffer) self->current = buffer; el_wset (self->editline, EL_HIST, history, buffer->history); - input_el__bottom (self); + input_el__start_over (self); input_el__restore_buffer (self, buffer); } @@ -1170,7 +1146,6 @@ input_el_destroy (void *input) free (iter->help); ffi_closure_free (iter); } - fclose (self->null); free (self->prompt); free (self); } @@ -1184,7 +1159,6 @@ input_el_new (void) { struct input_el *self = xcalloc (1, sizeof *self); self->super.vtable = &input_el_vtable; - self->null = fopen ("/dev/null", "w"); return &self->super; } @@ -13947,8 +13921,6 @@ on_editline_return (EditLine *editline, int key) const LineInfoW *info = el_wline (editline); int len = info->lastchar - info->buffer; - int point = info->cursor - info->buffer; - wchar_t *line = calloc (sizeof *info->buffer, len + 1); memcpy (line, info->buffer, sizeof *info->buffer * len); @@ -13965,9 +13937,8 @@ on_editline_return (EditLine *editline, int key) 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); - input_el__bottom (self); + // We must invoke ch_reset(), which isn't done for us with EL_UNBUFFERED. + input_el__start_over (self); return CC_REFRESH; } @@ -13992,8 +13963,12 @@ app_editline_init (struct input_el *self) CALL_ (input, bind_control, 'w', "ed-delete-prev-word"); // Just what are you doing? CALL_ (input, bind_control, 'u', "vi-kill-line-prev"); + // See input_el__redisplay(), functionally important CALL_ (input, bind_control, 'q', "ed-redisplay"); + // This is what buffered el_wgets() does, functionally important; + // perhaps it could be bound somewhere more appropriate + CALL_ (input, bind_control, 'g', "ed-start-over"); // We need to hide the prompt and input first CALL_ (input, bind, "\r", "send-line"); -- cgit v1.2.3-70-g09d2