Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

[PATCH] Re: Should we be avoiding "zstyle -m" ?



On Mon, Jan 8, 2024 at 8:52 AM Peter Stephenson
<p.w.stephenson@xxxxxxxxxxxx> wrote:
>
> > On 07/01/2024 20:06 GMT Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx> wrote:
> >
> > on a quick glance at the code I think they may be identical (that is,
> > that
> >   zstyle -L ":completion:$curcontext"
> > would give the desired result), but there's a lot going on in there.
> >
> > So what to do here?  Ideas that occur to me ...
> >
> > 2) Add a -q option to -L, to exit 0 or 1 on found or not found,
> > without printing.
>
> The -q and -L combination sounds like it ought to be reasonably easy
> (pass through a flag to suppress output) and ought to be quite flexible
> as -L already has a lot of search configurability built into it, maybe?

Sadly all zstyle options are singletons, that is, it doesn't use the
normal option parsing but only looks at argv[0][1].  Combining options
is not friendly.

Also -L acts more like -g than like -m, and what's wanted here is -m.
That is, -L doesn't apply the zstyle pattern to the context, it treats
the context as a pattern (which is why the doc calls it a
"metapattern") and looks for a zstyle pattern that matches it.  Which
could be shoehorned into working, I guess, but is not straightforward
for this use case.

So amend the above to say "add a -q option that acts like -m except ..."

It's possible this could be refactored but that felt uglier than
duplicating a couple of tests.
diff --git a/Doc/Zsh/mod_zutil.yo b/Doc/Zsh/mod_zutil.yo
index 3cf9e5028..9946618d6 100644
--- a/Doc/Zsh/mod_zutil.yo
+++ b/Doc/Zsh/mod_zutil.yo
@@ -11,6 +11,7 @@ xitem(tt(zstyle) [ tt(-L) [ var(metapattern) [ var(style) ] ] ])
 xitem(tt(zstyle) [ tt(-e) | tt(-) | tt(-)tt(-) ] var(pattern) var(style) var(string) ...)
 xitem(tt(zstyle -d) [ var(pattern) [ var(style) ... ] ])
 xitem(tt(zstyle -g) var(name) [ var(pattern) [ var(style) ] ])
+xitem(tt(zstyle -q) var(context) var(style))
 xitem(tt(zstyle -){tt(a)|tt(b)|tt(s)} var(context) var(style) var(name) [ var(sep) ])
 xitem(tt(zstyle -){tt(T)|tt(t)} var(context) var(style) [ var(string) ... ])
 item(tt(zstyle -m) var(context) var(style) var(pattern))(
@@ -105,6 +106,12 @@ enditem()
 The other forms can be used to look up or test styles for a given context.
 
 startitem()
+item(tt(zstyle -q) var(context) var(style))(
+Return tt(0) if var(style) is defined in var(context).  This does not
+evaluate expressions defined by tt(zstyle -e) and does not examine any
+values set by var(style).  The expected use is to test whether a style
+has been defined for var(context) before asserting a new style.
+)
 item(tt(zstyle -s) var(context) var(style) var(name) [ var(sep) ])(
 The parameter var(name) is set to the value of the style interpreted as a
 string.  If the value contains several strings they are concatenated with
diff --git a/Src/Modules/zutil.c b/Src/Modules/zutil.c
index 8b863d5c8..293a62dcf 100644
--- a/Src/Modules/zutil.c
+++ b/Src/Modules/zutil.c
@@ -461,6 +461,28 @@ lookupstyle(char *ctxt, char *style)
     return found;
 }
 
+static int
+testforstyle(char *ctxt, char *style)
+{
+    Style s;
+    Stypat p;
+    int found = 0;
+
+    s = (Style)zstyletab->getnode2(zstyletab, style);
+    if (s) {
+	MatchData match;
+	savematch(&match);
+	for (p = s->pats; p; p = p->next)
+	    if (pattry(p->prog, ctxt)) {
+		found = 1;
+		break;
+	    }
+	restorematch(&match);
+    }
+
+    return !found;	/* 0 == success */
+}
+
 static int
 bin_zstyle(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
 {
@@ -570,6 +592,7 @@ bin_zstyle(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
     case 't': min = 2; max = -1; break;
     case 'T': min = 2; max = -1; break;
     case 'm': min = 3; max =  3; break;
+    case 'q': min = 2; max =  2; break;
     case 'g': min = 1; max =  3; break;
     default:
 	zwarnnam(nam, "invalid option: %s", args[0]);
@@ -723,6 +746,15 @@ bin_zstyle(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
 	    return 1;
 	}
 	break;
+    case 'q':
+	{
+	    int success;
+	    queue_signals();	/* Protect PAT_STATIC */
+	    success = testforstyle(args[1], args[2]);
+	    unqueue_signals();
+	    return success;
+	}
+	break;
     case 'g':
 	{
 	    int ret = 1;


Messages sorted by: Reverse Date, Date, Thread, Author