summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOliver Kiddle <opk@zsh.org>2025-11-12 07:54:21 +0100
committerOliver Kiddle <opk@zsh.org>2025-11-12 07:55:05 +0100
commitd8666da9de4842b454567798e900c64c723c5e60 (patch)
treee5fcceacf66e5c8a2ea028c0ad577c7fd7d58757
parent54037: fix to highlight layers where special is assigned a low layer (diff)
downloadzsh-d8666da9de4842b454567798e900c64c723c5e60.tar
zsh-d8666da9de4842b454567798e900c64c723c5e60.tar.gz
zsh-d8666da9de4842b454567798e900c64c723c5e60.tar.bz2
zsh-d8666da9de4842b454567798e900c64c723c5e60.tar.lz
zsh-d8666da9de4842b454567798e900c64c723c5e60.tar.xz
zsh-d8666da9de4842b454567798e900c64c723c5e60.tar.zst
zsh-d8666da9de4842b454567798e900c64c723c5e60.zip
54043, 54055: allow highlighing attributes to be turned back off
-rw-r--r--ChangeLog6
-rw-r--r--Doc/Zsh/zle.yo43
-rw-r--r--Src/Modules/hlgroup.c2
-rw-r--r--Src/Modules/watch.c2
-rw-r--r--Src/Zle/complist.c2
-rw-r--r--Src/Zle/zle.h4
-rw-r--r--Src/Zle/zle_main.c4
-rw-r--r--Src/Zle/zle_refresh.c44
-rw-r--r--Src/Zle/zle_tricky.c2
-rw-r--r--Src/prompt.c142
10 files changed, 175 insertions, 76 deletions
diff --git a/ChangeLog b/ChangeLog
index e5b4e3486..10fca11de 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
diff --git a/Doc/Zsh/zle.yo b/Doc/Zsh/zle.yo
index e20184121..29a8b8597 100644
--- a/Doc/Zsh/zle.yo
+++ b/Doc/Zsh/zle.yo
@@ -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:
diff --git a/Src/Modules/hlgroup.c b/Src/Modules/hlgroup.c
index 6c5a4bec4..1dc6ac2ef 100644
--- a/Src/Modules/hlgroup.c
+++ b/Src/Modules/hlgroup.c
@@ -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) {
diff --git a/Src/Modules/watch.c b/Src/Modules/watch.c
index acc499518..0d86142c1 100644
--- a/Src/Modules/watch.c
+++ b/Src/Modules/watch.c
@@ -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);
}
diff --git a/Src/Zle/complist.c b/Src/Zle/complist.c
index ea18434a3..4c87c15d7 100644
--- a/Src/Zle/complist.c
+++ b/Src/Zle/complist.c
@@ -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);
}
diff --git a/Src/Zle/zle.h b/Src/Zle/zle.h
index 91eefc9e5..bf479d4cc 100644
--- a/Src/Zle/zle.h
+++ b/Src/Zle/zle.h
@@ -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 */
diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c
index d7b2ca21c..46d0e07d2 100644
--- a/Src/Zle/zle_main.c
+++ b/Src/Zle/zle_main.c
@@ -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);
diff --git a/Src/Zle/zle_refresh.c b/Src/Zle/zle_refresh.c
index 943eda672..8a89be333 100644
--- a/Src/Zle/zle_refresh.c
+++ b/Src/Zle/zle_refresh.c
@@ -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;
diff --git a/Src/Zle/zle_tricky.c b/Src/Zle/zle_tricky.c
index aa3c71bc2..f399ebd00 100644
--- a/Src/Zle/zle_tricky.c
+++ b/Src/Zle/zle_tricky.c
@@ -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);
diff --git a/Src/prompt.c b/Src/prompt.c
index 801f1a727..83a7667cc 100644
--- a/Src/prompt.c
+++ b/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) {