about summary refs log tree commit diff
diff options
context:
space:
mode:
authorOliver Kiddle <opk@zsh.org>2024-01-28 00:34:05 +0100
committerOliver Kiddle <opk@zsh.org>2024-01-28 00:34:21 +0100
commit3c5dacd503a2ac81059346b37d16ab5d1b6a1e04 (patch)
tree555a7b6b0684a3cda54c2e899189d4a028d6ea00
parent8e622c25b24fb0b0d6e705fab97960351e123c65 (diff)
downloadzsh-3c5dacd503a2ac81059346b37d16ab5d1b6a1e04.tar.gz
zsh-3c5dacd503a2ac81059346b37d16ab5d1b6a1e04.tar.xz
zsh-3c5dacd503a2ac81059346b37d16ab5d1b6a1e04.zip
52499: support highlight groups
These are defined in a .zle.hlgroups associative array and referenced
using %H in prompt strings or hl= in zle_highlight/region_highlight.
-rw-r--r--ChangeLog4
-rw-r--r--Src/prompt.c50
2 files changed, 52 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index 240fb0581..2e0b085e5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
 2024-01-28  Oliver Kiddle  <opk@zsh.org>
 
+	* 52499: Src/prompt.c: support highlight groups defined in a
+	.zle.hlgroups associative array and referenced using %H in
+	prompt strings or hl= in zle_highlight/region_highlight
+
 	* unposted: Src/Modules/zutil.c: remove unused variable to silence
 	compiler warning
 
diff --git a/Src/prompt.c b/Src/prompt.c
index 39fcf5eb7..e4c213a13 100644
--- a/Src/prompt.c
+++ b/Src/prompt.c
@@ -241,6 +241,39 @@ promptexpand(char *s, int ns, char *rs, char *Rs)
     return new_vars.buf;
 }
 
+/* Parse the argument for %H */
+static char *
+parsehighlight(char *arg, char endchar, zattr *atr)
+{
+    static int entered = 0;
+    char *var = ".zle.hlgroups";
+    struct value vbuf;
+    Value v;
+    char *ep, *attrs;
+    if ((ep = strchr(arg, endchar)))
+	*ep = '\0';
+    if (!entered && (v = getvalue(&vbuf, &var, 0)) &&
+	    PM_TYPE(v->pm->node.flags) == PM_HASHED)
+    {
+	Param node;
+	HashTable ht = v->pm->gsu.h->getfn(v->pm);
+	if ((node = (Param) ht->getnode(ht, arg))) {
+	    attrs = node->gsu.s->getfn(node);
+	    entered = 1;
+	    if (match_highlight(attrs, atr) == attrs)
+		*atr = TXT_ERROR;
+	} else
+	    *atr = TXT_ERROR;
+    } else
+	*atr = TXT_ERROR;
+    if (ep)
+	*ep = endchar;
+    else
+	ep = strchr(arg, '\0') - 1;
+    entered = 0;
+    return ep;
+}
+
 /* Parse the argument for %F and %K */
 static zattr
 parsecolorchar(zattr arg, int is_fg)
@@ -571,6 +604,13 @@ putpromptchar(int doprint, int endchar)
 		tunsetattrs(TXTBGCOLOUR);
 	        applytextattributes(TSC_PROMPT);
 		break;
+	    case 'H':
+		bv->fm = parsehighlight(bv->fm + 2, '}', &atr);
+		if (atr != TXT_ERROR) {
+		    treplaceattrs(atr);
+		    applytextattributes(TSC_PROMPT);
+		}
+		break;
 	    case '[':
 		if (idigit(*++bv->fm))
 		    arg = zstrtol(bv->fm, &bv->fm, 10);
@@ -1856,11 +1896,17 @@ match_highlight(const char *teststr, zattr *on_var)
     *on_var = 0;
     while (found && *teststr) {
 	const struct highlight *hl;
+	zattr atr = 0;
 
 	found = 0;
-	if (strpfx("fg=", teststr) || strpfx("bg=", teststr)) {
+	if (strpfx("hl=", teststr)) {
+	    teststr += 3;
+	    teststr = parsehighlight((char *)teststr, ',', &atr);
+	    if (atr != TXT_ERROR)
+		*on_var = atr;
+	    found = 1;
+	} else if (strpfx("fg=", teststr) || strpfx("bg=", teststr)) {
 	    int is_fg = (teststr[0] == 'f');
-	    zattr atr;
 
 	    teststr += 3;
 	    atr = match_colour(&teststr, is_fg, 0);