From 074b378f03ad9b3361ff276d3722e059ab4ac30e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C5=99emysl=20Eric=20Janouch?=
Date: Tue, 11 Aug 2026 09:37:30 +0200 Subject: [PATCH] xC/fancy-prompt.lua: remove old Readline hacks --- plugins/xC/fancy-prompt.lua | 30 +++++------------------------- xC.c | 18 +++++++++++++----- 2 files changed, 18 insertions(+), 30 deletions(-) diff --git a/plugins/xC/fancy-prompt.lua b/plugins/xC/fancy-prompt.lua index 0b7000c..322a6bc 100644 --- a/plugins/xC/fancy-prompt.lua +++ b/plugins/xC/fancy-prompt.lua @@ -14,19 +14,7 @@ -- OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -- CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -- --- Beware that it is a hack and only goes about 90% of the way, which is why --- this functionality is only available as a plugin in the first place --- (well, and also for customizability). --- --- The biggest problem is that the way we work with Readline is incompatible --- with multiline prompts, and normal newlines just don't work. This is being --- circumvented by using an overflowing single-line prompt with a specially --- crafted character in the rightmost column that prevents the bar's background --- from spilling all over the last line. --- --- There is also a problem with C-r search rendering not clearing out the --- background but to really fix that mode, we'd have to fully reimplement it --- since its alternative prompt very often gets overriden by accident anyway. +-- This might go directly to xC, though it's more customizable as a plugin. xC.hook_prompt (function (hook) local current = xC.current_buffer @@ -67,11 +55,7 @@ xC.hook_prompt (function (hook) x = x .. " (" .. active:sub (2) .. ")" end - -- Readline 7.0.003 seems to be broken and completely corrupts the prompt. - -- However 8.0.004 seems to be fine with these, as is libedit 20191231-3.1. - --x = x:gsub("[\128-\255]", "?") - - -- Align to the terminal's width and apply formatting, including the hack. + -- Align to the terminal's width and apply formatting. local lines, cols = xC.get_screen_size () local trailing, width = " ", xC.measure (x) while cols > 0 and width >= cols do @@ -79,10 +63,10 @@ xC.hook_prompt (function (hook) trailing, width = ">", xC.measure (x) end + -- xC automatically smartly wraps the line. x = "\x01\x1b[0;4;1;38;5;16m\x1b[48;5;" .. bg_color .. "m\x02" .. - x .. string.rep (" ", cols - width - 1) .. - "\x01\x1b[0;4;1;7;38;5;" .. bg_color .. "m\x02" .. - trailing .. "\x01\x1b[0;1m\x02" + x .. string.rep (" ", cols - width - 1) .. trailing .. + "\x01\x1b[0;1m\x02" local user_prefix = function (chan, user) for i, chan_user in ipairs (chan.users) do @@ -104,10 +88,6 @@ xC.hook_prompt (function (hook) if modes ~= "" then x = x .. "(" .. modes .. ")" end end x = x .. "] " - else - -- There needs to be at least one character so that the cursor - -- doesn't get damaged by our hack in that last column - x = x .. "> " end return x end) diff --git a/xC.c b/xC.c index c091444..50c6cc6 100644 --- a/xC.c +++ b/xC.c @@ -314,7 +314,7 @@ input__redisplay (struct input *self) // Also preferrably avoid using input__str_tputs(), // though this requires continuous transcoding to the locale encoding. struct str prompt = str_make (); - bool passthrough = false; + bool passthrough = false, clear_line = false; struct input_pos pos = { .y = 0, .x = 0 }; const char *p = self->prompt; @@ -327,11 +327,17 @@ input__redisplay (struct input *self) passthrough = true; else if (ch == INPUT_END_IGNORE) passthrough = false; + else if (passthrough) + str_append_data (&prompt, p, ch_len); else { - if (passthrough) - ; - else if (ch == '\n') + // Let any passthrough sequences reset formatting first, + // so that this newline doesn't cause an unnecessary BCE on scroll. + if (clear_line) + str_append_c (&prompt, '\n'); + + clear_line = false; + if (ch == '\n') { pos.y++; pos.x = 0; @@ -340,11 +346,13 @@ input__redisplay (struct input *self) else // FIXME: Either convert from Unicode to wchar_t here, // or implement the algorithm ourselves. - input__adjust (&pos, wcwidth (ch)); + clear_line = input__adjust (&pos, wcwidth (ch)); str_append_data (&prompt, p, ch_len); } p += ch_len; } + if (clear_line) + str_append_c (&prompt, '\n'); if (self->y) putp (tparm (parm_up_cursor, self->y, 0, 0, 0, 0, 0, 0, 0, 0));