From 48eb95998b4b1b34e0d2989c640994b8ee0b0138 Mon Sep 17 00:00:00 2001 From: "Alan C. Assis" Date: Wed, 22 Jul 2026 09:26:32 +0000 Subject: [PATCH] readline: Make prompt-caching available readline cached the current prompt only when TAB completion was enabled, even though line-editing redraws also depend on that cached prompt. With TAB completion disabled, full-line redraws erased the prompt and repainted only the command buffer. Make the prompt cache available whenever line editing is enabled. Signed-off-by: Alan C. Assis --- include/system/readline.h | 7 ++++--- nshlib/nsh_session.c | 2 +- system/readline/readline_common.c | 35 ++++++++++++++++++++----------- 3 files changed, 28 insertions(+), 16 deletions(-) diff --git a/include/system/readline.h b/include/system/readline.h index 5ab963879..8f40c92c1 100644 --- a/include/system/readline.h +++ b/include/system/readline.h @@ -88,8 +88,9 @@ extern "C" * * If a prompt string is used by the application, then the application * must provide the prompt string to readline() by calling this function. - * This is needed only for tab completion in cases where is it necessary - * to reprint the prompt string. + * This is needed for tab completion, and for line editing's full-line + * redraws (Home, End, history recall, ...), in cases where it is + * necessary to reprint the prompt string. * * Input Parameters: * prompt - The prompt string. This function may then be @@ -108,7 +109,7 @@ extern "C" * ****************************************************************************/ -#ifdef CONFIG_READLINE_TABCOMPLETION +#if defined(CONFIG_READLINE_TABCOMPLETION) || defined(CONFIG_READLINE_EDIT) FAR const char *readline_prompt(FAR const char *prompt); #else # define readline_prompt(p) diff --git a/nshlib/nsh_session.c b/nshlib/nsh_session.c index 4dd316a9d..acacb0f54 100644 --- a/nshlib/nsh_session.c +++ b/nshlib/nsh_session.c @@ -223,7 +223,7 @@ int nsh_session(FAR struct console_stdio_s *pstate, write(OUTFD(pstate), nsh_prompt(), strlen(nsh_prompt())); -#ifdef CONFIG_READLINE_TABCOMPLETION +#if defined(CONFIG_READLINE_TABCOMPLETION) || defined(CONFIG_READLINE_EDIT) /* Set the prompt so readline can redraw it for editing features */ readline_prompt(nsh_prompt()); diff --git a/system/readline/readline_common.c b/system/readline/readline_common.c index c1857cd48..3345a6624 100644 --- a/system/readline/readline_common.c +++ b/system/readline/readline_common.c @@ -73,8 +73,15 @@ struct cmdhist_s static const char g_erasetoeol[] = VT100_CLEAREOL; #endif #ifdef CONFIG_READLINE_EDIT -static const char g_curleft[] = {ASCII_ESC, '[', 'D'}; -static const char g_curright[] = {ASCII_ESC, '[', 'C'}; +static const char g_curleft[] = + { + ASCII_ESC, '[', 'D' + }; + +static const char g_curright[] = + { + ASCII_ESC, '[', 'C' + }; #endif #ifdef CONFIG_READLINE_EDIT_EMACS @@ -94,15 +101,20 @@ static const char g_curright[] = {ASCII_ESC, '[', 'C'}; # endif #endif -#ifdef CONFIG_READLINE_TABCOMPLETION -/* Prompt string to present at the beginning of the line */ +#if defined(CONFIG_READLINE_TABCOMPLETION) || defined(CONFIG_READLINE_EDIT) +/* Prompt string to present at the beginning of the line. Needed by tab + * completion (to reprint the prompt after listing multiple matches) and + * by line editing's full-line redraws (Home, End, history recall, ...), + * so this is available whenever either feature is enabled, not just + * when both are. + */ static FAR const char *g_readline_prompt = NULL; +#endif -#ifdef CONFIG_READLINE_HAVE_EXTMATCH +#if defined(CONFIG_READLINE_TABCOMPLETION) && defined(CONFIG_READLINE_HAVE_EXTMATCH) static FAR const struct extmatch_vtable_s *g_extmatch_vtbl = NULL; #endif -#endif /* CONFIG_READLINE_TABCOMPLETION */ #ifdef CONFIG_READLINE_CMD_HISTORY static struct cmdhist_s g_cmdhist; @@ -559,7 +571,6 @@ static void redraw_line(FAR struct rl_common_s *vtbl, FAR const char *buf, RL_PUTC(vtbl, '\r'); RL_WRITE(vtbl, g_erasetoeol, sizeof(g_erasetoeol)); -#ifdef CONFIG_READLINE_TABCOMPLETION if (g_readline_prompt != NULL) { for (i = 0; g_readline_prompt[i] != '\0'; i++) @@ -567,7 +578,6 @@ static void redraw_line(FAR struct rl_common_s *vtbl, FAR const char *buf, RL_PUTC(vtbl, g_readline_prompt[i]); } } -#endif if (nch > 0) { @@ -731,8 +741,9 @@ static ssize_t submit_line(FAR char *buf, int nch) * * If a prompt string is used by the application, then the application * must provide the prompt string to readline() by calling this function. - * This is needed only for tab completion in cases where is it necessary - * to reprint the prompt string. + * This is needed for tab completion, and for line editing's full-line + * redraws (Home, End, history recall, ...), in cases where it is + * necessary to reprint the prompt string. * * Input Parameters: * prompt - The prompt string. This function may then be @@ -751,7 +762,7 @@ static ssize_t submit_line(FAR char *buf, int nch) * ****************************************************************************/ -#ifdef CONFIG_READLINE_TABCOMPLETION +#if defined(CONFIG_READLINE_TABCOMPLETION) || defined(CONFIG_READLINE_EDIT) FAR const char *readline_prompt(FAR const char *prompt) { FAR const char *ret = g_readline_prompt; @@ -1188,7 +1199,7 @@ ssize_t readline_common(FAR struct rl_common_s *vtbl, FAR char *buf, #ifdef CONFIG_READLINE_ECHO RL_PUTC(vtbl, '\r'); RL_WRITE(vtbl, g_erasetoeol, sizeof(g_erasetoeol)); -#ifdef CONFIG_READLINE_TABCOMPLETION +#if defined(CONFIG_READLINE_TABCOMPLETION) || defined(CONFIG_READLINE_EDIT) if (g_readline_prompt != NULL) { int k;