mirror of
https://git.code.sf.net/p/zsh/code
synced 2026-04-18 06:53:35 -04:00
54043, 54055: allow highlighing attributes to be turned back off
This commit is contained in:
@@ -1,5 +1,11 @@
|
||||
2025-11-12 Oliver Kiddle <opk@zsh.org>
|
||||
|
||||
* 54043, 54055 (tweaked to use "reset" as suggested by Mikael):
|
||||
Doc/Zsh/zle.yo, Src/prompt.c, Src/Modules/hlgroup.c,
|
||||
Src/Modules/watch.c, Src/Zle/complist.c, Src/Zle/zle.h,
|
||||
Src/Zle/zle_main.c, Src/Zle/zle_refresh.c, Src/Zle/zle_tricky.c:
|
||||
allow highlighing attributes to be turned back off
|
||||
|
||||
* 54037: Src/Zle/zle_refresh.c: fix to highlight layers where
|
||||
special is assigned a low layer
|
||||
|
||||
|
||||
@@ -990,14 +990,14 @@ The var(token) is preserved verbatim but not parsed in any way.
|
||||
Plugins may use this to identify array elements they have added: for example,
|
||||
a plugin might set var(token) to its (the plugin's) name and then use
|
||||
`tt(region_highlight=+LPAR() ${region_highlight:#*memo=)var(token)tt(} +RPAR())'
|
||||
in order to remove array elements it have added.
|
||||
in order to remove array elements it added.
|
||||
|
||||
(This example uses the `tt(${)var(name)tt(:#)var(pattern)tt(})' array-grepping
|
||||
syntax described in
|
||||
sectref(Parameter Expansion)(zshexpn).))
|
||||
enditemize()
|
||||
|
||||
For example,
|
||||
For example,
|
||||
|
||||
example(region_highlight=("P0 20 bold memo=foobar"))
|
||||
|
||||
@@ -1009,12 +1009,16 @@ as soon as the line is accepted.
|
||||
|
||||
Note that zsh 5.8 and older do not support the `tt(memo=)var(token)' field
|
||||
and may misparse the third (highlight specification) field when a memo
|
||||
is given.
|
||||
COMMENT(The syntax `tt(0 20 bold, memo=foobar)' (with an auxiliary comma)
|
||||
happens to work on both zsh <=5.8 and zsh 5.9-to-be, but that seems to be more of
|
||||
is given. COMMENT(The syntax `tt(0 20 bold, memo=foobar)' (with an auxiliary comma)
|
||||
happens to work on both zsh <=5.8 and zsh 5.9, but that seems to be more of
|
||||
an accident of implementation than something we should make a first-class-citizen
|
||||
API promise. It's mentioned in the "Incompatibilities" section of README.)
|
||||
|
||||
Where a particular region is covered by multiple entries in
|
||||
tt(region_highlight), their effects are merged. In the case of conflicts, later
|
||||
entries take precedence over earlier ones. This precedence ordering can be
|
||||
overridden by specifying layers.
|
||||
|
||||
The final highlighting on the command line depends on both tt(region_highlight)
|
||||
and tt(zle_highlight); see
|
||||
sectref(Character Highlighting)(below) for details.
|
||||
@@ -2818,9 +2822,16 @@ not all types of highlighting are available on all terminals:
|
||||
|
||||
startitem()
|
||||
item(tt(none))(
|
||||
No highlighting is applied to the given context. It is not useful for
|
||||
this to appear with other types of highlighting; it is used to override
|
||||
a default.
|
||||
No additional highlighting is applied to the given context. It is not
|
||||
useful for this to appear with other types of highlighting; it is used to
|
||||
override a default. Any inherited highlighting is retained so for example,
|
||||
with tt(region:none), highlighting associated with tt(default) is still used
|
||||
for the region.
|
||||
)
|
||||
item(tt(reset))(
|
||||
The terminal's default highlighting is applied to the given context.
|
||||
This can be useful as a way to clear all inherited highlighting, so
|
||||
may be used before naming other types of highlighting.
|
||||
)
|
||||
item(tt(fg=)var(colour))(
|
||||
The foreground colour should be set to var(colour), a decimal integer,
|
||||
@@ -2888,12 +2899,20 @@ the associative array tt(.zle.hlgroups) to determine the actual highlighting.
|
||||
item(tt(layer=)var(layer))(
|
||||
The layer is used to determine precedence when multiple highlighting regions
|
||||
overlap. The var(layer) is a decimal integer, with higher numbers taking
|
||||
precedence over lower numbers. The default layer is 10 with 30 used as the
|
||||
default for tt(special), 20 for tt(region) and tt(isearch) and 15 for
|
||||
tt(paste).
|
||||
)
|
||||
precedence over lower numbers. This cannot be used with the tt(default) and
|
||||
tt(ellipsis) fields of tt(zle_highlight) because they treated as base layers.
|
||||
With the other fields 30 applies by default for tt(special), 20 for tt(region)
|
||||
and tt(isearch) and 15 for tt(paste). Highlighting defined in
|
||||
tt(region_highlight) defaults to layer 10 and would take precedence over
|
||||
highlighting for any fields of tt(zle_highlight) that are assigned to the same
|
||||
layer.)
|
||||
enditem()
|
||||
|
||||
In addition, the simple highlighting types can be prefixed with tt("no") to
|
||||
explicitly disable them. This is useful where highlighting is merged with
|
||||
inherited highlighting from other definitions. Note that tt(nobold) selects a
|
||||
normal font weight so also has the effect of disabling tt(faint).
|
||||
|
||||
The characters described above as `special' are as follows. The
|
||||
formatting described here is used irrespective of whether the characters
|
||||
are highlighted:
|
||||
|
||||
@@ -43,7 +43,7 @@ convertattr(char *attrstr, int sgr)
|
||||
char *r, *s;
|
||||
int len;
|
||||
|
||||
match_highlight(attrstr, &atr, NULL);
|
||||
match_highlight(attrstr, &atr, NULL, NULL);
|
||||
s = zattrescape(atr, sgr ? NULL : &len);
|
||||
|
||||
if (sgr) {
|
||||
|
||||
@@ -375,7 +375,7 @@ watchlog2(int inout, WATCH_STRUCT_UTMP *u, char *fmt, int prnt, int fini)
|
||||
break;
|
||||
case 'H':
|
||||
if (*fmt == '{') {
|
||||
fmt = parsehighlight(fmt + 1, '}', &atr);
|
||||
fmt = parsehighlight(fmt + 1, '}', &atr, NULL);
|
||||
if (atr && atr != TXT_ERROR)
|
||||
treplaceattrs(atr);
|
||||
}
|
||||
|
||||
@@ -1183,7 +1183,7 @@ compprintfmt(char *fmt, int n, int dopr, int doesc, int ml, int *stop)
|
||||
break;
|
||||
case ZWC('H'):
|
||||
if (*p == '{') {
|
||||
p = parsehighlight(p + 1, '}', &atr);
|
||||
p = parsehighlight(p + 1, '}', &atr, NULL);
|
||||
if (atr != TXT_ERROR && dopr)
|
||||
treplaceattrs(atr);
|
||||
}
|
||||
|
||||
@@ -433,8 +433,10 @@ enum {
|
||||
* and mark.
|
||||
*/
|
||||
struct region_highlight {
|
||||
/* Attributes turned on in the region */
|
||||
/* Attributes for the region */
|
||||
zattr atr;
|
||||
/* Explicitly set attributes for the region */
|
||||
zattr atrmask;
|
||||
/* Priority for this region relative to others that overlap */
|
||||
int layer;
|
||||
/* Start of the region */
|
||||
|
||||
@@ -1277,7 +1277,7 @@ zleread(char **lp, char **rp, int flags, int context, char *init, char *finish)
|
||||
raw_rp = rp;
|
||||
rpromptbuf = promptexpand(rp ? *rp : NULL, 1, markers[2], NULL, NULL);
|
||||
rpmpt_attr = txtcurrentattrs;
|
||||
prompt_attr = mixattrs(pmpt_attr, rpmpt_attr);
|
||||
prompt_attr = mixattrs(pmpt_attr, pmpt_attr, rpmpt_attr);
|
||||
free_prepostdisplay();
|
||||
|
||||
zlereadflags = flags;
|
||||
@@ -2032,7 +2032,7 @@ reexpandprompt(void)
|
||||
|
||||
new_rprompt = promptexpand(raw_rp ? *raw_rp : NULL, 1, markers[2], NULL, NULL);
|
||||
rpmpt_attr = txtcurrentattrs;
|
||||
prompt_attr = mixattrs(pmpt_attr, rpmpt_attr);
|
||||
prompt_attr = mixattrs(pmpt_attr, pmpt_attr, rpmpt_attr);
|
||||
free(rpromptbuf);
|
||||
rpromptbuf = new_rprompt;
|
||||
} while (looping != reexpanding);
|
||||
|
||||
@@ -208,7 +208,7 @@ int predisplaylen, postdisplaylen;
|
||||
* and for ellipsis continuation markers.
|
||||
*/
|
||||
|
||||
static zattr default_attr, special_attr, ellipsis_attr;
|
||||
static zattr default_attr, special_attr, special_mask, ellipsis_attr;
|
||||
|
||||
/*
|
||||
* Layer applied to highlighting for special characters
|
||||
@@ -359,28 +359,33 @@ zle_set_highlight(void)
|
||||
paste_attr_set = region_attr_set =
|
||||
isearch_attr_set = suffix_attr_set = 1;
|
||||
} else if (strpfx("default:", *atrs)) {
|
||||
match_highlight(*atrs + 8, &default_attr, NULL);
|
||||
match_highlight(*atrs + 8, &default_attr, NULL, NULL);
|
||||
} else if (strpfx("special:", *atrs)) {
|
||||
match_highlight(*atrs + 8, &special_attr, &special_layer);
|
||||
match_highlight(*atrs + 8, &special_attr, &special_mask,
|
||||
&special_layer);
|
||||
special_attr_set = 1;
|
||||
} else if (strpfx("region:", *atrs)) {
|
||||
match_highlight(*atrs + 7, &(region_highlights[0].atr),
|
||||
&(region_highlights[0].atrmask),
|
||||
&(region_highlights[0].layer));
|
||||
region_attr_set = 1;
|
||||
} else if (strpfx("isearch:", *atrs)) {
|
||||
match_highlight(*atrs + 8, &(region_highlights[1].atr),
|
||||
&(region_highlights[1].atrmask),
|
||||
&(region_highlights[1].layer));
|
||||
isearch_attr_set = 1;
|
||||
} else if (strpfx("suffix:", *atrs)) {
|
||||
match_highlight(*atrs + 7, &(region_highlights[2].atr),
|
||||
&(region_highlights[2].atrmask),
|
||||
&(region_highlights[2].layer));
|
||||
suffix_attr_set = 1;
|
||||
} else if (strpfx("paste:", *atrs)) {
|
||||
match_highlight(*atrs + 6, &(region_highlights[3].atr),
|
||||
&(region_highlights[3].atrmask),
|
||||
&(region_highlights[3].layer));
|
||||
paste_attr_set = 1;
|
||||
} else if (strpfx("ellipsis:", *atrs)) {
|
||||
match_highlight(*atrs + 9, &ellipsis_attr, NULL);
|
||||
match_highlight(*atrs + 9, &ellipsis_attr, NULL, NULL);
|
||||
ellipsis_attr_set = 1;
|
||||
}
|
||||
}
|
||||
@@ -388,15 +393,15 @@ zle_set_highlight(void)
|
||||
|
||||
/* Default attributes */
|
||||
if (!special_attr_set)
|
||||
special_attr = TXTSTANDOUT;
|
||||
special_attr = special_mask = TXTSTANDOUT;
|
||||
if (!region_attr_set)
|
||||
region_highlights[0].atr = TXTSTANDOUT;
|
||||
region_highlights[0].atr = region_highlights[0].atrmask = TXTSTANDOUT;
|
||||
if (!isearch_attr_set)
|
||||
region_highlights[1].atr = TXTUNDERLINE;
|
||||
region_highlights[1].atr = region_highlights[1].atrmask = TXTUNDERLINE;
|
||||
if (!suffix_attr_set)
|
||||
region_highlights[2].atr = TXTBOLDFACE;
|
||||
region_highlights[2].atr = region_highlights[2].atrmask = TXTBOLDFACE;
|
||||
if (!paste_attr_set)
|
||||
region_highlights[3].atr = TXTSTANDOUT;
|
||||
region_highlights[3].atr = region_highlights[3].atrmask = TXTSTANDOUT;
|
||||
if (!ellipsis_attr_set)
|
||||
ellipsis_attr = TXTBGCOLOUR | ((zattr) 3 << TXT_ATTR_BG_COL_SHIFT) |
|
||||
TXTFGCOLOUR | ((zattr) 4 << TXT_ATTR_FG_COL_SHIFT);
|
||||
@@ -442,7 +447,7 @@ get_region_highlight(UNUSED(Param pm))
|
||||
int offset;
|
||||
const char memo_equals[] = " memo=";
|
||||
int alloclen = sprintf(digbuf, "%d %d", rhp->start, rhp->end) +
|
||||
output_highlight(rhp->atr, NULL) +
|
||||
output_highlight(rhp->atr, rhp->atrmask, NULL) +
|
||||
2; /* space and terminating NUL */
|
||||
if (rhp->flags & ZRH_PREDISPLAY)
|
||||
alloclen++; /* "P" */
|
||||
@@ -461,7 +466,7 @@ get_region_highlight(UNUSED(Param pm))
|
||||
offset = sprintf(*arrp, "%s%s ",
|
||||
(rhp->flags & ZRH_PREDISPLAY) ? "P" : "",
|
||||
digbuf);
|
||||
(void)output_highlight(rhp->atr, *arrp + offset);
|
||||
(void)output_highlight(rhp->atr, rhp->atrmask, *arrp + offset);
|
||||
|
||||
if (rhp->layer != 10)
|
||||
strcat(*arrp, layerbuf);
|
||||
@@ -537,7 +542,8 @@ set_region_highlight(UNUSED(Param pm), char **aval)
|
||||
strp++;
|
||||
|
||||
rhp->layer = 10; /* default */
|
||||
strp = (char*) match_highlight(strp, &rhp->atr, &rhp->layer);
|
||||
strp = (char*) match_highlight(strp, &rhp->atr, &rhp->atrmask,
|
||||
&rhp->layer);
|
||||
|
||||
while (inblank(*strp))
|
||||
strp++;
|
||||
@@ -1155,6 +1161,9 @@ zrefresh(void)
|
||||
zputs("\n", shout); /* works with both hasam and !hasam */
|
||||
/* lpromptbuf includes literal escapes so we need to update for it */
|
||||
txtcurrentattrs = txtpendingattrs = pmpt_attr;
|
||||
/* Unknown attributes remain so but if sequences were embedded
|
||||
* directly in the prompt, let's not needlessly reset them. */
|
||||
txtunknownattrs = 0;
|
||||
}
|
||||
if (clearflag) {
|
||||
zputc(&zr_cr);
|
||||
@@ -1197,7 +1206,7 @@ zrefresh(void)
|
||||
rpms.s = nbuf[rpms.ln = 0] + lpromptw;
|
||||
rpms.sen = *nbuf + winw;
|
||||
for (t = tmpline, tmppos = 0; tmppos < tmpll; t++, tmppos++) {
|
||||
zattr base_attr = mixattrs(default_attr, prompt_attr);
|
||||
zattr base_attr = mixattrs(default_attr, default_attr, prompt_attr);
|
||||
zattr all_attr = 0;
|
||||
struct region_highlight *rhp;
|
||||
int layer, nextlayer = 0;
|
||||
@@ -1219,9 +1228,10 @@ zrefresh(void)
|
||||
offset = predisplaylen; /* increment over it */
|
||||
if (rhp->start + offset <= tmppos &&
|
||||
tmppos < rhp->end + offset) {
|
||||
base_attr = mixattrs(rhp->atr, base_attr);
|
||||
base_attr = mixattrs(rhp->atr, rhp->atrmask, base_attr);
|
||||
if (layer > special_layer)
|
||||
all_attr = mixattrs(rhp->atr, all_attr);
|
||||
all_attr = mixattrs(rhp->atr, rhp->atrmask,
|
||||
all_attr);
|
||||
}
|
||||
} else if (rhp->layer > layer &&
|
||||
(rhp->layer < nextlayer || nextlayer <= layer)) {
|
||||
@@ -1229,7 +1239,7 @@ zrefresh(void)
|
||||
}
|
||||
}
|
||||
if (special_layer == layer) {
|
||||
all_attr = mixattrs(special_attr, base_attr);
|
||||
all_attr = mixattrs(special_attr, special_mask, base_attr);
|
||||
}
|
||||
} while (nextlayer > layer);
|
||||
|
||||
@@ -2467,7 +2477,7 @@ singlerefresh(ZLE_STRING_T tmpline, int tmpll, int tmpcs)
|
||||
}
|
||||
}
|
||||
}
|
||||
all_attr = mixattrs(special_attr, base_attr);
|
||||
all_attr = mixattrs(special_attr, special_mask, base_attr);
|
||||
|
||||
if (t0 == tmpcs)
|
||||
nvcs = vp - vbuf;
|
||||
|
||||
@@ -2503,7 +2503,7 @@ printfmt(char *fmt, int n, int dopr, int doesc)
|
||||
break;
|
||||
case 'H':
|
||||
if (p[1] == '{') {
|
||||
p = parsehighlight(p + 2, '}', &atr);
|
||||
p = parsehighlight(p + 2, '}', &atr, NULL);
|
||||
--p;
|
||||
if (atr != TXT_ERROR)
|
||||
treplaceattrs(atr);
|
||||
|
||||
142
Src/prompt.c
142
Src/prompt.c
@@ -277,7 +277,7 @@ zattrescape(zattr atr, int *len)
|
||||
/* Parse the argument for %H */
|
||||
/**/
|
||||
mod_export char *
|
||||
parsehighlight(char *arg, char endchar, zattr *atr)
|
||||
parsehighlight(char *arg, char endchar, zattr *atr, zattr *mask)
|
||||
{
|
||||
static int entered = 0;
|
||||
char *var = ".zle.hlgroups";
|
||||
@@ -294,7 +294,7 @@ parsehighlight(char *arg, char endchar, zattr *atr)
|
||||
if (ht && (node = (Param) ht->getnode(ht, arg))) {
|
||||
attrs = node->gsu.s->getfn(node);
|
||||
entered = 1;
|
||||
if (match_highlight(attrs, atr, 0) == attrs)
|
||||
if (match_highlight(attrs, atr, mask, NULL) == attrs)
|
||||
*atr = TXT_ERROR;
|
||||
} else
|
||||
*atr = TXT_ERROR;
|
||||
@@ -639,7 +639,7 @@ putpromptchar(int doprint, int endchar)
|
||||
break;
|
||||
case 'H':
|
||||
if (bv->fm[1] == '{') {
|
||||
bv->fm = parsehighlight(bv->fm + 2, '}', &atr);
|
||||
bv->fm = parsehighlight(bv->fm + 2, '}', &atr, NULL);
|
||||
--bv->fm;
|
||||
if (atr != TXT_ERROR) {
|
||||
treplaceattrs(atr);
|
||||
@@ -1757,23 +1757,27 @@ tunsetattrs(zattr newattrs)
|
||||
txtpendingattrs &= ~TXT_ATTR_BG_MASK;
|
||||
}
|
||||
|
||||
/* Merge two attribute sets. In an case where attributes might conflict
|
||||
* choose those from the first parameter. Foreground and background
|
||||
* colours are taken together - less likely to end up with unreadable
|
||||
* combinations. */
|
||||
/* Merge two attribute sets.
|
||||
* secondary is the background base attributes
|
||||
* primary is attributes to be overlaid, taking precedence.
|
||||
* mask indicates those attributes in primary that were explicitly
|
||||
* set allowing an explicitly disabled attribute in primary to take
|
||||
* precedence. */
|
||||
|
||||
/**/
|
||||
mod_export zattr
|
||||
mixattrs(zattr primary, zattr secondary)
|
||||
mixattrs(zattr primary, zattr mask, zattr secondary)
|
||||
{
|
||||
zattr result = secondary;
|
||||
/* take colours from primary */
|
||||
if (primary & (TXTFGCOLOUR|TXTBGCOLOUR))
|
||||
result &= ~TXT_ATTR_COLOUR_MASK;
|
||||
/* take font weight from primary */
|
||||
if (primary & TXT_ATTR_FONT_WEIGHT)
|
||||
result &= ~TXT_ATTR_FONT_WEIGHT;
|
||||
return result | primary;
|
||||
zattr select = mask & TXT_ATTR_ALL;
|
||||
|
||||
if (mask & TXTFGCOLOUR)
|
||||
select |= TXT_ATTR_FG_MASK;
|
||||
if (mask & TXTBGCOLOUR)
|
||||
select |= TXT_ATTR_BG_MASK;
|
||||
if (mask & TXT_ATTR_FONT_WEIGHT)
|
||||
select |= TXT_ATTR_FONT_WEIGHT;
|
||||
|
||||
return (primary & select) | (secondary & ~select);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
@@ -1797,7 +1801,7 @@ struct highlight {
|
||||
};
|
||||
|
||||
static const struct highlight highlights[] = {
|
||||
{ "none", 0, TXT_ATTR_ALL },
|
||||
{ "reset", 0, TXT_ATTR_ALL },
|
||||
{ "bold", TXTBOLDFACE, TXTFAINT },
|
||||
{ "faint", TXTFAINT, TXTBOLDFACE },
|
||||
{ "standout", TXTSTANDOUT, 0 },
|
||||
@@ -1923,15 +1927,17 @@ match_colour(const char **teststrp, int is_fg, int colour)
|
||||
/*
|
||||
* Match a set of highlights in the given teststr.
|
||||
* Set *on_var to reflect the values found.
|
||||
* Set *setmask to explicitly set attributes
|
||||
* Set *layer to the layer
|
||||
* Return a pointer to the first character not consumed.
|
||||
*/
|
||||
|
||||
/**/
|
||||
mod_export const char *
|
||||
match_highlight(const char *teststr, zattr *on_var, int *layer)
|
||||
match_highlight(const char *teststr, zattr *on_var, zattr *setmask, int *layer)
|
||||
{
|
||||
int found = 1;
|
||||
zattr mask = 0;
|
||||
|
||||
*on_var = 0;
|
||||
while (found && *teststr) {
|
||||
@@ -1941,7 +1947,7 @@ match_highlight(const char *teststr, zattr *on_var, int *layer)
|
||||
found = 0;
|
||||
if (strpfx("hl=", teststr)) {
|
||||
teststr += 3;
|
||||
teststr = parsehighlight((char *)teststr, ',', &atr);
|
||||
teststr = parsehighlight((char *)teststr, ',', &atr, &mask);
|
||||
if (atr != TXT_ERROR)
|
||||
*on_var = atr;
|
||||
found = 1;
|
||||
@@ -1958,6 +1964,7 @@ match_highlight(const char *teststr, zattr *on_var, int *layer)
|
||||
/* skip out of range colours but keep scanning attributes */
|
||||
if (atr != TXT_ERROR)
|
||||
*on_var |= atr;
|
||||
mask |= is_fg ? TXTFGCOLOUR : TXTBGCOLOUR;
|
||||
} else if (layer && strpfx("layer=", teststr)) {
|
||||
teststr += 6;
|
||||
*layer = (int) zstrtol(teststr, (char **) &teststr, 10);
|
||||
@@ -1967,7 +1974,8 @@ match_highlight(const char *teststr, zattr *on_var, int *layer)
|
||||
break;
|
||||
found = 1;
|
||||
} else {
|
||||
for (hl = highlights; hl->name; hl++) {
|
||||
int turn_off = 0;
|
||||
for (hl = highlights; !found && hl->name; hl++) {
|
||||
if (strpfx(hl->name, teststr)) {
|
||||
const char *val = teststr + strlen(hl->name);
|
||||
|
||||
@@ -1976,14 +1984,25 @@ match_highlight(const char *teststr, zattr *on_var, int *layer)
|
||||
else if (*val && *val != ' ')
|
||||
break;
|
||||
|
||||
*on_var |= hl->mask_on;
|
||||
*on_var &= ~hl->mask_off;
|
||||
if (turn_off) {
|
||||
*on_var &= ~hl->mask_on & ~hl->mask_off;
|
||||
} else {
|
||||
*on_var |= hl->mask_on;
|
||||
*on_var &= ~hl->mask_off;
|
||||
}
|
||||
mask |= hl->mask_on | hl->mask_off;
|
||||
teststr = val;
|
||||
found = 1;
|
||||
}
|
||||
/* delayed this to the end of the first iteration because
|
||||
* "noclear" isn't valid */
|
||||
if (hl == highlights && (turn_off = strpfx("no", teststr)))
|
||||
teststr += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (setmask)
|
||||
*setmask = mask;
|
||||
|
||||
return teststr;
|
||||
}
|
||||
@@ -2038,22 +2057,28 @@ output_colour(int colour, int fg_bg, int truecol, char *buf)
|
||||
|
||||
/**/
|
||||
mod_export int
|
||||
output_highlight(zattr atr, char *buf)
|
||||
output_highlight(zattr atr, zattr mask, char *buf)
|
||||
{
|
||||
const struct highlight *hp;
|
||||
int atrlen = 0, len;
|
||||
char *ptr = buf;
|
||||
|
||||
if (atr & TXTFGCOLOUR) {
|
||||
len = output_colour(txtchangeget(atr, TXT_ATTR_FG_COL),
|
||||
COL_SEQ_FG,
|
||||
(atr & TXT_ATTR_FG_24BIT),
|
||||
ptr);
|
||||
atrlen += len;
|
||||
if (buf)
|
||||
ptr += len;
|
||||
if (mask == TXT_ATTR_ALL) {
|
||||
zattr threebits = ~atr & TXT_ATTR_ALL;
|
||||
threebits &= threebits - 1; /* can't be both bold and faint */
|
||||
threebits &= threebits - 1; /* strip next bit to allow one "no" entry */
|
||||
|
||||
if (threebits) { /* more remain - shorter to start with "none" */
|
||||
mask &= atr; /* mark unset bits from atr as done */
|
||||
atrlen = 4;
|
||||
if (buf) {
|
||||
strcpy(ptr, "reset");
|
||||
ptr += 5;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (atr & TXTBGCOLOUR) {
|
||||
|
||||
if (mask & TXTFGCOLOUR) {
|
||||
if (atrlen) {
|
||||
atrlen++;
|
||||
if (buf) {
|
||||
@@ -2061,16 +2086,46 @@ output_highlight(zattr atr, char *buf)
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
len = output_colour(txtchangeget(atr, TXT_ATTR_BG_COL),
|
||||
COL_SEQ_BG,
|
||||
(atr & TXT_ATTR_BG_24BIT),
|
||||
ptr);
|
||||
atrlen += len;
|
||||
if (buf)
|
||||
ptr += len;
|
||||
if (atr & TXTFGCOLOUR) {
|
||||
len = output_colour(txtchangeget(atr, TXT_ATTR_FG_COL), COL_SEQ_FG,
|
||||
(atr & TXT_ATTR_FG_24BIT), ptr);
|
||||
atrlen += len;
|
||||
if (buf)
|
||||
ptr += len;
|
||||
} else {
|
||||
atrlen += 10;
|
||||
if (buf) {
|
||||
strcpy(ptr, "fg=default");
|
||||
ptr += 10;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mask & TXTBGCOLOUR) {
|
||||
if (atrlen) {
|
||||
atrlen++;
|
||||
if (buf) {
|
||||
strcpy(ptr, ",");
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
if (atr & TXTBGCOLOUR) {
|
||||
len = output_colour(txtchangeget(atr, TXT_ATTR_BG_COL), COL_SEQ_BG,
|
||||
(atr & TXT_ATTR_BG_24BIT), ptr);
|
||||
atrlen += len;
|
||||
if (buf)
|
||||
ptr += len;
|
||||
} else {
|
||||
atrlen += 10;
|
||||
if (buf) {
|
||||
strcpy(ptr, "bg=default");
|
||||
ptr += 10;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (hp = highlights; hp->name; hp++) {
|
||||
if (hp->mask_on & atr) {
|
||||
if (hp->mask_on & mask && !(hp->mask_off & mask & atr)) {
|
||||
mask &= ~hp->mask_off;
|
||||
if (atrlen) {
|
||||
atrlen++;
|
||||
if (buf) {
|
||||
@@ -2078,6 +2133,13 @@ output_highlight(zattr atr, char *buf)
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
if (!(hp->mask_on & atr)) {
|
||||
atrlen += 2;
|
||||
if (buf) {
|
||||
strcpy(ptr, "no");
|
||||
ptr += 2;
|
||||
}
|
||||
}
|
||||
len = strlen(hp->name);
|
||||
atrlen += len;
|
||||
if (buf) {
|
||||
|
||||
Reference in New Issue
Block a user