summaryrefslogtreecommitdiff
path: root/Src/prompt.c
diff options
context:
space:
mode:
authorromkatv <roman.perepelitsa@gmail.com>2019-06-19 12:16:41 +0200
committerPeter Stephenson <p.stephenson@samsung.com>2019-06-19 15:56:05 +0100
commit80aa807a61cf10ebf459ba8e06621a5ec33041dc (patch)
tree16893e03df10802a9c1a520fa049702c6c9ee13a /Src/prompt.c
parenteaba3ab2da714d09754a49eaaf4402268d95e5cb (diff)
downloadzsh-80aa807a61cf10ebf459ba8e06621a5ec33041dc.tar.gz
zsh-80aa807a61cf10ebf459ba8e06621a5ec33041dc.zip
fix multiple bugs in countprompt
1. Height off by one in the presence of meta characters at the end of the line. The following prompt has height 2 but countprompt used to return 3. PROMPT="${(pl.$COLUMNS..-.)}%f"$'\n' You can observe the effects of the bug with esc-x followed by reset-prompt. 2. Width off by one when a line is broken in the middle of a wide character. Assuming COLUMNS=79, the following prompt has width 2 but countprompt used to return 0. PROMPT="${(pl.40..\u3050.)}" zsh -df Press ctrl-r or type ls<tab> to observe the effects of the bug. 3. Width off by 1-7 when a line is broken in the middle of a tab. Assuming COLUMNS=79, the following prompt has width 1 but countprompt used to return 0. PROMPT="${(pl.10..\t.)}" zsh -df Press Ctrl-R or type ls<TAB> to observe the effects of the bug.
Diffstat (limited to 'Src/prompt.c')
-rw-r--r--Src/prompt.c35
1 files changed, 27 insertions, 8 deletions
diff --git a/Src/prompt.c b/Src/prompt.c
index e8d50d161..7f4d7a70e 100644
--- a/Src/prompt.c
+++ b/Src/prompt.c
@@ -1075,10 +1075,9 @@ putstr(int d)
mod_export void
countprompt(char *str, int *wp, int *hp, int overf)
{
- int w = 0, h = 1, multi = 0;
+ int w = 0, h = 1, multi = 0, wcw = 0;
int s = 1;
#ifdef MULTIBYTE_SUPPORT
- int wcw;
char inchar;
mbstate_t mbs;
wchar_t wc;
@@ -1092,10 +1091,23 @@ countprompt(char *str, int *wp, int *hp, int overf)
* prompt and the line it terminates takes up exactly the width of the
* terminal
*/
- if (w >= zterm_columns && overf >= 0 && !multi && *str != '\n') {
- w = 0;
+ while (w > zterm_columns && overf >= 0 && !multi) {
h++;
+ if (wcw) {
+ /*
+ * Wide characters don't get split off. They move to the
+ * next line if there is not enough space.
+ */
+ w = wcw;
+ break;
+ } else {
+ /*
+ * Tabs overflow to the next line as if they were made of spaces.
+ */
+ w -= zterm_columns;
+ }
}
+ wcw = 0;
/*
* Input string should be metafied, so tokens in it should
* be real tokens, even if there are multibyte characters.
@@ -1176,12 +1188,19 @@ countprompt(char *str, int *wp, int *hp, int overf)
* This isn't easy to handle generally; just assume there's no
* output.
*/
- if(w >= zterm_columns && overf >= 0) {
- if (!overf || w > zterm_columns) {
- w = 0;
- h++;
+ while (w > zterm_columns && overf >= 0) {
+ h++;
+ if (wcw) {
+ w = wcw;
+ break;
+ } else {
+ w -= zterm_columns;
}
}
+ if (w == zterm_columns && overf == 0) {
+ w = 0;
+ h++;
+ }
if(wp)
*wp = w;
if(hp)