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

Re: input line changes colour after print -P %F



On Mon, 12 May 2008 14:07:53 +0200
"Mikael Magnusson" <mikachu@xxxxxxxxx> wrote:
> zsh -f
> autoload compinit; compinit
> zstyle ':completion:*:warnings' format ''
> print -P '%F{red}foo'
> asdasfasdasfasfasadasf<tab>
> 
> the last entered input now appears in red for me.

The basic feature of this has always been there.  This is part of the
difficult-to-follow attempt in the code to keep track of prompt formatting
across multiple line editor functions, which I am in any case uncomfortable
with and would like to move away from.

It's clear, I think, that it shouldn't be trying anything of that kind
except in the line editor.  This patch eliminates another instance of the
pathological fear of passing variables as parameters instead of globally
which seems to affect the shell.  The txtchange global variable disappears;
instead, the prompt attribute to be updated is passed directly to the
prompt code.

As I can't entirely follow what was happening to txtchange in all the
global changes, it's quite likely this works differently in some way or
another.  I've tried to preserve the basic flow by feeding in the left
prompt attributes and using the result to initialize the right prompt
attributes.  txtchange is now local in zrefresh(), so all attribute control
using the values from expanding the prompt is supposed to take place there.

I'm hoping, however, that suitable effects in zle_highlight will dispense
with the need for this altogether.

Index: Src/builtin.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/builtin.c,v
retrieving revision 1.192
diff -u -r1.192 builtin.c
--- Src/builtin.c	8 May 2008 12:07:06 -0000	1.192
+++ Src/builtin.c	12 May 2008 13:10:34 -0000
@@ -3571,8 +3571,10 @@
 	     * messy memory management, stick it on the heap
 	     * instead.
 	     */
-	    char *str = unmetafy(promptexpand(metafy(args[n], len[n],
-						     META_NOALLOC), 0, NULL, NULL), &len[n]);
+	    char *str = unmetafy(
+		promptexpand(metafy(args[n], len[n], META_NOALLOC),
+			     0, NULL, NULL, NULL),
+		&len[n]);
 	    args[n] = dupstrpfx(str, len[n]);
 	    free(str);
 	}
Index: Src/init.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/init.c,v
retrieving revision 1.84
diff -u -r1.84 init.c
--- Src/init.c	9 May 2008 17:33:51 -0000	1.84
+++ Src/init.c	12 May 2008 13:10:35 -0000
@@ -1237,7 +1237,8 @@
     char *pptbuf;
     int pptlen;
 
-    pptbuf = unmetafy(promptexpand(lp ? *lp : NULL, 0, NULL, NULL), &pptlen);
+    pptbuf = unmetafy(promptexpand(lp ? *lp : NULL, 0, NULL, NULL, NULL),
+		      &pptlen);
     write(2, (WRITE_ARG_2_T)pptbuf, pptlen);
     free(pptbuf);
 
Index: Src/input.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/input.c,v
retrieving revision 1.15
diff -u -r1.15 input.c
--- Src/input.c	8 Mar 2008 01:20:50 -0000	1.15
+++ Src/input.c	12 May 2008 13:10:35 -0000
@@ -256,7 +256,7 @@
 	    char *pptbuf;
 	    int pptlen;
 	    pptbuf = unmetafy(promptexpand(ingetcpmptl ? *ingetcpmptl : NULL,
-					   0, NULL, NULL), &pptlen);
+					   0, NULL, NULL, NULL), &pptlen);
 	    write(2, (WRITE_ARG_2_T)pptbuf, pptlen);
 	    free(pptbuf);
 	}
