From 65520f1901cee7bcad2871d47f62df2bbeac0126 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Sun, 17 Feb 2008 18:15:04 +0000 Subject: 24566: fix prompts with glitch spaces a bit more --- ChangeLog | 7 +++++++ Doc/Zsh/prompt.yo | 10 ++++++++++ Src/prompt.c | 31 ++++++++++++++++++++++++------- 3 files changed, 41 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 347743fe5..606f85e97 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2008-02-17 Peter Stephenson + + * 24566: Doc/Zsh/prompt.yo, Src/prompt.c: fallout: + fix truncation with glitch spaces; more careful + documentation; allow %N{...}; make unsupported + characters default to width 1. + 2008-02-15 Peter Stephenson * 24556: Doc/Zsh/prompt.yo, Src/prompt.c: %G inside %{...%} diff --git a/Doc/Zsh/prompt.yo b/Doc/Zsh/prompt.yo index 66e2b9015..29761140e 100644 --- a/Doc/Zsh/prompt.yo +++ b/Doc/Zsh/prompt.yo @@ -187,6 +187,9 @@ item(tt(%{)...tt(%}))( Include a string as a literal escape sequence. The string within the braces should not change the cursor position. Brace pairs can nest. + +A positive numeric argument between the tt(%) and the %%({) is treated as +described for tt(%G) below. ) item(tt(%G))( Within a tt(%{)...tt(%}) sequence, include a `glitch': that is, assume @@ -199,6 +202,13 @@ indicate the correct width. An integer between the `tt(%)' and `tt(G)' indicates a character width other than one. Hence tt(%{)var(seq)tt(%2G%}) outputs var(seq) and assumes it takes up the width of two standard characters. + +Multiple uses of tt(%G) accumulate in the obvious fashion; the position +of the tt(%G) is unimportant. Negative integers are not handled. + +Note that when prompt truncation is in use it is advisable to divide up +output into single characters within each tt(%{)...tt(%}) group so that +the correct truncation point can be found. ) enditem() diff --git a/Src/prompt.c b/Src/prompt.c index 54baf47ed..63b048083 100644 --- a/Src/prompt.c +++ b/Src/prompt.c @@ -472,7 +472,10 @@ putpromptchar(int doprint, int endchar) addbufspc(1); *bp++ = Inpar; } - break; + if (arg <= 0) + break; + /* else */ + /* FALLTHROUGH */ case 'G': if (arg > 0) { addbufspc(arg); @@ -948,9 +951,11 @@ countprompt(char *str, int *wp, int *hp, int overf) break; case MB_INVALID: memset(&mbs, 0, sizeof mbs); - /* FALL THROUGH */ + /* Invalid character: assume single width. */ + multi = 0; + w++; + break; case 0: - /* Invalid character or null: assume no output. */ multi = 0; break; default: @@ -1124,14 +1129,19 @@ prompttrunc(int arg, int truncchar, int doprint, int endchar) /* * Text marked as invisible: copy * regardless, since we don't know what - * this does but it shouldn't affect - * the width. + * this does. It only affects the width + * if there are Nularg's present. + * However, even in that case we + * can't break the sequence down, so + * we still loop over the entire group. */ for (;;) { *ptr++ = *fulltextptr; if (*fulltextptr == Outpar || *fulltextptr == '\0') break; + if (*fulltextptr == Nularg) + remw--; fulltextptr++; } } else { @@ -1206,8 +1216,15 @@ prompttrunc(int arg, int truncchar, int doprint, int endchar) while (maxwidth > 0 && *skiptext) { if (*skiptext == Inpar) { - for (; *skiptext != Outpar && *skiptext; - skiptext++); + /* see comment on left truncation above */ + for (;;) { + if (*skiptext == Outpar || + *skiptext == '\0') + break; + if (*skiptext == Nularg) + maxwidth--; + skiptext++; + } } else { #ifdef MULTIBYTE_SUPPORT char inchar; -- cgit 1.4.1