Subject: PATCH: allow default match specs to be disabled (was Re: [PATCH v4] zsh localedef completion)
From: Oliver Kiddle <[email-masked]>
To: [email-masked]
Date: Sat, 18 Jun 2016 23:17:05 +0200
List-Id: Zsh Workers List <zsh-workers.zsh.org>

On 15 Jun, Eric Cook wrote:
>
> > Perhaps we could
> > allow a special token in match specs that would cause subsequent specs
> > to be ignored or filtered?
>
> If it isn't hard to do, sure; i wouldn't mind it.

Turns out it isn't hard to do.

This patch uses x: as the token. Any thoughts on that or alternative
suggestions?

There's nothing in the documentation to suggest that the ordering of
matching specifications has any effect. Is anyone aware of whether it
perhaps does?

The documentation of the matcher style was perhaps deceptive in
indicating that it is tried before matcher-list. The value is merely
placed before those from matcher-list.

Oliver

diff --git a/Doc/Zsh/compsys.yo b/Doc/Zsh/compsys.yo
index c97f80f..fb0abce 100644
--- a/Doc/Zsh/compsys.yo
+++ b/Doc/Zsh/compsys.yo
@@ -2023,8 +2023,9 @@ only be performed with the `tt(*)' inserted.
 kindex(matcher, completion style)
 item(tt(matcher))(
 This style is tested separately for each tag valid in the current
-context.  Its value is tried before any match specifications given by the 
-tt(matcher-list) style.  It should be in the form described in
+context.  Its value is placed before any match specifications given by the
+tt(matcher-list) style so can override them via the use of an tt(x:)
+specification.  The value should be in the form described in
 ifzman(the section `Completion Matching Control' in zmanref(zshcompwid))\
 ifnzman(noderef(Completion Matching Control))\
 .  For examples of this, see the description of the tt(tag-order) style.
diff --git a/Doc/Zsh/compwid.yo b/Doc/Zsh/compwid.yo
index c017633..1cc94bf 100644
--- a/Doc/Zsh/compwid.yo
+++ b/Doc/Zsh/compwid.yo
@@ -913,6 +913,13 @@ line and trial completion patterns are anchored on the right side.
 Here an empty var(ranchor) and the tt(e) and tt(E) forms force the
 match to the end of the command line or trial completion string.
 )
+item(tt(x:))(
+This form is used to mark the end of matching specifications:
+subsequent specifications are ignored. In a single standalone list
+of specifications this has no use but where matching specifications
+are accumulated, such as from nested function calls, it can allow one
+function to override another.
+)
 enditem()
 
 Each var(lpat), var(tpat) or var(anchor) is either an empty string or
diff --git a/Src/Zle/complete.c b/Src/Zle/complete.c
index 30fab54..0c14d86 100644
--- a/Src/Zle/complete.c
+++ b/Src/Zle/complete.c
@@ -241,6 +241,7 @@ parse_cmatcher(char *name, char *s)
 	case 'E': fl2 = CMF_INTER;
 	case 'R': fl = CMF_RIGHT | CMF_LINE; break;
 	case 'M': fl = CMF_LINE; break;
+	case 'x': break;
 	default:
 	    if (name)
 		zwarnnam(name, "unknown match specification character `%c'",
@@ -252,6 +253,15 @@ parse_cmatcher(char *name, char *s)
 		zwarnnam(name, "missing `:'");
 	    return pcm_err;
 	}
+	if (*s == 'x') {
+	    if (s[2] && !inblank(s[2])) {
+		if (name)
+		    zwarnnam(name,
+			"unexpected pattern following x: specification");
+		return pcm_err;
+	    }
+	    return ret;
+	}
 	s += 2;
 	if (!*s) {
 	    if (name)