about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2008-02-17 18:15:04 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2008-02-17 18:15:04 +0000
commit65520f1901cee7bcad2871d47f62df2bbeac0126 (patch)
tree2bd0452a50c5168bbd1e5ae5a539cacff79d0a30
parent7da98c51246f245cde16cddb9b418afcfb3b3574 (diff)
downloadzsh-65520f1901cee7bcad2871d47f62df2bbeac0126.tar.gz
zsh-65520f1901cee7bcad2871d47f62df2bbeac0126.tar.xz
zsh-65520f1901cee7bcad2871d47f62df2bbeac0126.zip
24566: fix prompts with glitch spaces a bit more
-rw-r--r--ChangeLog7
-rw-r--r--Doc/Zsh/prompt.yo10
-rw-r--r--Src/prompt.c31
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  <p.w.stephenson@ntlworld.com>
+
+	* 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  <p.w.stephenson@ntlworld.com>
 
 	* 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;