zsh-workers
 help / color / mirror / code / Atom feed
From: Oliver Kiddle <opk@zsh.org>
To: Marlon Richert <marlon.richert@gmail.com>
Cc: Zsh workers <zsh-workers@zsh.org>
Subject: PATCH: highlight groups (was Re: Why are prompt expansions of %v sequences quoted in bindkey style?)
Date: Wed, 24 Jan 2024 23:41:09 +0100	[thread overview]
Message-ID: <16378-1706136069.980168@UYJb.QT-b._wqn> (raw)
In-Reply-To: <35F0FA32-34D7-4BF6-978D-EBFC2427ABE8@gmail.com>

[ moved to -workers ]

Marlon Richert wrote:
> Thanks, I think that might work for me. 
>
> I am indeed trying to use $psvar to dynamically update my prompt’s visual formatting, without the use of prompsubst or changing $PS1.

The following is something which I've been intending to add since the
attribute code refactoring from a year ago which added support for
italic and faint without adding new prompt escapes. The hardest part
of adding those now would be finding unused available letters and a
separate abstraction layer for visual attributes is rather more useful.

Highlight-groups is the term used by vim for its similar feature. What
this does is support an associative array named .zle.hlgroups and if
you refer to keys from that associative array with %H{...} in a prompt
or hl=... in zle_highlight, it will look up the actual attributes in
the associative array expecting the same format as zle_highlight (e.g.
fg=blue,bg=108,italic).

There is no corresponding end escape. %h is already taken for the
history event number. And while I could have used %A and %a, I'm not
quite sure what exactly the behaviour of %a should even be. %r (for
reset) which resets all attributes (or reverts to whatever the prompt
tag in zle_highlight specifies) might be more useful. Note that %H will
replace all attributes. With default: in zle_highlight, there
is some mixing of attributes with prompt leftovers that exists for
backward compatibility.

It is intentional that unrecognised strings at the end of attributes are
ignored without error to allow some forward compatibility with future
extensions. Recursion is blocked: you can't use hl= in .zle.hlgroups.

Oliver

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);


       reply	other threads:[~2024-01-24 22:41 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <CAHYJk3R8cpPSrNQOk8tnwz6bVYFVTfpJHz_DeFiYmCKHu880_Q@mail.gmail.com>
     [not found] ` <35F0FA32-34D7-4BF6-978D-EBFC2427ABE8@gmail.com>
2024-01-24 22:41   ` Oliver Kiddle [this message]
2024-01-25  9:12     ` Marlon Richert

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=16378-1706136069.980168@UYJb.QT-b._wqn \
    --to=opk@zsh.org \
    --cc=marlon.richert@gmail.com \
    --cc=zsh-workers@zsh.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).