aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2013-08-19 16:45:04 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2013-08-19 16:45:04 +0200
commite66a56de23fd08907f324d79e61ed2930ea5c350 (patch)
tree8cca369a09ef4f638d79c0153c10da2ca8b22928
parent7a18043a968ec6d4b8c4c8cac059ad977d14e47c (diff)
downloadbusybox-w32-e66a56de23fd08907f324d79e61ed2930ea5c350.tar.gz
busybox-w32-e66a56de23fd08907f324d79e61ed2930ea5c350.tar.bz2
busybox-w32-e66a56de23fd08907f324d79e61ed2930ea5c350.zip
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>
-rw-r--r--libbb/lineedit.c44
1 files changed, 30 insertions, 14 deletions
diff --git a/libbb/lineedit.c b/libbb/lineedit.c
index ecf3066b1..b3f16cd9d 100644
--- a/libbb/lineedit.c
+++ b/libbb/lineedit.c
@@ -38,6 +38,14 @@
38 * and the \] escape to signal the end of such a sequence. Example: 38 * and the \] escape to signal the end of such a sequence. Example:
39 * 39 *
40 * PS1='\[\033[01;32m\]\u@\h\[\033[01;34m\] \w \$\[\033[00m\] ' 40 * PS1='\[\033[01;32m\]\u@\h\[\033[01;34m\] \w \$\[\033[00m\] '
41 *
42 * Unicode in PS1 is not fully supported: prompt length calulation is wrong,
43 * resulting in line wrap problems with long (multi-line) input.
44 *
45 * Multi-line PS1 (e.g. PS1="\n[\w]\n$ ") has problems with history
46 * browsing: up/down arrows result in scrolling.
47 * It stems from simplistic "cmdedit_y = cmdedit_prmt_len / cmdedit_termw"
48 * calculation of how many lines the prompt takes.
41 */ 49 */
42#include "libbb.h" 50#include "libbb.h"
43#include "unicode.h" 51#include "unicode.h"
@@ -1759,34 +1767,36 @@ static void ask_terminal(void)
1759#define ask_terminal() ((void)0) 1767#define ask_terminal() ((void)0)
1760#endif 1768#endif
1761 1769
1770/* Called just once at read_line_input() init time */
1762#if !ENABLE_FEATURE_EDITING_FANCY_PROMPT 1771#if !ENABLE_FEATURE_EDITING_FANCY_PROMPT
1763static void parse_and_put_prompt(const char *prmt_ptr) 1772static void parse_and_put_prompt(const char *prmt_ptr)
1764{ 1773{
1774 const char *p;
1765 cmdedit_prompt = prmt_ptr; 1775 cmdedit_prompt = prmt_ptr;
1766 cmdedit_prmt_len = unicode_strlen(prmt_ptr); 1776 p = strrchr(prmt_ptr, '\n');
1777 cmdedit_prmt_len = unicode_strlen(p ? p+1 : prmt_ptr);
1767 put_prompt(); 1778 put_prompt();
1768} 1779}
1769#else 1780#else
1770static void parse_and_put_prompt(const char *prmt_ptr) 1781static void parse_and_put_prompt(const char *prmt_ptr)
1771{ 1782{
1772 int prmt_len = 0; 1783 int prmt_size = 0;
1773 size_t cur_prmt_len = 0;
1774 char flg_not_length = '[';
1775 char *prmt_mem_ptr = xzalloc(1); 1784 char *prmt_mem_ptr = xzalloc(1);
1776# if ENABLE_USERNAME_OR_HOMEDIR 1785# if ENABLE_USERNAME_OR_HOMEDIR
1777 char *cwd_buf = NULL; 1786 char *cwd_buf = NULL;
1778# endif 1787# endif
1779 char timebuf[sizeof("HH:MM:SS")]; 1788 char flg_not_length = '[';
1780 char cbuf[2]; 1789 char cbuf[2];
1781 char c;
1782 char *pbuf;
1783 1790
1784 /*cmdedit_prmt_len = 0; - already is */ 1791 /*cmdedit_prmt_len = 0; - already is */
1785 1792
1786 cbuf[1] = '\0'; /* never changes */ 1793 cbuf[1] = '\0'; /* never changes */
1787 1794
1788 while (*prmt_ptr) { 1795 while (*prmt_ptr) {
1796 char timebuf[sizeof("HH:MM:SS")];
1789 char *free_me = NULL; 1797 char *free_me = NULL;
1798 char *pbuf;
1799 char c;
1790 1800
1791 pbuf = cbuf; 1801 pbuf = cbuf;
1792 c = *prmt_ptr++; 1802 c = *prmt_ptr++;
@@ -1924,16 +1934,22 @@ static void parse_and_put_prompt(const char *prmt_ptr)
1924 } /* if */ 1934 } /* if */
1925 } /* if */ 1935 } /* if */
1926 cbuf[0] = c; 1936 cbuf[0] = c;
1927 cur_prmt_len = strlen(pbuf); 1937 {
1928 prmt_len += cur_prmt_len; 1938 int n = strlen(pbuf);
1929 if (flg_not_length != ']') { 1939 prmt_size += n;
1930#if 0 /*ENABLE_UNICODE_SUPPORT - won't work, pbuf is one BYTE string here. FIXME */ 1940 if (c == '\n')
1931 cmdedit_prmt_len += unicode_strlen(pbuf); 1941 cmdedit_prmt_len = 0;
1942 else if (flg_not_length != ']') {
1943#if 0 /*ENABLE_UNICODE_SUPPORT*/
1944/* Won't work, pbuf is one BYTE string here instead of an one Unicode char string. */
1945/* FIXME */
1946 cmdedit_prmt_len += unicode_strlen(pbuf);
1932#else 1947#else
1933 cmdedit_prmt_len += cur_prmt_len; 1948 cmdedit_prmt_len += n;
1934#endif 1949#endif
1950 }
1935 } 1951 }
1936 prmt_mem_ptr = strcat(xrealloc(prmt_mem_ptr, prmt_len+1), pbuf); 1952 prmt_mem_ptr = strcat(xrealloc(prmt_mem_ptr, prmt_size+1), pbuf);
1937 free(free_me); 1953 free(free_me);
1938 } /* while */ 1954 } /* while */
1939 1955