summaryrefslogtreecommitdiff
path: root/Src
diff options
context:
space:
mode:
Diffstat (limited to 'Src')
-rw-r--r--Src/Zle/zle.h4
-rw-r--r--Src/Zle/zle_refresh.c62
-rw-r--r--Src/Zle/zle_utils.c21
-rw-r--r--Src/prompt.c9
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;
}
/*