mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-06-12 19:38:03 +02:00
52500: add layer token to zle attributes
This provide control over the precedence of highlighting where different regions overlap.
This commit is contained in:
parent
3c5dacd503
commit
85545af42b
4 changed files with 88 additions and 46 deletions
|
@ -1,5 +1,9 @@
|
||||||
2024-01-28 Oliver Kiddle <opk@zsh.org>
|
2024-01-28 Oliver Kiddle <opk@zsh.org>
|
||||||
|
|
||||||
|
* 52500: Src/Zle/zle.h, Src/Zle/zle_refresh.c, Src/prompt.c:
|
||||||
|
add layer token to zle attributes to provide control over
|
||||||
|
the precedence of highlighting
|
||||||
|
|
||||||
* 52499: Src/prompt.c: support highlight groups defined in a
|
* 52499: Src/prompt.c: support highlight groups defined in a
|
||||||
.zle.hlgroups associative array and referenced using %H in
|
.zle.hlgroups associative array and referenced using %H in
|
||||||
prompt strings or hl= in zle_highlight/region_highlight
|
prompt strings or hl= in zle_highlight/region_highlight
|
||||||
|
|
|
@ -435,6 +435,8 @@ enum {
|
||||||
struct region_highlight {
|
struct region_highlight {
|
||||||
/* Attributes turned on in the region */
|
/* Attributes turned on in the region */
|
||||||
zattr atr;
|
zattr atr;
|
||||||
|
/* Priority for this region relative to others that overlap */
|
||||||
|
int layer;
|
||||||
/* Start of the region */
|
/* Start of the region */
|
||||||
int start;
|
int start;
|
||||||
/* Start of the region in metafied ZLE line */
|
/* Start of the region in metafied ZLE line */
|
||||||
|
|
|
@ -210,6 +210,12 @@ int predisplaylen, postdisplaylen;
|
||||||
|
|
||||||
static zattr default_attr, special_attr, ellipsis_attr;
|
static zattr default_attr, special_attr, ellipsis_attr;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Layer applied to highlighting for special characters
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int special_layer;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Array of region highlights, no special termination.
|
* Array of region highlights, no special termination.
|
||||||
* The first N_SPECIAL_HIGHLIGHTS elements describe special uses of
|
* The first N_SPECIAL_HIGHLIGHTS elements describe special uses of
|
||||||
|
@ -337,6 +343,13 @@ zle_set_highlight(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Default layers */
|
||||||
|
region_highlights[0].layer = 20; /* region */
|
||||||
|
region_highlights[1].layer = 20; /* isearch */
|
||||||
|
region_highlights[2].layer = 10; /* suffix */
|
||||||
|
region_highlights[3].layer = 15; /* paste */
|
||||||
|
special_layer = 30;
|
||||||
|
|
||||||
if (atrs) {
|
if (atrs) {
|
||||||
for (; *atrs; atrs++) {
|
for (; *atrs; atrs++) {
|
||||||
if (!strcmp(*atrs, "none")) {
|
if (!strcmp(*atrs, "none")) {
|
||||||
|
@ -346,30 +359,34 @@ zle_set_highlight(void)
|
||||||
paste_attr_set = region_attr_set =
|
paste_attr_set = region_attr_set =
|
||||||
isearch_attr_set = suffix_attr_set = 1;
|
isearch_attr_set = suffix_attr_set = 1;
|
||||||
} else if (strpfx("default:", *atrs)) {
|
} else if (strpfx("default:", *atrs)) {
|
||||||
match_highlight(*atrs + 8, &default_attr);
|
match_highlight(*atrs + 8, &default_attr, NULL);
|
||||||
} else if (strpfx("special:", *atrs)) {
|
} else if (strpfx("special:", *atrs)) {
|
||||||
match_highlight(*atrs + 8, &special_attr);
|
match_highlight(*atrs + 8, &special_attr, &special_layer);
|
||||||
special_attr_set = 1;
|
special_attr_set = 1;
|
||||||
} else if (strpfx("region:", *atrs)) {
|
} else if (strpfx("region:", *atrs)) {
|
||||||
match_highlight(*atrs + 7, ®ion_highlights[0].atr);
|
match_highlight(*atrs + 7, &(region_highlights[0].atr),
|
||||||
|
&(region_highlights[0].layer));
|
||||||
region_attr_set = 1;
|
region_attr_set = 1;
|
||||||
} else if (strpfx("isearch:", *atrs)) {
|
} else if (strpfx("isearch:", *atrs)) {
|
||||||
match_highlight(*atrs + 8, &(region_highlights[1].atr));
|
match_highlight(*atrs + 8, &(region_highlights[1].atr),
|
||||||
|
&(region_highlights[1].layer));
|
||||||
isearch_attr_set = 1;
|
isearch_attr_set = 1;
|
||||||
} else if (strpfx("suffix:", *atrs)) {
|
} else if (strpfx("suffix:", *atrs)) {
|
||||||
match_highlight(*atrs + 7, &(region_highlights[2].atr));
|
match_highlight(*atrs + 7, &(region_highlights[2].atr),
|
||||||
|
&(region_highlights[2].layer));
|
||||||
suffix_attr_set = 1;
|
suffix_attr_set = 1;
|
||||||
} else if (strpfx("paste:", *atrs)) {
|
} else if (strpfx("paste:", *atrs)) {
|
||||||
match_highlight(*atrs + 6, &(region_highlights[3].atr));
|
match_highlight(*atrs + 6, &(region_highlights[3].atr),
|
||||||
|
&(region_highlights[3].layer));
|
||||||
paste_attr_set = 1;
|
paste_attr_set = 1;
|
||||||
} else if (strpfx("ellipsis:", *atrs)) {
|
} else if (strpfx("ellipsis:", *atrs)) {
|
||||||
match_highlight(*atrs + 9, &ellipsis_attr);
|
match_highlight(*atrs + 9, &ellipsis_attr, NULL);
|
||||||
ellipsis_attr_set = 1;
|
ellipsis_attr_set = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Defaults */
|
/* Default attributes */
|
||||||
if (!special_attr_set)
|
if (!special_attr_set)
|
||||||
special_attr = TXTSTANDOUT;
|
special_attr = TXTSTANDOUT;
|
||||||
if (!region_attr_set)
|
if (!region_attr_set)
|
||||||
|
@ -407,14 +424,13 @@ zle_free_highlight(void)
|
||||||
char **
|
char **
|
||||||
get_region_highlight(UNUSED(Param pm))
|
get_region_highlight(UNUSED(Param pm))
|
||||||
{
|
{
|
||||||
int arrsize = n_region_highlights;
|
int arrsize = n_region_highlights - N_SPECIAL_HIGHLIGHTS;
|
||||||
char **retarr, **arrp;
|
char **retarr, **arrp;
|
||||||
struct region_highlight *rhp;
|
struct region_highlight *rhp;
|
||||||
|
|
||||||
/* region_highlights may not have been set yet */
|
/* region_highlights may not have been set yet */
|
||||||
if (!arrsize)
|
if (!n_region_highlights)
|
||||||
return hmkarray(NULL);
|
return hmkarray(NULL);
|
||||||
arrsize -= N_SPECIAL_HIGHLIGHTS;
|
|
||||||
DPUTS(arrsize < 0, "arrsize is negative from n_region_highlights");
|
DPUTS(arrsize < 0, "arrsize is negative from n_region_highlights");
|
||||||
arrp = retarr = (char **)zhalloc((arrsize+1)*sizeof(char *));
|
arrp = retarr = (char **)zhalloc((arrsize+1)*sizeof(char *));
|
||||||
|
|
||||||
|
@ -422,20 +438,18 @@ get_region_highlight(UNUSED(Param pm))
|
||||||
for (rhp = region_highlights + N_SPECIAL_HIGHLIGHTS;
|
for (rhp = region_highlights + N_SPECIAL_HIGHLIGHTS;
|
||||||
arrsize--;
|
arrsize--;
|
||||||
rhp++, arrp++) {
|
rhp++, arrp++) {
|
||||||
char digbuf1[DIGBUFSIZE], digbuf2[DIGBUFSIZE];
|
char digbuf[2 * DIGBUFSIZE], layerbuf[7 + DIGBUFSIZE];
|
||||||
int atrlen, alloclen;
|
int offset;
|
||||||
const char memo_equals[] = "memo=";
|
const char memo_equals[] = " memo=";
|
||||||
|
int alloclen = sprintf(digbuf, "%d %d", rhp->start, rhp->end) +
|
||||||
sprintf(digbuf1, "%d", rhp->start);
|
output_highlight(rhp->atr, NULL) +
|
||||||
sprintf(digbuf2, "%d", rhp->end);
|
2; /* space and terminating NUL */
|
||||||
|
|
||||||
atrlen = output_highlight(rhp->atr, NULL);
|
|
||||||
alloclen = atrlen + strlen(digbuf1) + strlen(digbuf2) +
|
|
||||||
3; /* 2 spaces, 1 terminating NUL */
|
|
||||||
if (rhp->flags & ZRH_PREDISPLAY)
|
if (rhp->flags & ZRH_PREDISPLAY)
|
||||||
alloclen += 2; /* "P " */
|
alloclen++; /* "P" */
|
||||||
|
if (rhp->layer != 10)
|
||||||
|
alloclen += sprintf(layerbuf, ",layer=%d", rhp->layer);
|
||||||
if (rhp->memo)
|
if (rhp->memo)
|
||||||
alloclen += 1 /* space */ + strlen(memo_equals) + strlen(rhp->memo);
|
alloclen += sizeof(memo_equals) - 1 + strlen(rhp->memo);
|
||||||
*arrp = (char *)zhalloc(alloclen * sizeof(char));
|
*arrp = (char *)zhalloc(alloclen * sizeof(char));
|
||||||
/*
|
/*
|
||||||
* On input we allow a space after the flags.
|
* On input we allow a space after the flags.
|
||||||
|
@ -444,13 +458,14 @@ get_region_highlight(UNUSED(Param pm))
|
||||||
* into three words, and then check the first to
|
* into three words, and then check the first to
|
||||||
* see if there are flags. However, it's arguable.
|
* see if there are flags. However, it's arguable.
|
||||||
*/
|
*/
|
||||||
sprintf(*arrp, "%s%s %s ",
|
offset = sprintf(*arrp, "%s%s ",
|
||||||
(rhp->flags & ZRH_PREDISPLAY) ? "P" : "",
|
(rhp->flags & ZRH_PREDISPLAY) ? "P" : "",
|
||||||
digbuf1, digbuf2);
|
digbuf);
|
||||||
(void)output_highlight(rhp->atr, *arrp + strlen(*arrp));
|
(void)output_highlight(rhp->atr, *arrp + offset);
|
||||||
|
|
||||||
|
if (rhp->layer != 10)
|
||||||
|
strcat(*arrp, layerbuf);
|
||||||
if (rhp->memo) {
|
if (rhp->memo) {
|
||||||
strcat(*arrp, " ");
|
|
||||||
strcat(*arrp, memo_equals);
|
strcat(*arrp, memo_equals);
|
||||||
strcat(*arrp, rhp->memo);
|
strcat(*arrp, rhp->memo);
|
||||||
}
|
}
|
||||||
|
@ -459,12 +474,10 @@ get_region_highlight(UNUSED(Param pm))
|
||||||
return retarr;
|
return retarr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The parameter system requires the pm argument, but this
|
* The parameter system requires the pm argument, but this
|
||||||
* may be NULL if called directly.
|
* may be NULL if called directly.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
void
|
void
|
||||||
set_region_highlight(UNUSED(Param pm), char **aval)
|
set_region_highlight(UNUSED(Param pm), char **aval)
|
||||||
|
@ -523,7 +536,8 @@ set_region_highlight(UNUSED(Param pm), char **aval)
|
||||||
while (inblank(*strp))
|
while (inblank(*strp))
|
||||||
strp++;
|
strp++;
|
||||||
|
|
||||||
strp = (char*) match_highlight(strp, &rhp->atr);
|
rhp->layer = 10; /* default */
|
||||||
|
strp = (char*) match_highlight(strp, &rhp->atr, &rhp->layer);
|
||||||
|
|
||||||
while (inblank(*strp))
|
while (inblank(*strp))
|
||||||
strp++;
|
strp++;
|
||||||
|
@ -1180,27 +1194,40 @@ zrefresh(void)
|
||||||
rpms.s = nbuf[rpms.ln = 0] + lpromptw;
|
rpms.s = nbuf[rpms.ln = 0] + lpromptw;
|
||||||
rpms.sen = *nbuf + winw;
|
rpms.sen = *nbuf + winw;
|
||||||
for (t = tmpline, tmppos = 0; tmppos < tmpll; t++, tmppos++) {
|
for (t = tmpline, tmppos = 0; tmppos < tmpll; t++, tmppos++) {
|
||||||
unsigned ireg;
|
|
||||||
zattr base_attr = mixattrs(default_attr, prompt_attr);
|
zattr base_attr = mixattrs(default_attr, prompt_attr);
|
||||||
zattr all_attr;
|
zattr all_attr;
|
||||||
struct region_highlight *rhp;
|
struct region_highlight *rhp;
|
||||||
|
int layer, nextlayer = 0;
|
||||||
/*
|
/*
|
||||||
* Calculate attribute based on region.
|
* Calculate attribute based on region.
|
||||||
*/
|
*/
|
||||||
for (ireg = 0, rhp = region_highlights;
|
do {
|
||||||
ireg < n_region_highlights;
|
unsigned ireg;
|
||||||
ireg++, rhp++) {
|
layer = nextlayer;
|
||||||
int offset;
|
nextlayer = special_layer;
|
||||||
if (rhp->flags & ZRH_PREDISPLAY)
|
for (ireg = 0, rhp = region_highlights;
|
||||||
offset = 0; /* include predisplay in start end */
|
ireg < n_region_highlights;
|
||||||
else
|
ireg++, rhp++) {
|
||||||
offset = predisplaylen; /* increment over it */
|
if (rhp->layer == layer) {
|
||||||
if (rhp->start + offset <= tmppos &&
|
int offset;
|
||||||
tmppos < rhp->end + offset) {
|
if (rhp->flags & ZRH_PREDISPLAY)
|
||||||
base_attr = mixattrs(rhp->atr, base_attr);
|
offset = 0; /* include predisplay in start end */
|
||||||
|
else
|
||||||
|
offset = predisplaylen; /* increment over it */
|
||||||
|
if (rhp->start + offset <= tmppos &&
|
||||||
|
tmppos < rhp->end + offset) {
|
||||||
|
base_attr = mixattrs(rhp->atr, base_attr);
|
||||||
|
if (layer > special_layer)
|
||||||
|
all_attr = mixattrs(rhp->atr, all_attr);
|
||||||
|
}
|
||||||
|
} else if (rhp->layer > layer && rhp->layer < nextlayer) {
|
||||||
|
nextlayer = rhp->layer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
if (special_layer == layer) {
|
||||||
all_attr = mixattrs(special_attr, base_attr);
|
all_attr = mixattrs(special_attr, base_attr);
|
||||||
|
}
|
||||||
|
} while (nextlayer > layer);
|
||||||
|
|
||||||
if (t == scs) /* if cursor is here, remember it */
|
if (t == scs) /* if cursor is here, remember it */
|
||||||
rpms.nvcs = rpms.s - nbuf[rpms.nvln = rpms.ln];
|
rpms.nvcs = rpms.s - nbuf[rpms.nvln = rpms.ln];
|
||||||
|
|
13
Src/prompt.c
13
Src/prompt.c
|
@ -260,7 +260,7 @@ parsehighlight(char *arg, char endchar, zattr *atr)
|
||||||
if ((node = (Param) ht->getnode(ht, arg))) {
|
if ((node = (Param) ht->getnode(ht, arg))) {
|
||||||
attrs = node->gsu.s->getfn(node);
|
attrs = node->gsu.s->getfn(node);
|
||||||
entered = 1;
|
entered = 1;
|
||||||
if (match_highlight(attrs, atr) == attrs)
|
if (match_highlight(attrs, atr, 0) == attrs)
|
||||||
*atr = TXT_ERROR;
|
*atr = TXT_ERROR;
|
||||||
} else
|
} else
|
||||||
*atr = TXT_ERROR;
|
*atr = TXT_ERROR;
|
||||||
|
@ -1884,12 +1884,13 @@ match_colour(const char **teststrp, int is_fg, int colour)
|
||||||
/*
|
/*
|
||||||
* Match a set of highlights in the given teststr.
|
* Match a set of highlights in the given teststr.
|
||||||
* Set *on_var to reflect the values found.
|
* Set *on_var to reflect the values found.
|
||||||
|
* Set *layer to the layer
|
||||||
* Return a pointer to the first character not consumed.
|
* Return a pointer to the first character not consumed.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
mod_export const char *
|
mod_export const char *
|
||||||
match_highlight(const char *teststr, zattr *on_var)
|
match_highlight(const char *teststr, zattr *on_var, int *layer)
|
||||||
{
|
{
|
||||||
int found = 1;
|
int found = 1;
|
||||||
|
|
||||||
|
@ -1918,6 +1919,14 @@ match_highlight(const char *teststr, zattr *on_var)
|
||||||
/* skip out of range colours but keep scanning attributes */
|
/* skip out of range colours but keep scanning attributes */
|
||||||
if (atr != TXT_ERROR)
|
if (atr != TXT_ERROR)
|
||||||
*on_var |= atr;
|
*on_var |= atr;
|
||||||
|
} else if (layer && strpfx("layer=", teststr)) {
|
||||||
|
teststr += 6;
|
||||||
|
*layer = (int) zstrtol(teststr, (char **) &teststr, 10);
|
||||||
|
if (*teststr == ',')
|
||||||
|
teststr++;
|
||||||
|
else if (*teststr && *teststr != ' ')
|
||||||
|
break;
|
||||||
|
found = 1;
|
||||||
} else {
|
} else {
|
||||||
for (hl = highlights; hl->name; hl++) {
|
for (hl = highlights; hl->name; hl++) {
|
||||||
if (strpfx(hl->name, teststr)) {
|
if (strpfx(hl->name, teststr)) {
|
||||||
|
|
Loading…
Reference in a new issue