From bd70d684fcf40ff1fba07ec69bd08e1ce40cbd2f Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Mon, 12 May 2008 13:50:42 +0000 Subject: 25002: only ZLE should update attributes resulting from prompt expansion --- ChangeLog | 7 ++++++ Src/Zle/zle_main.c | 19 +++++++------- Src/Zle/zle_refresh.c | 3 ++- Src/builtin.c | 6 +++-- Src/init.c | 3 ++- Src/input.c | 2 +- Src/loop.c | 4 +-- Src/prompt.c | 70 +++++++++++++++++++++++++++------------------------ Src/subst.c | 4 +-- Src/utils.c | 7 +++--- Src/zsh.h | 2 +- 11 files changed, 72 insertions(+), 55 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2fb0dedba..c7500cdca 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2008-05-12 Peter Stephenson + + * 25002: Src/builtin.c, Src/init.c, Src/input.c, Src/loop.c, + Src/prompt.c, Src/subst.c, Src/utils.c, Src/zsh.h, + Src/Zle/zle_main.c, Src/Zle/zle_refresh.c: only update + display attributes from prompts within zle. + 2008-05-11 Peter Stephenson * 24996: Src/cond.c, Src/exec.c, Src/glob.c, Src/loop.c, diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c index 804661ac6..7fb6878da 100644 --- a/Src/Zle/zle_main.c +++ b/Src/Zle/zle_main.c @@ -1115,7 +1115,8 @@ zleread(char **lp, char **rp, int flags, int context) 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 @@ zleread(char **lp, char **rp, int flags, int context) 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 @@ reexpandprompt(void) 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--; } diff --git a/Src/Zle/zle_refresh.c b/Src/Zle/zle_refresh.c index dd8c26079..f43ad45e2 100644 --- a/Src/Zle/zle_refresh.c +++ b/Src/Zle/zle_refresh.c @@ -990,12 +990,13 @@ zrefresh(void) 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 * diff --git a/Src/builtin.c b/Src/builtin.c index d28d9fffd..f11d5aa51 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -3571,8 +3571,10 @@ bin_print(char *name, char **args, Options ops, int func) * 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); } diff --git a/Src/init.c b/Src/init.c index 7707b825e..e3c89008a 100644 --- a/Src/init.c +++ b/Src/init.c @@ -1237,7 +1237,8 @@ fallback_zleread(char **lp, UNUSED(char **rp), UNUSED(int ha), UNUSED(int con)) 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); diff --git a/Src/input.c b/Src/input.c index d6fd8d089..a721eba9b 100644 --- a/Src/input.c +++ b/Src/input.c @@ -256,7 +256,7 @@ inputline(void) 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); } diff --git a/Src/loop.c b/Src/loop.c index 0de963318..9533ba186 100644 --- a/Src/loop.c +++ b/Src/loop.c @@ -250,7 +250,7 @@ execselect(Estate state, UNUSED(int do_exec)) 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 @@ execcase(Estate state, int do_exec) 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); diff --git a/Src/prompt.c b/Src/prompt.c index f83053a8f..004080577 100644 --- a/Src/prompt.c +++ b/Src/prompt.c @@ -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 @@ promptpath(char *p, int npath, int tilde) 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 @@ promptexpand(char *s, int ns, char *rs, char *Rs) 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 @@ promptexpand(char *s, int ns, char *rs, char *Rs) /**/ 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 @@ putpromptchar(int doprint, int endchar) /* 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 @@ putpromptchar(int doprint, int endchar) 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 @@ putpromptchar(int doprint, int endchar) } 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 @@ putpromptchar(int doprint, int endchar) /* 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 @@ putpromptchar(int doprint, int endchar) } 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 @@ putpromptchar(int doprint, int endchar) /* 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 @@ countprompt(char *str, int *wp, int *hp, int overf) /**/ 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 @@ prompttrunc(int arg, int truncchar, int doprint, int endchar) 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 @@ prompttrunc(int arg, int truncchar, int doprint, int endchar) * 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 */ diff --git a/Src/subst.c b/Src/subst.c index 1645764ec..7906f80bd 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -2699,7 +2699,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub) 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 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub) 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); } diff --git a/Src/utils.c b/Src/utils.c index 30162a71e..d3319f0a9 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -1176,7 +1176,7 @@ preprompt(void) 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 @@ printprompt4(void) 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 @@ spckword(char **s, int hist, int cmd, int ask) 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); diff --git a/Src/zsh.h b/Src/zsh.h index 7617e2281..5618174a8 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -2043,7 +2043,7 @@ struct ttyinfo { #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 -- cgit 1.4.1