aboutsummaryrefslogtreecommitdiff
path: root/libbb/lineedit.c
diff options
context:
space:
mode:
Diffstat (limited to 'libbb/lineedit.c')
-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