From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 16918 invoked from network); 12 May 2008 13:24:01 -0000 X-Spam-Checker-Version: SpamAssassin 3.2.4 (2008-01-01) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-2.4 required=5.0 tests=AWL,BAYES_00 autolearn=ham version=3.2.4 Received: from news.dotsrc.org (HELO a.mx.sunsite.dk) (130.225.247.88) by ns1.primenet.com.au with SMTP; 12 May 2008 13:24:01 -0000 Received-SPF: none (ns1.primenet.com.au: domain at sunsite.dk does not designate permitted sender hosts) Received: (qmail 70971 invoked from network); 12 May 2008 13:23:55 -0000 Received: from sunsite.dk (130.225.247.90) by a.mx.sunsite.dk with SMTP; 12 May 2008 13:23:55 -0000 Received: (qmail 26160 invoked by alias); 12 May 2008 13:23:50 -0000 Mailing-List: contact zsh-workers-help@sunsite.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 25002 Received: (qmail 26142 invoked from network); 12 May 2008 13:23:50 -0000 Received: from bifrost.dotsrc.org (130.225.254.106) by sunsite.dk with SMTP; 12 May 2008 13:23:50 -0000 Received: from cluster-g.mailcontrol.com (cluster-g.mailcontrol.com [85.115.41.190]) by bifrost.dotsrc.org (Postfix) with ESMTP id B44C280ED172 for ; Mon, 12 May 2008 15:23:43 +0200 (CEST) Received: from cameurexb01.EUROPE.ROOT.PRI ([62.189.241.200]) by rly01g.srv.mailcontrol.com (MailControl) with ESMTP id m4CDLEDk008757 for ; Mon, 12 May 2008 14:23:38 +0100 Received: from news01 ([10.103.143.38]) by cameurexb01.EUROPE.ROOT.PRI with Microsoft SMTPSVC(6.0.3790.3959); Mon, 12 May 2008 14:22:50 +0100 Date: Mon, 12 May 2008 14:22:51 +0100 From: Peter Stephenson To: zsh-workers Subject: Re: input line changes colour after print -P %F Message-ID: <20080512142251.062e9c7b@news01> In-Reply-To: <237967ef0805120507s27a4405ds9be5f27ede3e3a5f@mail.gmail.com> References: <237967ef0805120507s27a4405ds9be5f27ede3e3a5f@mail.gmail.com> Organization: CSR X-Mailer: Claws Mail 3.3.1 (GTK+ 2.12.5; i386-redhat-linux-gnu) Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-OriginalArrivalTime: 12 May 2008 13:22:50.0915 (UTC) FILETIME=[47180F30:01C8B433] X-Scanned-By: MailControl A-08-50-00 (www.mailcontrol.com) on 10.71.0.111 X-Virus-Scanned: ClamAV 0.91.2/7102/Mon May 12 15:06:15 2008 on bifrost X-Virus-Status: Clean On Mon, 12 May 2008 14:07:53 +0200 "Mikael Magnusson" wrote: > zsh -f > autoload compinit; compinit > zstyle ':completion:*:warnings' format '' > print -P '%F{red}foo' > asdasfasdasfasfasadasf > > 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 Software Engineer CSR PLC, Churchill House, Cambridge Business Park, Cowley Road Cambridge, CB4 0WZ, UK Tel: +44 (0)1223 692070