From 7ebe10128eef978e99667d741ed4588d80b38441 Mon Sep 17 00:00:00 2001 From: Robbie Harwood Date: Thu, 21 Oct 2021 15:15:33 -0400 Subject: [PATCH] Fix backspace when editing a multiline cmdline Once the cmdline had passed the width of the screen, adding additional characters introduced a spurious newline, and another newline at the width of input. Furthermore, hitting backspace would not start redrawing at the end of input, but rather at the beginning of the current line - resulting in extra duplicate lines scrolling the console. First, fix the assumption that the length of cmdline is the width - it needs to include the length of the prompt (i.e., length of input and space). Second, fix the behavior of single-line redraw (i.e., redraw == 1) to move the cursor to the row the line begins at. Third, don't scroll the cursor down when a line wrap would occur - it's not necessary since line wrap is enabled, and results in the extra blank line. Finally, comment all used escape sequences so that I don't need to look them up again. Signed-off-by: Robbie Harwood --- com32/elflink/ldlinux/cli.c | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/com32/elflink/ldlinux/cli.c b/com32/elflink/ldlinux/cli.c index 3119b11f..4913f038 100644 --- a/com32/elflink/ldlinux/cli.c +++ b/com32/elflink/ldlinux/cli.c @@ -135,6 +135,7 @@ const char *edit_cmdline(const char *input, int top /*, int width */ , struct cli_command *comm_counter = NULL; clock_t kbd_to = kbdtimeout; clock_t tto = totaltimeout; + int prompt_len = 1 + strlen(input); if (!width) { int height; @@ -144,7 +145,7 @@ const char *edit_cmdline(const char *input, int top /*, int width */ , len = cursor = 0; prev_len = 0; - x = y = 0; + y = 0; /* * Before we start messing with the x,y coordinates print 'input' @@ -152,6 +153,7 @@ const char *edit_cmdline(const char *input, int top /*, int width */ , * previously. */ printf("%s ", input); + x = prompt_len; while (!done) { if (redraw > 1) { @@ -162,8 +164,7 @@ const char *edit_cmdline(const char *input, int top /*, int width */ , if (pDraw_Menu) (*pDraw_Menu) (-1, top, 1); prev_len = 0; - printf("\033[2J\033[H"); - // printf("\033[0m\033[2J\033[H"); + printf("\033[2J\033[H"); /* Clear entire screen; move to 0, 0. */ } if (redraw > 0) { @@ -172,10 +173,14 @@ const char *edit_cmdline(const char *input, int top /*, int width */ , prev_len = max(len, prev_len); /* Redraw the command line */ - printf("\033[?25l"); - printf("\033[1G%s ", input); + printf("\033[?25l"); /* Hide cursor. */ + printf("\033[1G"); /* Column 1. */ + if (y > 0) + printf("\033[%dA", y); /* Directly up. */ - x = strlen(input); + printf("%s ", input); + + x = prompt_len; y = 0; at = 0; while (at < prev_len) { @@ -183,23 +188,22 @@ const char *edit_cmdline(const char *input, int top /*, int width */ , at++; x++; if (x >= width) { - printf("\r\n"); x = 0; y++; } } - printf("\033[K\r"); + printf("\033[K\r"); /* Clear to end of line; go to beginning. */ - dy = y - (cursor + strlen(input) + 1) / width; - x = (cursor + strlen(input) + 1) % width; + dy = y - (cursor + prompt_len) / width; + x = (cursor + prompt_len) % width; if (dy) { - printf("\033[%dA", dy); + printf("\033[%dA", dy); /* Cursor directly up. */ y -= dy; } if (x) - printf("\033[%dC", x); - printf("\033[?25h"); + printf("\033[%dC", x); /* Cursor forward. */ + printf("\033[?25h"); /* Show cursor. */ prev_len = len; redraw = 0; } @@ -439,7 +443,6 @@ const char *edit_cmdline(const char *input, int top /*, int width */ , cursor++; x++; if (x >= width) { - printf("\r\n\033[K"); y++; x = 0; } @@ -459,7 +462,7 @@ const char *edit_cmdline(const char *input, int top /*, int width */ , } } - printf("\033[?7h"); + printf("\033[?7h"); /* Enable line wrap. */ /* Add the command to the history if its length is larger than 0 */ len = strlen(ret); -- 2.33.0