Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Count only visible characters?



On Thu, 8 Apr 2010 22:38:05 +0000 (UTC)
Seth House <seth@xxxxxxxxx> wrote:
> Is there any way to count only visible characters?
> 
>     testing="%F{green}hello"
>     echo ${(%)#testing}
> 
> The number I'm interested in is 5 not 14.
> 
> After an awful lot of Googling, I'm under the impression this isn't a trivial 
> problem.

That's correct, it isn't trivial using shell code.  (It's not *so* hard
to strip the various highlighting codes and %{ ... %} sections if you
want an exercise in shell programming.)  However, the code to do this
is already built into the shell itself, so making this available is a
straightforward change.  Note you need the `#' inside the
parentheses---the normal `#' is too long established for me to be keen
on changing its meaning even in combination with `(%)'.

print ${(%#):-%F{red}hello%f there}
11

I'm guessing there's no call for what this syntax previously meant,
doing prompt expansion on a string and then treating the result as a
numeric expression to give you a character.  I've spent too much of my
life finding new codes for substitution flags.  However, I'm open to
more imaginative suggestions.

Index: Doc/Zsh/expn.yo
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/expn.yo,v
retrieving revision 1.112
diff -p -u -r1.112 expn.yo
--- Doc/Zsh/expn.yo	27 Mar 2010 19:04:35 -0000	1.112
+++ Doc/Zsh/expn.yo	9 Apr 2010 19:38:28 -0000
@@ -729,6 +729,14 @@ entirely distinct from use of the tt(#) 
 
 If the tt(MULTIBYTE) option is set and the number is greater than 127
 (i.e. not an ASCII character) it is treated as a Unicode character.
+
+In combination with the tt(%) flag, described immediately below,
+this has a different meaning: the expanded prompt is replaced by
+the width of the string as it would appear on the screen in the same
+way as it would be calculated by the prompt code.  In other words,
+this takes account of tt(%{), tt(%}) and highlighting sequences in
+the string, but is not otherwise sensitive to embedded control
+sequences.
 )
 item(tt(%))(
 Expand all tt(%) escapes in the resulting words in the same way as in
Index: Src/subst.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/subst.c,v
retrieving revision 1.103
diff -p -u -r1.103 subst.c
--- Src/subst.c	9 Apr 2010 15:40:14 -0000	1.103
+++ Src/subst.c	9 Apr 2010 19:38:28 -0000
@@ -2660,7 +2660,7 @@ paramsubst(LinkList l, LinkNode n, char 
     }
     if (errflag)
 	return NULL;
-    if (evalchar) {
+    if (evalchar && !presc) {
 	int one = noerrs, oef = errflag, haserr = 0;
 
 	if (!quoteerr)
@@ -2801,6 +2801,7 @@ paramsubst(LinkList l, LinkNode n, char 
     if (presc) {
 	int ops = opts[PROMPTSUBST], opb = opts[PROMPTBANG];
 	int opp = opts[PROMPTPERCENT];
+	int width;
 
 	if (presc < 2) {
 	    opts[PROMPTPERCENT] = 1;
@@ -2823,17 +2824,33 @@ paramsubst(LinkList l, LinkNode n, char 
 	    for (; *ap; ap++) {
 		char *tmps;
 		untokenize(*ap);
-		tmps = promptexpand(*ap, 0, NULL, NULL, NULL);
-		*ap = dupstring(tmps);
+		tmps = promptexpand(*ap, evalchar, NULL, NULL, NULL);
+		if (evalchar) {
+		    char digbuf[DIGBUFSIZE];
+		    countprompt(tmps, &width, NULL, -1);
+		    sprintf(digbuf, "%d", width);
+		    *ap = dupstring(digbuf);
+		} else {
+		    *ap = dupstring(tmps);
+		}
 		free(tmps);
 	    }
 	} else {
 	    char *tmps;
-	    if (!copied)
-		val = dupstring(val), copied = 1;
+	    if (!copied) {
+		val = dupstring(val);
+		copied = 1;
+	    }
 	    untokenize(val);
-	    tmps = promptexpand(val, 0, NULL, NULL, NULL);
-	    val = dupstring(tmps);
+	    tmps = promptexpand(val, evalchar, NULL, NULL, NULL);
+	    if (evalchar) {
+		char digbuf[DIGBUFSIZE];
+		countprompt(tmps, &width, NULL, -1);
+		sprintf(digbuf, "%d", width);
+		val = dupstring(digbuf);
+	    } else {
+		val = dupstring(tmps);
+	    }
 	    free(tmps);
 	}
 	opts[PROMPTSUBST] = ops;


-- 
Peter Stephenson <p.w.stephenson@xxxxxxxxxxxx>
Web page now at http://homepage.ntlworld.com/p.w.stephenson/



Messages sorted by: Reverse Date, Date, Thread, Author