Skip to content

Commit 85545af

Browse files
author
Oliver Kiddle
committed
52500: add layer token to zle attributes
This provide control over the precedence of highlighting where different regions overlap.
1 parent 3c5dacd commit 85545af

File tree

4 files changed

+88
-46
lines changed

4 files changed

+88
-46
lines changed

ChangeLog

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
2024-01-28 Oliver Kiddle <[email protected]>
22

3+
* 52500: Src/Zle/zle.h, Src/Zle/zle_refresh.c, Src/prompt.c:
4+
add layer token to zle attributes to provide control over
5+
the precedence of highlighting
6+
37
* 52499: Src/prompt.c: support highlight groups defined in a
48
.zle.hlgroups associative array and referenced using %H in
59
prompt strings or hl= in zle_highlight/region_highlight

Src/Zle/zle.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,8 @@ enum {
435435
struct region_highlight {
436436
/* Attributes turned on in the region */
437437
zattr atr;
438+
/* Priority for this region relative to others that overlap */
439+
int layer;
438440
/* Start of the region */
439441
int start;
440442
/* Start of the region in metafied ZLE line */

Src/Zle/zle_refresh.c

Lines changed: 71 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,12 @@ int predisplaylen, postdisplaylen;
210210

211211
static zattr default_attr, special_attr, ellipsis_attr;
212212

213+
/*
214+
* Layer applied to highlighting for special characters
215+
*/
216+
217+
static int special_layer;
218+
213219
/*
214220
* Array of region highlights, no special termination.
215221
* The first N_SPECIAL_HIGHLIGHTS elements describe special uses of
@@ -337,6 +343,13 @@ zle_set_highlight(void)
337343
}
338344
}
339345

346+
/* Default layers */
347+
region_highlights[0].layer = 20; /* region */
348+
region_highlights[1].layer = 20; /* isearch */
349+
region_highlights[2].layer = 10; /* suffix */
350+
region_highlights[3].layer = 15; /* paste */
351+
special_layer = 30;
352+
340353
if (atrs) {
341354
for (; *atrs; atrs++) {
342355
if (!strcmp(*atrs, "none")) {
@@ -346,30 +359,34 @@ zle_set_highlight(void)
346359
paste_attr_set = region_attr_set =
347360
isearch_attr_set = suffix_attr_set = 1;
348361
} else if (strpfx("default:", *atrs)) {
349-
match_highlight(*atrs + 8, &default_attr);
362+
match_highlight(*atrs + 8, &default_attr, NULL);
350363
} else if (strpfx("special:", *atrs)) {
351-
match_highlight(*atrs + 8, &special_attr);
364+
match_highlight(*atrs + 8, &special_attr, &special_layer);
352365
special_attr_set = 1;
353366
} else if (strpfx("region:", *atrs)) {
354-
match_highlight(*atrs + 7, &region_highlights[0].atr);
367+
match_highlight(*atrs + 7, &(region_highlights[0].atr),
368+
&(region_highlights[0].layer));
355369
region_attr_set = 1;
356370
} else if (strpfx("isearch:", *atrs)) {
357-
match_highlight(*atrs + 8, &(region_highlights[1].atr));
371+
match_highlight(*atrs + 8, &(region_highlights[1].atr),
372+
&(region_highlights[1].layer));
358373
isearch_attr_set = 1;
359374
} else if (strpfx("suffix:", *atrs)) {
360-
match_highlight(*atrs + 7, &(region_highlights[2].atr));
375+
match_highlight(*atrs + 7, &(region_highlights[2].atr),
376+
&(region_highlights[2].layer));
361377
suffix_attr_set = 1;
362378
} else if (strpfx("paste:", *atrs)) {
363-
match_highlight(*atrs + 6, &(region_highlights[3].atr));
379+
match_highlight(*atrs + 6, &(region_highlights[3].atr),
380+
&(region_highlights[3].layer));
364381
paste_attr_set = 1;
365382
} else if (strpfx("ellipsis:", *atrs)) {
366-
match_highlight(*atrs + 9, &ellipsis_attr);
383+
match_highlight(*atrs + 9, &ellipsis_attr, NULL);
367384
ellipsis_attr_set = 1;
368385
}
369386
}
370387
}
371388

372-
/* Defaults */
389+
/* Default attributes */
373390
if (!special_attr_set)
374391
special_attr = TXTSTANDOUT;
375392
if (!region_attr_set)
@@ -407,35 +424,32 @@ zle_free_highlight(void)
407424
char **
408425
get_region_highlight(UNUSED(Param pm))
409426
{
410-
int arrsize = n_region_highlights;
427+
int arrsize = n_region_highlights - N_SPECIAL_HIGHLIGHTS;
411428
char **retarr, **arrp;
412429
struct region_highlight *rhp;
413430

414431
/* region_highlights may not have been set yet */
415-
if (!arrsize)
432+
if (!n_region_highlights)
416433
return hmkarray(NULL);
417-
arrsize -= N_SPECIAL_HIGHLIGHTS;
418434
DPUTS(arrsize < 0, "arrsize is negative from n_region_highlights");
419435
arrp = retarr = (char **)zhalloc((arrsize+1)*sizeof(char *));
420436

421437
/* ignore special highlighting */
422438
for (rhp = region_highlights + N_SPECIAL_HIGHLIGHTS;
423439
arrsize--;
424440
rhp++, arrp++) {
425-
char digbuf1[DIGBUFSIZE], digbuf2[DIGBUFSIZE];
426-
int atrlen, alloclen;
427-
const char memo_equals[] = "memo=";
428-
429-
sprintf(digbuf1, "%d", rhp->start);
430-
sprintf(digbuf2, "%d", rhp->end);
431-
432-
atrlen = output_highlight(rhp->atr, NULL);
433-
alloclen = atrlen + strlen(digbuf1) + strlen(digbuf2) +
434-
3; /* 2 spaces, 1 terminating NUL */
441+
char digbuf[2 * DIGBUFSIZE], layerbuf[7 + DIGBUFSIZE];
442+
int offset;
443+
const char memo_equals[] = " memo=";
444+
int alloclen = sprintf(digbuf, "%d %d", rhp->start, rhp->end) +
445+
output_highlight(rhp->atr, NULL) +
446+
2; /* space and terminating NUL */
435447
if (rhp->flags & ZRH_PREDISPLAY)
436-
alloclen += 2; /* "P " */
448+
alloclen++; /* "P" */
449+
if (rhp->layer != 10)
450+
alloclen += sprintf(layerbuf, ",layer=%d", rhp->layer);
437451
if (rhp->memo)
438-
alloclen += 1 /* space */ + strlen(memo_equals) + strlen(rhp->memo);
452+
alloclen += sizeof(memo_equals) - 1 + strlen(rhp->memo);
439453
*arrp = (char *)zhalloc(alloclen * sizeof(char));
440454
/*
441455
* On input we allow a space after the flags.
@@ -444,13 +458,14 @@ get_region_highlight(UNUSED(Param pm))
444458
* into three words, and then check the first to
445459
* see if there are flags. However, it's arguable.
446460
*/
447-
sprintf(*arrp, "%s%s %s ",
461+
offset = sprintf(*arrp, "%s%s ",
448462
(rhp->flags & ZRH_PREDISPLAY) ? "P" : "",
449-
digbuf1, digbuf2);
450-
(void)output_highlight(rhp->atr, *arrp + strlen(*arrp));
463+
digbuf);
464+
(void)output_highlight(rhp->atr, *arrp + offset);
451465

466+
if (rhp->layer != 10)
467+
strcat(*arrp, layerbuf);
452468
if (rhp->memo) {
453-
strcat(*arrp, " ");
454469
strcat(*arrp, memo_equals);
455470
strcat(*arrp, rhp->memo);
456471
}
@@ -459,12 +474,10 @@ get_region_highlight(UNUSED(Param pm))
459474
return retarr;
460475
}
461476

462-
463477
/*
464478
* The parameter system requires the pm argument, but this
465479
* may be NULL if called directly.
466480
*/
467-
468481
/**/
469482
void
470483
set_region_highlight(UNUSED(Param pm), char **aval)
@@ -523,7 +536,8 @@ set_region_highlight(UNUSED(Param pm), char **aval)
523536
while (inblank(*strp))
524537
strp++;
525538

526-
strp = (char*) match_highlight(strp, &rhp->atr);
539+
rhp->layer = 10; /* default */
540+
strp = (char*) match_highlight(strp, &rhp->atr, &rhp->layer);
527541

528542
while (inblank(*strp))
529543
strp++;
@@ -1180,27 +1194,40 @@ zrefresh(void)
11801194
rpms.s = nbuf[rpms.ln = 0] + lpromptw;
11811195
rpms.sen = *nbuf + winw;
11821196
for (t = tmpline, tmppos = 0; tmppos < tmpll; t++, tmppos++) {
1183-
unsigned ireg;
11841197
zattr base_attr = mixattrs(default_attr, prompt_attr);
11851198
zattr all_attr;
11861199
struct region_highlight *rhp;
1200+
int layer, nextlayer = 0;
11871201
/*
11881202
* Calculate attribute based on region.
11891203
*/
1190-
for (ireg = 0, rhp = region_highlights;
1191-
ireg < n_region_highlights;
1192-
ireg++, rhp++) {
1193-
int offset;
1194-
if (rhp->flags & ZRH_PREDISPLAY)
1195-
offset = 0; /* include predisplay in start end */
1196-
else
1197-
offset = predisplaylen; /* increment over it */
1198-
if (rhp->start + offset <= tmppos &&
1199-
tmppos < rhp->end + offset) {
1200-
base_attr = mixattrs(rhp->atr, base_attr);
1204+
do {
1205+
unsigned ireg;
1206+
layer = nextlayer;
1207+
nextlayer = special_layer;
1208+
for (ireg = 0, rhp = region_highlights;
1209+
ireg < n_region_highlights;
1210+
ireg++, rhp++) {
1211+
if (rhp->layer == layer) {
1212+
int offset;
1213+
if (rhp->flags & ZRH_PREDISPLAY)
1214+
offset = 0; /* include predisplay in start end */
1215+
else
1216+
offset = predisplaylen; /* increment over it */
1217+
if (rhp->start + offset <= tmppos &&
1218+
tmppos < rhp->end + offset) {
1219+
base_attr = mixattrs(rhp->atr, base_attr);
1220+
if (layer > special_layer)
1221+
all_attr = mixattrs(rhp->atr, all_attr);
1222+
}
1223+
} else if (rhp->layer > layer && rhp->layer < nextlayer) {
1224+
nextlayer = rhp->layer;
1225+
}
12011226
}
1202-
}
1203-
all_attr = mixattrs(special_attr, base_attr);
1227+
if (special_layer == layer) {
1228+
all_attr = mixattrs(special_attr, base_attr);
1229+
}
1230+
} while (nextlayer > layer);
12041231

12051232
if (t == scs) /* if cursor is here, remember it */
12061233
rpms.nvcs = rpms.s - nbuf[rpms.nvln = rpms.ln];

Src/prompt.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ parsehighlight(char *arg, char endchar, zattr *atr)
260260
if ((node = (Param) ht->getnode(ht, arg))) {
261261
attrs = node->gsu.s->getfn(node);
262262
entered = 1;
263-
if (match_highlight(attrs, atr) == attrs)
263+
if (match_highlight(attrs, atr, 0) == attrs)
264264
*atr = TXT_ERROR;
265265
} else
266266
*atr = TXT_ERROR;
@@ -1884,12 +1884,13 @@ match_colour(const char **teststrp, int is_fg, int colour)
18841884
/*
18851885
* Match a set of highlights in the given teststr.
18861886
* Set *on_var to reflect the values found.
1887+
* Set *layer to the layer
18871888
* Return a pointer to the first character not consumed.
18881889
*/
18891890

18901891
/**/
18911892
mod_export const char *
1892-
match_highlight(const char *teststr, zattr *on_var)
1893+
match_highlight(const char *teststr, zattr *on_var, int *layer)
18931894
{
18941895
int found = 1;
18951896

@@ -1918,6 +1919,14 @@ match_highlight(const char *teststr, zattr *on_var)
19181919
/* skip out of range colours but keep scanning attributes */
19191920
if (atr != TXT_ERROR)
19201921
*on_var |= atr;
1922+
} else if (layer && strpfx("layer=", teststr)) {
1923+
teststr += 6;
1924+
*layer = (int) zstrtol(teststr, (char **) &teststr, 10);
1925+
if (*teststr == ',')
1926+
teststr++;
1927+
else if (*teststr && *teststr != ' ')
1928+
break;
1929+
found = 1;
19211930
} else {
19221931
for (hl = highlights; hl->name; hl++) {
19231932
if (strpfx(hl->name, teststr)) {

0 commit comments

Comments
 (0)