Index: Src/loop.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/loop.c,v
retrieving revision 1.23
diff -u -r1.23 loop.c
--- Src/loop.c	11 May 2008 19:55:21 -0000	1.23
+++ Src/loop.c	12 May 2008 13:10:35 -0000
@@ -250,7 +250,7 @@
 			str = NULL;
 		    errflag = oef;
 	    	} else {
-		    str = promptexpand(prompt3, 0, NULL, NULL);
+		    str = promptexpand(prompt3, 0, NULL, NULL, NULL);
 		    zputs(str, stderr);
 		    free(str);
 		    fflush(stderr);
@@ -552,7 +552,7 @@
 	next = state->pc + WC_CASE_SKIP(code);
 
 	if (isset(XTRACE)) {
-	    char *pat2, *opat;
+	    char *opat;
 
 	    pat = dupstring(opat = ecrawstr(state->prog, state->pc, NULL));
 	    singsub(&pat);
Index: Src/prompt.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/prompt.c,v
retrieving revision 1.49
diff -u -r1.49 prompt.c
--- Src/prompt.c	9 May 2008 17:41:57 -0000	1.49
+++ Src/prompt.c	12 May 2008 13:10:36 -0000
@@ -35,11 +35,6 @@
 /**/
 mod_export unsigned txtattrmask;
 
-/* text change - attribute change made by prompts */
-
-/**/
-mod_export unsigned txtchange;
-
 /* the command stack for use with %_ in prompts */
 
 /**/
@@ -144,16 +139,22 @@
 	zsfree(modp);
 }
 
-/* Perform prompt expansion on a string, putting the result in a *
- * permanently-allocated string.  If ns is non-zero, this string *
- * may have embedded Inpar and Outpar, which indicate a toggling *
- * between spacing and non-spacing parts of the prompt, and      *
- * Nularg, which (in a non-spacing sequence) indicates a         *
- * `glitch' space.                                               */
+/*
+ * Perform prompt expansion on a string, putting the result in a
+ * permanently-allocated string.  If ns is non-zero, this string
+ * may have embedded Inpar and Outpar, which indicate a toggling
+ * between spacing and non-spacing parts of the prompt, and
+ * Nularg, which (in a non-spacing sequence) indicates a
+ * `glitch' space.
+ *
+ * txtchangep gives an integer controlling the attributes of
+ * the prompt.  This is for use in zle to maintain the attributes
+ * consistenly.  Other parts of the shell should not need to use it.
+ */
 
 /**/
 mod_export char *
-promptexpand(char *s, int ns, char *rs, char *Rs)
+promptexpand(char *s, int ns, char *rs, char *Rs, unsigned int *txtchangep)
 {
     if(!s)
 	return ztrdup("");
@@ -180,7 +181,7 @@
     bp = bufline = buf = zshcalloc(bufspc = 256);
     bp1 = NULL;
     truncwidth = 0;
-    putpromptchar(1, '\0');
+    putpromptchar(1, '\0', txtchangep);
     addbufspc(2);
     if(dontcount)
 	*bp++ = Outpar;
@@ -205,7 +206,7 @@
 
 /**/
 static int
-putpromptchar(int doprint, int endchar)
+putpromptchar(int doprint, int endchar, unsigned int *txtchangep)
 {
     char *ss, *hostnam;
     int t0, arg, test, sep, j, numjobs;
@@ -336,8 +337,10 @@
 		/* Don't do the current truncation until we get back */
 		otruncwidth = truncwidth;
 		truncwidth = 0;
-		if (!putpromptchar(test == 1 && doprint, sep) || !*++fm ||
-		    !putpromptchar(test == 0 && doprint, ')')) {
+		if (!putpromptchar(test == 1 && doprint, sep,
+				   txtchangep) || !*++fm ||
+		    !putpromptchar(test == 0 && doprint, ')',
+				   txtchangep)) {
 		    truncwidth = otruncwidth;
 		    return 0;
 		}
@@ -421,34 +424,34 @@
 		unqueue_signals();
 		break;
 	    case 'S':
-		txtchangeset(TXTSTANDOUT, TXTNOSTANDOUT);
+		txtchangeset(txtchangep, TXTSTANDOUT, TXTNOSTANDOUT);
 		txtset(TXTSTANDOUT);
 		tsetcap(TCSTANDOUTBEG, TSC_PROMPT);
 		break;
 	    case 's':
-		txtchangeset(TXTNOSTANDOUT, TXTSTANDOUT);
+		txtchangeset(txtchangep, TXTNOSTANDOUT, TXTSTANDOUT);
 		txtunset(TXTSTANDOUT);
 		tsetcap(TCSTANDOUTEND, TSC_PROMPT|TSC_DIRTY);
 		break;
 	    case 'B':
-		txtchangeset(TXTBOLDFACE, TXTNOBOLDFACE);
+		txtchangeset(txtchangep, TXTBOLDFACE, TXTNOBOLDFACE);
 		txtset(TXTBOLDFACE);
 		tsetcap(TCBOLDFACEBEG, TSC_PROMPT|TSC_DIRTY);
 		break;
 	    case 'b':
-		txtchangeset(TXTNOBOLDFACE, TXTBOLDFACE);
-		txtchangeset(TXTNOSTANDOUT, TXTSTANDOUT);
-		txtchangeset(TXTNOUNDERLINE, TXTUNDERLINE);
+		txtchangeset(txtchangep, TXTNOBOLDFACE, TXTBOLDFACE);
+		txtchangeset(txtchangep, TXTNOSTANDOUT, TXTSTANDOUT);
+		txtchangeset(txtchangep, TXTNOUNDERLINE, TXTUNDERLINE);
 		txtunset(TXTBOLDFACE);
 		tsetcap(TCALLATTRSOFF, TSC_PROMPT|TSC_DIRTY);
 		break;
 	    case 'U':
-		txtchangeset(TXTUNDERLINE, TXTNOUNDERLINE);
+		txtchangeset(txtchangep, TXTUNDERLINE, TXTNOUNDERLINE);
 		txtset(TXTUNDERLINE);
 		tsetcap(TCUNDERLINEBEG, TSC_PROMPT);
 		break;
 	    case 'u':
-		txtchangeset(TXTNOUNDERLINE, TXTUNDERLINE);
+		txtchangeset(txtchangep, TXTNOUNDERLINE, TXTUNDERLINE);
 		txtunset(TXTUNDERLINE);
 		tsetcap(TCUNDERLINEEND, TSC_PROMPT|TSC_DIRTY);
 		break;
@@ -461,7 +464,7 @@
 		} else
 		    arg = match_colour(NULL, 1, arg);
 		if (arg >= 0 && !(arg & TXTNOFGCOLOUR)) {
-		    txtchangeset(arg & TXT_ATTR_FG_ON_MASK,
+		    txtchangeset(txtchangep, arg & TXT_ATTR_FG_ON_MASK,
 				 TXTNOFGCOLOUR);
 		    txtset(arg & TXT_ATTR_FG_ON_MASK);
 		    set_colour_attribute(arg, COL_SEQ_FG, TSC_PROMPT);
@@ -470,7 +473,7 @@
 		/* else FALLTHROUGH */
 		break;
 	    case 'f':
-		txtchangeset(TXTNOFGCOLOUR, TXT_ATTR_FG_ON_MASK);
+		txtchangeset(txtchangep, TXTNOFGCOLOUR, TXT_ATTR_FG_ON_MASK);
 		txtunset(TXT_ATTR_FG_ON_MASK);
 		set_colour_attribute(TXTNOFGCOLOUR, COL_SEQ_FG, TSC_PROMPT);
 		break;
@@ -483,7 +486,7 @@
 		} else
 		    arg = match_colour(NULL, 0, arg);
 		if (arg >= 0 && !(arg & TXTNOBGCOLOUR)) {
-		    txtchangeset(arg & TXT_ATTR_BG_ON_MASK,
+		    txtchangeset(txtchangep, arg & TXT_ATTR_BG_ON_MASK,
 				 TXTNOBGCOLOUR);
 		    txtset(arg & TXT_ATTR_BG_ON_MASK);
 		    set_colour_attribute(arg, COL_SEQ_BG, TSC_PROMPT);
@@ -492,19 +495,19 @@
 		/* else FALLTHROUGH */
 		break;
 	    case 'k':
-		txtchangeset(TXTNOBGCOLOUR, TXT_ATTR_BG_ON_MASK);
+		txtchangeset(txtchangep, TXTNOBGCOLOUR, TXT_ATTR_BG_ON_MASK);
 		txtunset(TXT_ATTR_BG_ON_MASK);
 		set_colour_attribute(TXTNOBGCOLOUR, COL_SEQ_BG, TSC_PROMPT);
 		break;
 	    case '[':
 		if (idigit(*++fm))
 		    arg = zstrtol(fm, &fm, 10);
-		if (!prompttrunc(arg, ']', doprint, endchar))
+		if (!prompttrunc(arg, ']', doprint, endchar, txtchangep))
 		    return *fm;
 		break;
 	    case '<':
 	    case '>':
-		if (!prompttrunc(arg, *fm, doprint, endchar))
+		if (!prompttrunc(arg, *fm, doprint, endchar, txtchangep))
 		    return *fm;
 		break;
 	    case '{': /*}*/
@@ -1036,7 +1039,8 @@
 
 /**/
 static int
-prompttrunc(int arg, int truncchar, int doprint, int endchar)
+prompttrunc(int arg, int truncchar, int doprint, int endchar,
+	    unsigned int *txtchangep)
 {
     if (arg > 0) {
 	char ch = *fm, *ptr, *truncstr;
@@ -1083,7 +1087,7 @@
 	w = bp - buf;
 	fm++;
 	trunccount = dontcount;
-	putpromptchar(doprint, endchar);
+	putpromptchar(doprint, endchar, txtchangep);
 	trunccount = 0;
 	ptr = buf + w;		/* putpromptchar() may have realloc()'d */
 	*bp = '\0';
@@ -1365,7 +1369,7 @@
 	     * With truncwidth set to zero, we always reach endchar *
 	     * (or the terminating NULL) this time round.         *
 	     */
-	    if (!putpromptchar(doprint, endchar))
+	    if (!putpromptchar(doprint, endchar, txtchangep))
 		return 0;
 	}
 	/* Now we have to trick it into matching endchar again */
Index: Src/subst.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/subst.c,v
retrieving revision 1.84
diff -u -r1.84 subst.c
--- Src/subst.c	3 Apr 2008 21:11:00 -0000	1.84
+++ Src/subst.c	12 May 2008 13:10:38 -0000
@@ -2699,7 +2699,7 @@
 		unmetafy(*ap, &len);
 		untokenize(*ap);
 		tmps = unmetafy(promptexpand(metafy(*ap, len, META_NOALLOC),
-					     0, NULL, NULL), &len);
+					     0, NULL, NULL, NULL), &len);
 		*ap = dupstring(tmps);
 		free(tmps);
 	    }
@@ -2710,7 +2710,7 @@
 	    unmetafy(val, &len);
 	    untokenize(val);
 	    tmps = unmetafy(promptexpand(metafy(val, len, META_NOALLOC),
-					0, NULL, NULL), &len);
+					0, NULL, NULL, NULL), &len);
 	    val = dupstring(tmps);
 	    free(tmps);
 	}
Index: Src/utils.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/utils.c,v
retrieving revision 1.188
diff -u -r1.188 utils.c
--- Src/utils.c	22 Apr 2008 15:08:12 -0000	1.188
+++ Src/utils.c	12 May 2008 13:10:42 -0000
@@ -1176,7 +1176,7 @@
 	char *str;
 	int percents = opts[PROMPTPERCENT];
 	opts[PROMPTPERCENT] = 1;
-	str = promptexpand("%B%S%#%s%b", 0, NULL, NULL);
+	str = promptexpand("%B%S%#%s%b", 0, NULL, NULL, NULL);
 	opts[PROMPTPERCENT] = percents;
 	fprintf(shout, "%s%*s\r", str, (int)columns - 1 - !hasxn, "");
 	free(str);
@@ -1341,7 +1341,8 @@
 
 	opts[XTRACE] = 0;
 	unmetafy(s, &l);
-	s = unmetafy(promptexpand(metafy(s, l, META_NOALLOC), 0, NULL, NULL), &l);
+	s = unmetafy(promptexpand(metafy(s, l, META_NOALLOC),
+				  0, NULL, NULL, NULL), &l);
 	opts[XTRACE] = t;
 
 	fprintf(xtrerr, "%s", s);
@@ -2310,7 +2311,7 @@
 		x = 'n';
 	    } else if (shout) {
 		char *pptbuf;
-		pptbuf = promptexpand(sprompt, 0, best, guess);
+		pptbuf = promptexpand(sprompt, 0, best, guess, NULL);
 		zputs(pptbuf, shout);
 		free(pptbuf);
 		fflush(shout);
Index: Src/zsh.h
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/zsh.h,v
retrieving revision 1.133
diff -u -r1.133 zsh.h
--- Src/zsh.h	11 May 2008 19:55:21 -0000	1.133
+++ Src/zsh.h	12 May 2008 13:10:44 -0000
@@ -2043,7 +2043,7 @@
 
 #define txtchangeisset(T,X)	((T) & (X))
 #define txtchangeget(T,A)	(((T) & A ## _MASK) >> A ## _SHIFT)
-#define txtchangeset(X, Y)	(txtchange |= (X), txtchange &= ~(Y))
+#define txtchangeset(T, X, Y)	((void)(T && (*T |= (X), *T &= ~(Y))))
 
 /*
  * For outputting sequences to change colour: specify foreground
Index: Src/Zle/zle_main.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Zle/zle_main.c,v
retrieving revision 1.111
diff -u -r1.111 zle_main.c
--- Src/Zle/zle_main.c	1 May 2008 10:58:25 -0000	1.111
+++ Src/Zle/zle_main.c	12 May 2008 13:10:45 -0000
@@ -1115,7 +1115,8 @@
 	char *pptbuf;
 	int pptlen;
 
-	pptbuf = unmetafy(promptexpand(lp ? *lp : NULL, 0, NULL, NULL),
+	pptbuf = unmetafy(promptexpand(lp ? *lp : NULL, 0, NULL, NULL,
+				       &pmpt_attr),
 			  &pptlen);
 	write(2, (WRITE_ARG_2_T)pptbuf, pptlen);
 	free(pptbuf);
@@ -1145,11 +1146,10 @@
     fetchttyinfo = 0;
     trashedzle = 0;
     raw_lp = lp;
-    lpromptbuf = promptexpand(lp ? *lp : NULL, 1, NULL, NULL);
-    pmpt_attr = txtchange;
+    lpromptbuf = promptexpand(lp ? *lp : NULL, 1, NULL, NULL, &pmpt_attr);
     raw_rp = rp;
-    rpromptbuf = promptexpand(rp ? *rp : NULL, 1, NULL, NULL);
-    rpmpt_attr = txtchange;
+    rpmpt_attr = pmpt_attr;
+    rpromptbuf = promptexpand(rp ? *rp : NULL, 1, NULL, NULL, &rpmpt_attr);
     free_prepostdisplay();
 
     zlereadflags = flags;
@@ -1725,11 +1725,12 @@
 
     if (!reexpanding++) {
 	free(lpromptbuf);
-	lpromptbuf = promptexpand(raw_lp ? *raw_lp : NULL, 1, NULL, NULL);
-	pmpt_attr = txtchange;
+	lpromptbuf = promptexpand(raw_lp ? *raw_lp : NULL, 1, NULL, NULL,
+				  &pmpt_attr);
+	rpmpt_attr = pmpt_attr;
 	free(rpromptbuf);
-	rpromptbuf = promptexpand(raw_rp ? *raw_rp : NULL, 1, NULL, NULL);
-	rpmpt_attr = txtchange;
+	rpromptbuf = promptexpand(raw_rp ? *raw_rp : NULL, 1, NULL, NULL,
+				  &rpmpt_attr);
     }
     reexpanding--;
 }
Index: Src/Zle/zle_refresh.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Zle/zle_refresh.c,v
retrieving revision 1.69
diff -u -r1.69 zle_refresh.c
--- Src/Zle/zle_refresh.c	9 May 2008 17:33:51 -0000	1.69
+++ Src/Zle/zle_refresh.c	12 May 2008 13:10:46 -0000
@@ -990,12 +990,13 @@
     int tmppos;			/* t - tmpline				     */
     int tmpalloced;		/* flag to free tmpline when finished	     */
     int remetafy;		/* flag that zle line is metafied	     */
+    int txtchange;		/* attributes set after prompts */
     struct rparams rpms;
 #ifdef MULTIBYTE_SUPPORT
     int width;			/* width of wide character		     */
 #endif
 
-    
+
     /* If this is called from listmatches() (indirectly via trashzle()), and *
      * that was called from the end of zrefresh(), then we don't need to do  *
      * anything.  All this `inlist' code is actually unnecessary, but it     *


-- 
Peter Stephenson <pws@xxxxxxx>                  Software Engineer
CSR PLC, Churchill House, Cambridge Business Park, Cowley Road
Cambridge, CB4 0WZ, UK                          Tel: +44 (0)1223 692070



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