mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-09-03 10:21:46 +02:00
25002: only ZLE should update attributes resulting from prompt expansion
This commit is contained in:
parent
58580d31f5
commit
bd70d684fc
11 changed files with 72 additions and 55 deletions
|
@ -1,3 +1,10 @@
|
|||
2008-05-12 Peter Stephenson <pws@csr.com>
|
||||
|
||||
* 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 <p.w.stephenson@ntlworld.com>
|
||||
|
||||
* 24996: Src/cond.c, Src/exec.c, Src/glob.c, Src/loop.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--;
|
||||
}
|
||||
|
|
|
@ -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 *
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
70
Src/prompt.c
70
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 */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue