lineedit: fix multi-line PS1 handling: calculate PS1 length from last \n
function old new delta parse_and_put_prompt 755 774 +19 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
7a18043a96
commit
e66a56de23
@ -38,6 +38,14 @@
|
|||||||
* and the \] escape to signal the end of such a sequence. Example:
|
* and the \] escape to signal the end of such a sequence. Example:
|
||||||
*
|
*
|
||||||
* PS1='\[\033[01;32m\]\u@\h\[\033[01;34m\] \w \$\[\033[00m\] '
|
* PS1='\[\033[01;32m\]\u@\h\[\033[01;34m\] \w \$\[\033[00m\] '
|
||||||
|
*
|
||||||
|
* Unicode in PS1 is not fully supported: prompt length calulation is wrong,
|
||||||
|
* resulting in line wrap problems with long (multi-line) input.
|
||||||
|
*
|
||||||
|
* Multi-line PS1 (e.g. PS1="\n[\w]\n$ ") has problems with history
|
||||||
|
* browsing: up/down arrows result in scrolling.
|
||||||
|
* It stems from simplistic "cmdedit_y = cmdedit_prmt_len / cmdedit_termw"
|
||||||
|
* calculation of how many lines the prompt takes.
|
||||||
*/
|
*/
|
||||||
#include "libbb.h"
|
#include "libbb.h"
|
||||||
#include "unicode.h"
|
#include "unicode.h"
|
||||||
@ -1759,34 +1767,36 @@ static void ask_terminal(void)
|
|||||||
#define ask_terminal() ((void)0)
|
#define ask_terminal() ((void)0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Called just once at read_line_input() init time */
|
||||||
#if !ENABLE_FEATURE_EDITING_FANCY_PROMPT
|
#if !ENABLE_FEATURE_EDITING_FANCY_PROMPT
|
||||||
static void parse_and_put_prompt(const char *prmt_ptr)
|
static void parse_and_put_prompt(const char *prmt_ptr)
|
||||||
{
|
{
|
||||||
|
const char *p;
|
||||||
cmdedit_prompt = prmt_ptr;
|
cmdedit_prompt = prmt_ptr;
|
||||||
cmdedit_prmt_len = unicode_strlen(prmt_ptr);
|
p = strrchr(prmt_ptr, '\n');
|
||||||
|
cmdedit_prmt_len = unicode_strlen(p ? p+1 : prmt_ptr);
|
||||||
put_prompt();
|
put_prompt();
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
static void parse_and_put_prompt(const char *prmt_ptr)
|
static void parse_and_put_prompt(const char *prmt_ptr)
|
||||||
{
|
{
|
||||||
int prmt_len = 0;
|
int prmt_size = 0;
|
||||||
size_t cur_prmt_len = 0;
|
|
||||||
char flg_not_length = '[';
|
|
||||||
char *prmt_mem_ptr = xzalloc(1);
|
char *prmt_mem_ptr = xzalloc(1);
|
||||||
# if ENABLE_USERNAME_OR_HOMEDIR
|
# if ENABLE_USERNAME_OR_HOMEDIR
|
||||||
char *cwd_buf = NULL;
|
char *cwd_buf = NULL;
|
||||||
# endif
|
# endif
|
||||||
char timebuf[sizeof("HH:MM:SS")];
|
char flg_not_length = '[';
|
||||||
char cbuf[2];
|
char cbuf[2];
|
||||||
char c;
|
|
||||||
char *pbuf;
|
|
||||||
|
|
||||||
/*cmdedit_prmt_len = 0; - already is */
|
/*cmdedit_prmt_len = 0; - already is */
|
||||||
|
|
||||||
cbuf[1] = '\0'; /* never changes */
|
cbuf[1] = '\0'; /* never changes */
|
||||||
|
|
||||||
while (*prmt_ptr) {
|
while (*prmt_ptr) {
|
||||||
|
char timebuf[sizeof("HH:MM:SS")];
|
||||||
char *free_me = NULL;
|
char *free_me = NULL;
|
||||||
|
char *pbuf;
|
||||||
|
char c;
|
||||||
|
|
||||||
pbuf = cbuf;
|
pbuf = cbuf;
|
||||||
c = *prmt_ptr++;
|
c = *prmt_ptr++;
|
||||||
@ -1924,16 +1934,22 @@ static void parse_and_put_prompt(const char *prmt_ptr)
|
|||||||
} /* if */
|
} /* if */
|
||||||
} /* if */
|
} /* if */
|
||||||
cbuf[0] = c;
|
cbuf[0] = c;
|
||||||
cur_prmt_len = strlen(pbuf);
|
{
|
||||||
prmt_len += cur_prmt_len;
|
int n = strlen(pbuf);
|
||||||
if (flg_not_length != ']') {
|
prmt_size += n;
|
||||||
#if 0 /*ENABLE_UNICODE_SUPPORT - won't work, pbuf is one BYTE string here. FIXME */
|
if (c == '\n')
|
||||||
cmdedit_prmt_len += unicode_strlen(pbuf);
|
cmdedit_prmt_len = 0;
|
||||||
|
else if (flg_not_length != ']') {
|
||||||
|
#if 0 /*ENABLE_UNICODE_SUPPORT*/
|
||||||
|
/* Won't work, pbuf is one BYTE string here instead of an one Unicode char string. */
|
||||||
|
/* FIXME */
|
||||||
|
cmdedit_prmt_len += unicode_strlen(pbuf);
|
||||||
#else
|
#else
|
||||||
cmdedit_prmt_len += cur_prmt_len;
|
cmdedit_prmt_len += n;
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
prmt_mem_ptr = strcat(xrealloc(prmt_mem_ptr, prmt_len+1), pbuf);
|
prmt_mem_ptr = strcat(xrealloc(prmt_mem_ptr, prmt_size+1), pbuf);
|
||||||
free(free_me);
|
free(free_me);
|
||||||
} /* while */
|
} /* while */
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user