diff options
Diffstat (limited to 'Src')
-rw-r--r-- | Src/Zle/zle.h | 4 | ||||
-rw-r--r-- | Src/Zle/zle_refresh.c | 62 | ||||
-rw-r--r-- | Src/Zle/zle_utils.c | 21 | ||||
-rw-r--r-- | Src/prompt.c | 9 |
4 files changed, 87 insertions, 9 deletions
diff --git a/Src/Zle/zle.h b/Src/Zle/zle.h index 609493f8c..391586c4a 100644 --- a/Src/Zle/zle.h +++ b/Src/Zle/zle.h @@ -447,6 +447,10 @@ struct region_highlight { * Any of the flags defined above. */ int flags; + /* + * User-settable "memo" key. Metafied. + */ + const char *memo; }; /* diff --git a/Src/Zle/zle_refresh.c b/Src/Zle/zle_refresh.c index 7b8593dec..d9d9503e2 100644 --- a/Src/Zle/zle_refresh.c +++ b/Src/Zle/zle_refresh.c @@ -212,9 +212,9 @@ static zattr default_atr_on, special_atr_on; /* * Array of region highlights, no special termination. - * The first element (0) always describes the region between - * point and mark. Any other elements are set by the user - * via the parameter region_highlight. + * The first N_SPECIAL_HIGHLIGHTS elements describe special uses of + * highlighting, documented under N_SPECIAL_HIGHLIGHTS. + * Any other elements are set by the user via the parameter region_highlight. */ /**/ @@ -414,16 +414,19 @@ get_region_highlight(UNUSED(Param pm)) arrsize--; rhp++, arrp++) { char digbuf1[DIGBUFSIZE], digbuf2[DIGBUFSIZE]; - int atrlen = 0, alloclen; + int atrlen, alloclen; + const char memo_equals[] = "memo="; sprintf(digbuf1, "%d", rhp->start); sprintf(digbuf2, "%d", rhp->end); atrlen = output_highlight(rhp->atr, NULL); alloclen = atrlen + strlen(digbuf1) + strlen(digbuf2) + - 3; /* 2 spaces, 1 0 */ + 3; /* 2 spaces, 1 terminating NUL */ if (rhp->flags & ZRH_PREDISPLAY) alloclen += 2; /* "P " */ + if (rhp->memo) + alloclen += 1 /* space */ + strlen(memo_equals) + strlen(rhp->memo); *arrp = (char *)zhalloc(alloclen * sizeof(char)); /* * On input we allow a space after the flags. @@ -436,6 +439,12 @@ get_region_highlight(UNUSED(Param pm)) (rhp->flags & ZRH_PREDISPLAY) ? "P" : "", digbuf1, digbuf2); (void)output_highlight(rhp->atr, *arrp + strlen(*arrp)); + + if (rhp->memo) { + strcat(*arrp, " "); + strcat(*arrp, memo_equals); + strcat(*arrp, rhp->memo); + } } *arrp = NULL; return retarr; @@ -460,6 +469,8 @@ set_region_highlight(UNUSED(Param pm), char **aval) /* no null termination, but include special highlighting at start */ int newsize = len + N_SPECIAL_HIGHLIGHTS; int diffsize = newsize - n_region_highlights; + + free_region_highlights_memos(); region_highlights = (struct region_highlight *) zrealloc(region_highlights, sizeof(struct region_highlight) * newsize); @@ -476,6 +487,7 @@ set_region_highlight(UNUSED(Param pm), char **aval) *aval; rhp++, aval++) { char *strp, *oldstrp; + const char memo_equals[] = "memo="; oldstrp = *aval; if (*oldstrp == 'P') { @@ -502,7 +514,44 @@ set_region_highlight(UNUSED(Param pm), char **aval) while (inblank(*strp)) strp++; - match_highlight(strp, &rhp->atr); + strp = (char*) match_highlight(strp, &rhp->atr); + + while (inblank(*strp)) + strp++; + + if (strpfx(memo_equals, strp)) { + const char *memo_start = strp + strlen(memo_equals); + const char *i, *memo_end; + + /* + * Forward compatibility: end parsing at a comma or whitespace to + * allow the following extensions: + * + * - A fifth field: "0 20 bold memo=foo bar". + * + * - Additional attributes in the fourth field: "0 20 bold memo=foo,bar" + * and "0 20 bold memo=foo\0bar". + * + * For similar reasons, we don't flag an error if the fourth field + * doesn't start with "memo=" as we expect. + */ + i = memo_start; + + /* ### TODO: Consider optimizing the common case that memo_start to + * end-of-string is entirely ASCII */ + while (1) { + int nbytes; + convchar_t c = unmeta_one(i, &nbytes); + + if (c == '\0' || c == ',' || inblank(c)) { + memo_end = i; + break; + } else + i += nbytes; + } + rhp->memo = ztrduppfx(memo_start, memo_end - memo_start); + } else + rhp->memo = NULL; } freearray(av); @@ -2797,6 +2846,7 @@ zle_refresh_finish(void) if (region_highlights) { + free_region_highlights_memos(); zfree(region_highlights, sizeof(struct region_highlight) * n_region_highlights); region_highlights = NULL; diff --git a/Src/Zle/zle_utils.c b/Src/Zle/zle_utils.c index 2b306fdcd..927b88bba 100644 --- a/Src/Zle/zle_utils.c +++ b/Src/Zle/zle_utils.c @@ -557,6 +557,22 @@ zlegetline(int *ll, int *cs) } +/* + * free() the 'memo' elements of region_highlights. + */ + +/**/ +void +free_region_highlights_memos(void) +{ + struct region_highlight *rhp; + for (rhp = region_highlights; + rhp < region_highlights + n_region_highlights; + rhp++) { + zfree(rhp->memo, 0); + } +} + /* Forward reference */ struct zle_region; @@ -568,6 +584,7 @@ struct zle_region { int start; int end; int flags; + const char *memo; }; /* Forward reference */ @@ -632,6 +649,7 @@ zle_save_positions(void) newrhp->next = NULL; newrhp->atr = rhp->atr; newrhp->flags = rhp->flags; + newrhp->memo = ztrdup(rhp->memo); if (zlemetaline) { newrhp->start = rhp->start_meta; newrhp->end = rhp->end_meta; @@ -682,6 +700,7 @@ zle_restore_positions(void) nreg++, oldrhp = oldrhp->next) ; if (nreg + N_SPECIAL_HIGHLIGHTS != n_region_highlights) { + free_region_highlights_memos(); n_region_highlights = nreg + N_SPECIAL_HIGHLIGHTS; region_highlights = (struct region_highlight *) zrealloc(region_highlights, @@ -694,6 +713,7 @@ zle_restore_positions(void) rhp->atr = oldrhp->atr; rhp->flags = oldrhp->flags; + rhp->memo = oldrhp->memo; /* transferring ownership of the permanently-allocated memory */ if (zlemetaline) { rhp->start_meta = oldrhp->start; rhp->end_meta = oldrhp->end; @@ -707,6 +727,7 @@ zle_restore_positions(void) rhp++; } } else if (region_highlights) { + free_region_highlights_memos(); zfree(region_highlights, sizeof(struct region_highlight) * n_region_highlights); region_highlights = NULL; diff --git a/Src/prompt.c b/Src/prompt.c index b65bfb86b..bc9734720 100644 --- a/Src/prompt.c +++ b/Src/prompt.c @@ -1724,10 +1724,11 @@ 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. + * Return a pointer to the first character not consumed. */ /**/ -mod_export void +mod_export const char * match_highlight(const char *teststr, zattr *on_var) { int found = 1; @@ -1745,7 +1746,7 @@ match_highlight(const char *teststr, zattr *on_var) atr = match_colour(&teststr, is_fg, 0); if (*teststr == ',') teststr++; - else if (*teststr) + else if (*teststr && *teststr != ' ') break; found = 1; /* skip out of range colours but keep scanning attributes */ @@ -1758,7 +1759,7 @@ match_highlight(const char *teststr, zattr *on_var) if (*val == ',') val++; - else if (*val) + else if (*val && *val != ' ') break; *on_var |= hl->mask_on; @@ -1769,6 +1770,8 @@ match_highlight(const char *teststr, zattr *on_var) } } } + + return teststr; } /* |