zsh-workers
 help / color / mirror / code / Atom feed
From: Oliver Kiddle <okiddle@yahoo.co.uk>
To: dana <dana@dana.is>, Zsh workers <zsh-workers@zsh.org>
Subject: completion match ordering
Date: Mon, 26 Nov 2018 02:25:50 +0100	[thread overview]
Message-ID: <76839-1543195550.251964@c6AU.RX4q.p78d> (raw)
In-Reply-To: <88812-1541586959.338018@YaNA.ZOZt.NKaA>

On 7 Nov, I wrote:
> You can do:
>   _arguments '-b-:level: compadd "${(@)expl/#-J/-2V}" ${(on)levels}'
> But what you have is perhaps better, especially as it's duplicated for
> -b and -e.

The patch below is an initial experiment for what I was suggesting.
It allows, e.g:
  _arguments '-b-:level:compadd -o numeric -a levels'

Any thoughts on the interface? Is something more terse like -on
preferable? The -V option becomes superfluous (but remains for
compatibility). Instead of -V grp you can use -J grp -o nosort.
Do we need to worry about this breaking uses of the old -o?

By the way, the change in 41242 has a problem: zstrcmp() doesn't honour
the SORTIT_IGNORING_BACKSLASHES flag if it is passed. This patch doesn't
attempt to fix that.

With this the existing, -o would become -o match and becomes a property
of the group rather than the match. Being associated with the group is
more consistent with related options like -1, -2 and -V. It might be
confusing that it doesn't work if no group is specified, however.

Besides match, nosort and numeric, should any other orderings be
supported? Reverse or case-sensitive perhaps? Zsh's numeric sorting
works well for version numbers which is useful for things like git
tags. This implementation allows combinations, e.g. -o match,numeric An
alternative might be allowing multiple -o options but that affects how
we compose options passed down from other functions.

Currently, given two -o options, only the first applies, This is
consistent with -X, -J etc even though I think it would have been better
if the last of these were used. In many cases where functions use
zparseopts to extract compadd options, they should be using J+: rather
than J: as zparseopts is taking the last one only with J:

Oliver

diff --git a/Src/Zle/comp.h b/Src/Zle/comp.h
index 3e9834560..46a35aa2d 100644
--- a/Src/Zle/comp.h
+++ b/Src/Zle/comp.h
@@ -90,6 +90,8 @@ struct cmgroup {
 #define CGF_PACKED  32		/* LIST_PACKED for this group */
 #define CGF_ROWS    64		/* LIST_ROWS_FIRST for this group */
 #define CGF_FILES   128		/* contains file names */
+#define CGF_MATSORT 256         /* sort by match rather than by display string */
+#define CGF_NUMSORT 512         /* sort numerically */
 
 /* This is the struct used to hold matches. */
 
@@ -300,6 +302,8 @@ struct menuinfo {
 #define CAF_ARRAYS  32    /* compadd -a or -k: array/assoc parameter names */
 #define CAF_KEYS    64    /* compadd -k: assoc parameter names */
 #define CAF_ALL    128    /* compadd -C: _all_matches */
+#define CAF_MATSORT 256   /* compadd -o match: sort by match rather than by display string */
+#define CAF_NUMSORT 512   /* compadd -o numeric: sort numerically */
 
 /* Data for compadd and addmatches() */
 
@@ -314,6 +318,7 @@ struct cadata {
     char *pre;			/* prefix to insert (-P) */
     char *suf;			/* suffix to insert (-S) */
     char *group;		/* name of the group (-[JV]) */
+    char *order;		/* group order (-o) */
     char *rems;			/* remove suffix on chars... (-r) */
     char *remf;			/* function to remove suffix (-R) */
     char *ign;			/* ignored suffixes (-F) */
diff --git a/Src/Zle/compcore.c b/Src/Zle/compcore.c
index 0a454ad5f..4163fa20b 100644
--- a/Src/Zle/compcore.c
+++ b/Src/Zle/compcore.c
@@ -2080,6 +2080,8 @@ addmatches(Cadata dat, char **argv)
 
         /* Select the group in which to store the matches. */
         gflags = (((dat->aflags & CAF_NOSORT ) ? CGF_NOSORT  : 0) |
+                  ((dat->aflags & CAF_MATSORT) ? CGF_MATSORT : 0) |
+                  ((dat->aflags & CAF_NUMSORT) ? CGF_NUMSORT : 0) |
                   ((dat->aflags & CAF_UNIQALL) ? CGF_UNIQALL : 0) |
                   ((dat->aflags & CAF_UNIQCON) ? CGF_UNIQCON : 0));
         if (dat->group) {
@@ -3034,8 +3036,8 @@ begcmgroup(char *n, int flags)
 		HEAP_ERROR(p->heap_id);
 	    }
 #endif
-	    if (p->name &&
-		flags == (p->flags & (CGF_NOSORT|CGF_UNIQALL|CGF_UNIQCON)) &&
+	    if (p->name && flags ==
+		(p->flags & (CGF_NOSORT|CGF_UNIQALL|CGF_UNIQCON|CGF_MATSORT|CGF_NUMSORT)) &&
 		!strcmp(n, p->name)) {
 		mgroup = p;
 
@@ -3118,32 +3120,33 @@ addexpl(int always)
 
 /* The comparison function for matches (used for sorting). */
 
+static int matchorder;
+
 /**/
 static int
 matchcmp(Cmatch *a, Cmatch *b)
 {
-    if ((*a)->disp && !((*a)->flags & CMF_MORDER)) {
-	if ((*b)->disp) {
-	    if ((*a)->flags & CMF_DISPLINE) {
-		if ((*b)->flags & CMF_DISPLINE)
-		    return strcmp((*a)->disp, (*b)->disp);
-		else
-		    return -1;
-	    } else {
-		if ((*b)->flags & CMF_DISPLINE)
-		    return 1;
-		else
-		    return strcmp((*a)->disp, (*b)->disp);
-	    }
-	}
-	return -1;
-    }
-    if ((*b)->disp && !((*b)->flags & CMF_MORDER))
-	return 1;
+    const char *as, *bs;
+    int cmp = !!(*b)->disp - !!(*a)->disp;
 
-    return zstrcmp((*a)->str, (*b)->str, (SORTIT_IGNORING_BACKSLASHES|
-					  (isset(NUMERICGLOBSORT) ?
-					   SORTIT_NUMERICALLY : 0)));
+    /* if match sorting selected or we have no display strings */
+    if ((matchorder & CGF_MATSORT) || (!cmp && !(*a)->disp)) {
+	as = (*a)->str;
+	bs = (*b)->str;
+    } else {
+        if (cmp) /* matches with display strings come first */
+	    return cmp;
+
+	cmp = ((*b)->flags & CMF_DISPLINE) - ((*a)->flags & CMF_DISPLINE);
+        if (cmp) /* sort one-per-line display strings first */
+	    return cmp;
+
+	as = (*a)->disp;
+	bs = (*b)->disp;
+    }
+
+    return zstrcmp(as, bs, (isset(NUMERICGLOBSORT) || matchorder & CGF_NUMSORT)
+	    ? SORTIT_NUMERICALLY : 0);
 }
 
 /* This tests whether two matches are equal (would produce the same
@@ -3205,6 +3208,7 @@ makearray(LinkList l, int type, int flags, int *np, int *nlp, int *llp)
     } else {
 	if (!(flags & CGF_NOSORT)) {
 	    /* Now sort the array (it contains matches). */
+	    matchorder = flags;
 	    qsort((void *) rp, n, sizeof(Cmatch),
 		  (int (*) _((const void *, const void *)))matchcmp);
 
diff --git a/Src/Zle/complete.c b/Src/Zle/complete.c
index 1dc2b01c2..316e51844 100644
--- a/Src/Zle/complete.c
+++ b/Src/Zle/complete.c
@@ -558,6 +558,12 @@ parse_class(Cpattern p, char *iptr)
     return iptr;
 }
 
+static struct { char *name; int oflag; } orderopts[] = {
+    { "nosort", CAF_NOSORT },
+    { "match", CAF_MATSORT },
+    { "numeric", CAF_NUMSORT }
+};
+
 /**/
 static int
 bin_compadd(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
@@ -572,8 +578,8 @@ bin_compadd(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
 	return 1;
     }
     dat.ipre = dat.isuf = dat.ppre = dat.psuf = dat.prpre = dat.mesg =
-	dat.pre = dat.suf = dat.group = dat.rems = dat.remf = dat.disp = 
-	dat.ign = dat.exp = dat.apar = dat.opar = dat.dpar = NULL;
+	dat.pre = dat.suf = dat.group = dat.order = dat.rems = dat.remf =
+	dat.disp = dat.ign = dat.exp = dat.apar = dat.opar = dat.dpar = NULL;
     dat.match = NULL;
     dat.flags = 0;
     dat.aflags = CAF_MATCH;
@@ -710,7 +716,8 @@ bin_compadd(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
 		dat.flags |= CMF_DISPLINE;
 		break;
 	    case 'o':
-		dat.flags |= CMF_MORDER;
+		sp = &(dat.order);
+		e = "string expected after -%c";
 		break;
 	    case 'E':
                 if (p[1]) {
@@ -775,6 +782,23 @@ bin_compadd(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
     }
     zsfree(mstr);
 
+    if (dat.order) {
+	int o;
+	const char *next, *opt = dat.order;
+	do {
+	    next = strchr(opt, ',');
+	    if (!next)
+		next = opt + strlen(opt);
+
+	    for (o = sizeof(orderopts)/sizeof(*orderopts) - 1; o >= 0 &&
+		strncmp(orderopts[o].name, opt, next - opt); o--) {}
+	    if (o < 0) {
+		zwarnnam(name, "unknown match ordering: %s\n", dat.order);
+		return 1;
+	    }
+	    dat.aflags |= orderopts[o].oflag;
+	} while (*next && ((opt = next + 1)));
+    }
     if (!*argv && !dat.group && !dat.mesg &&
 	!(dat.aflags & (CAF_NOSORT|CAF_UNIQALL|CAF_UNIQCON|CAF_ALL)))
 	return 1;
diff --git a/Completion/Base/Core/_all_labels b/Completion/Base/Core/_all_labels
index e607d639d..54d163895 100644
--- a/Completion/Base/Core/_all_labels
+++ b/Completion/Base/Core/_all_labels
@@ -8,7 +8,7 @@ if [[ "$1" = - ]]; then
 fi
 
 __gopt=()
-zparseopts -D -a __gopt 1 2 V J x
+zparseopts -D -a __gopt 1 2 V J x o:
 
 __tmp=${argv[(ib:4:)-]}
 __len=$#
diff --git a/Completion/Base/Core/_description b/Completion/Base/Core/_description
index 304c747a6..f51f4a18c 100644
--- a/Completion/Base/Core/_description
+++ b/Completion/Base/Core/_description
@@ -1,13 +1,15 @@
 #autoload
 
 local name gropt nopt xopt format gname hidden hide match opts tag sort
+local -a sortopt
 
 opts=()
 
 gropt=(-J)
 xopt=(-X)
 nopt=()
-zparseopts -K -D -a nopt 1 2 V=gropt J=gropt x=xopt
+zparseopts -K -D -a nopt 1 2 V=gropt J=gropt x=xopt o:=sortopt
+[[ "$gropt" = -V ]] && sortopt=( -o nosort )
 
 3="${${3##[[:blank:]]#}%%[[:blank:]]#}"
 [[ -n "$3" ]] && _lastdescr=( "$_lastdescr[@]" "$3" )
@@ -32,15 +34,15 @@ zstyle -s ":completion:${curcontext}:$1" matcher match &&
 [[ -n "$_matcher" ]] && opts=($opts -M "$_matcher")
 
 # Use sort style, but ignore `menu' value to help _expand.
-# Also don't override explicit use of -V.
-if { zstyle -s ":completion:${curcontext}:$1" sort sort ||
-     zstyle -s ":completion:${curcontext}:" sort sort; } &&
-    [[ "$gropt" = -J && $sort != menu ]]; then
-    if [[ "$sort" = (yes|true|1|on) ]]; then
-	gropt=(-J)
-    else
-	gropt=(-V)
-    fi
+# Also don't override explicit use of -V or -o.
+if (( ! $+sortopt )) &&
+  { zstyle -s ":completion:${curcontext}:$1" sort sort ||
+     zstyle -s ":completion:${curcontext}:" sort sort; }; then
+  if [[ "$sort" = (match|numeric) ]]; then
+    sortopt=( -o $sort )
+  elif [[ "$sort" != (yes|true|1|on|menu) ]]; then
+    sortopt=( -o nosort )
+  fi
 fi
 
 if [[ -z "$_comp_no_ignore" ]]; then
@@ -79,15 +81,15 @@ fi
 
 if [[ -n "$gname" ]]; then
   if [[ -n "$format" ]]; then
-    set -A "$name" "$opts[@]" "$nopt[@]" "$gropt" "$gname" "$xopt" "$format"
+    set -A "$name" "$opts[@]" "$nopt[@]" "$sortopt[@]" -J "$gname" "$xopt" "$format"
   else
-    set -A "$name" "$opts[@]" "$nopt[@]" "$gropt" "$gname"
+    set -A "$name" "$opts[@]" "$nopt[@]" "$sortopt" -J "$gname"
   fi
 else
   if [[ -n "$format" ]]; then
-    set -A "$name" "$opts[@]" "$nopt[@]" "$gropt" -default- "$xopt" "$format"
+    set -A "$name" "$opts[@]" "$nopt[@]" "$sortopt" -J -default- "$xopt" "$format"
   else
-    set -A "$name" "$opts[@]" "$nopt[@]" "$gropt" -default-
+    set -A "$name" "$opts[@]" "$nopt[@]" "$sortopt" -J -default-
   fi
 fi
 
diff --git a/Completion/Base/Core/_message b/Completion/Base/Core/_message
index 4d5645eaf..e4e764f64 100644
--- a/Completion/Base/Core/_message
+++ b/Completion/Base/Core/_message
@@ -25,7 +25,7 @@ if [[ "$1" = -e ]]; then
 fi
 
 gopt=()
-zparseopts -D -a gopt 1 2 V J
+zparseopts -D -a gopt 1 2 V J o:
 
 _tags messages || return 1
 
diff --git a/Completion/Base/Core/_next_label b/Completion/Base/Core/_next_label
index 64506d05a..acc4c04a7 100644
--- a/Completion/Base/Core/_next_label
+++ b/Completion/Base/Core/_next_label
@@ -3,7 +3,7 @@
 local __gopt __descr __spec
 
 __gopt=()
-zparseopts -D -a __gopt 1 2 V J x
+zparseopts -D -a __gopt 1 2 V J x o:
 
 if comptags -A "$1" curtag __spec; then
   (( $#funcstack > _tags_level )) && _comp_tags="${_comp_tags% * }"
diff --git a/Completion/Base/Core/_requested b/Completion/Base/Core/_requested
index 4ba52ce7f..991158801 100644
--- a/Completion/Base/Core/_requested
+++ b/Completion/Base/Core/_requested
@@ -3,7 +3,7 @@
 local __gopt
 
 __gopt=()
-zparseopts -D -a __gopt 1 2 V J x
+zparseopts -D -a __gopt 1 2 V J x o:
 
 if comptags -R "$1"; then
   if [[ $# -gt 3 ]]; then
diff --git a/Completion/Base/Core/_wanted b/Completion/Base/Core/_wanted
index 5bba7fd63..17bc4ad18 100644
--- a/Completion/Base/Core/_wanted
+++ b/Completion/Base/Core/_wanted
@@ -2,7 +2,7 @@
 
 local -a __targs __gopt
 
-zparseopts -D -a __gopt 1 2 V J x C:=__targs
+zparseopts -D -a __gopt 1 2 V J x o: C:=__targs
 
 _tags "$__targs[@]" "$1"
 
diff --git a/Completion/Base/Utility/_describe b/Completion/Base/Utility/_describe
index 76ab1d995..c12eb0eab 100644
--- a/Completion/Base/Utility/_describe
+++ b/Completion/Base/Utility/_describe
@@ -108,10 +108,10 @@ while _tags; do
         fi
     
         if [[ -n $_mats ]]; then
-          compadd "$_opts[@]" "${(@)_expl:/-J/-2V}" -D $_strs -O $_mats - \
+          compadd "$_opts[@]" -2 -o nosort "${_expl[@]}" -D $_strs -O $_mats - \
                   "${(@)${(@M)${(@P)_mats}##([^:\\]|\\?)##}//\\(#b)(?)/$match[1]}"
         else
-          compadd "$_opts[@]" "${(@)_expl:/-J/-2V}" -D $_strs - \
+          compadd "$_opts[@]" -2 -o nosort "${_expl[@]}" -D $_strs - \
                   "${(@)${(@M)${(@P)_strs}##([^:\\]|\\?)##}//\\(#b)(?)/$match[1]}"
         fi
       done
diff --git a/Completion/Base/Utility/_guard b/Completion/Base/Utility/_guard
index ff62981ce..ab9bf6128 100644
--- a/Completion/Base/Utility/_guard
+++ b/Completion/Base/Utility/_guard
@@ -2,7 +2,7 @@
 
 local garbage
 
-zparseopts -K -D -a garbage M: J: V: 1 2 n F: X:
+zparseopts -K -D -a garbage M: J: V: 1 2 o: n F: X:
 
 [[ "$PREFIX$SUFFIX" != $~1 ]] && return 1
 
diff --git a/Completion/Base/Utility/_multi_parts b/Completion/Base/Utility/_multi_parts
index 3e2f36c9c..ce2f1a978 100644
--- a/Completion/Base/Utility/_multi_parts
+++ b/Completion/Base/Utility/_multi_parts
@@ -14,8 +14,8 @@ typeset -U tmp1 matches
 # Get the options.
 
 zparseopts -D -a sopts \
-    'J+:=group' 'V+:=group' 'X+:=expl' 'P:=opts' 'F:=opts' \
-    S: r: R: q 1 2 n f 'M+:=matcher' 'i=imm'
+    'J+:=group' 'V+:=group' 'x+:=expl' 'X+:=expl' 'P:=opts' 'F:=opts' \
+    S: r: R: q 1 2 o+: n f 'M+:=matcher' 'i=imm'
 
 sopts=( "$sopts[@]" "$opts[@]" )
 if (( $#matcher )); then
diff --git a/Completion/Base/Utility/_sep_parts b/Completion/Base/Utility/_sep_parts
index de836a696..6fcf54ec4 100644
--- a/Completion/Base/Utility/_sep_parts
+++ b/Completion/Base/Utility/_sep_parts
@@ -22,8 +22,8 @@ local matchflags opt group expl nm=$compstate[nmatches] opre osuf opts matcher
 
 # Get the options.
 
-zparseopts -D -a opts \
-    'J+:=group' 'V+:=group' P: F: S: r: R: q 1 2 n 'X+:=expl' 'M+:=matcher'
+zparseopts -D -a opts 'J+:=group' 'V+:=group' P: F: S: r: R: q 1 2 o+: n \
+    'x+:=expl' 'X+:=expl' 'M+:=matcher'
 
 # Get the string from the line.
 
diff --git a/Completion/Base/Utility/_sequence b/Completion/Base/Utility/_sequence
index f52955f46..101934490 100644
--- a/Completion/Base/Utility/_sequence
+++ b/Completion/Base/Utility/_sequence
@@ -10,7 +10,8 @@
 local curcontext="$curcontext" nm="$compstate[nmatches]" pre qsep nosep minus
 local -a sep num pref suf end uniq dedup
 
-zparseopts -D -a opts s:=sep n:=num p:=pref i:=pref P:=pref I:=suf S:=suf q=suf r:=suf R:=suf C:=cont d=uniq M: J: X: x:
+zparseopts -D -a opts s:=sep n:=num p:=pref i:=pref P:=pref I:=suf S:=suf \
+    q=suf r:=suf R:=suf C:=cont d=uniq M+: J+: V+: 1 2 o+: X+: x+:
 (( $#cont )) && curcontext="${curcontext%:*}:$cont[2]"
 (( $#sep )) || sep[2]=,
 
diff --git a/Completion/Base/Widget/_next_tags b/Completion/Base/Widget/_next_tags
index 8522d7c9a..83fc55a85 100644
--- a/Completion/Base/Widget/_next_tags
+++ b/Completion/Base/Widget/_next_tags
@@ -18,7 +18,7 @@ _next_tags() {
     fi
 
     __gopt=()
-    zparseopts -D -a __gopt 1 2 V J x
+    zparseopts -D -a __gopt 1 2 V J x o:
 
     __tmp=${argv[(ib:4:)-]}
     __len=$#
@@ -58,7 +58,7 @@ _next_tags() {
     local __gopt __descr __spec
 
     __gopt=()
-    zparseopts -D -a __gopt 1 2 V J x
+    zparseopts -D -a __gopt 1 2 V J x o:
 
     if comptags -A "$1" curtag __spec; then
       (( $#funcstack > _tags_level )) && _comp_tags="${_comp_tags% * }"
diff --git a/Completion/Darwin/Type/_mac_files_for_application b/Completion/Darwin/Type/_mac_files_for_application
index 299d8ff5c..44516b4db 100644
--- a/Completion/Darwin/Type/_mac_files_for_application
+++ b/Completion/Darwin/Type/_mac_files_for_application
@@ -35,7 +35,7 @@ _mac_parse_info_plist() {
 # Try to complete files for the specified application.
 _mac_files_for_application() {
   local -a opts
-  zparseopts -D -a opts q n 1 2 P: S: r: R: W: X+: M+: F: J+: V+:
+  zparseopts -D -a opts q n 1 2 o+: P: S: r: R: W: x+: X+: M+: F: J+: V+:
 
   local app_path
   _retrieve_mac_apps
diff --git a/Completion/Redhat/Command/_yum b/Completion/Redhat/Command/_yum
index 34a337109..8abd23ebb 100644
--- a/Completion/Redhat/Command/_yum
+++ b/Completion/Redhat/Command/_yum
@@ -212,7 +212,7 @@ _yum_ids() {
   # `${(@)@[...]}' selects a subrange from $@
   # `${(@)@[1,-2]}' are all except the last argument
   # `$@[$#]' is the last argument, e.g. the first suggestable ID
-  compadd "${(@)@[1,-2]:/-J/-V}" -M "B:0=" {$@[$#]..$maxid}
+  compadd "${(@)@[1,-2]}" -o numeric -M "B:0=" {$@[$#]..$maxid}
 }
 
 _yum_ranges() {
diff --git a/Completion/Unix/Command/_git b/Completion/Unix/Command/_git
index 093464625..19698f0b1 100644
--- a/Completion/Unix/Command/_git
+++ b/Completion/Unix/Command/_git
@@ -5696,7 +5696,7 @@ __git_ignore_line () {
 __git_ignore_line_inside_arguments () {
   declare -a compadd_opts
 
-  zparseopts -D -E -a compadd_opts V: J: 1 2 n f X: M: P: S: r: R: q F:
+  zparseopts -D -E -a compadd_opts V+: J+: 1 2 o+: n f x+: X+: M+: P: S: r: R: q F:
 
   __git_ignore_line $* $compadd_opts
 }
@@ -6168,7 +6168,7 @@ __git_ref_fields () {
   local match mbegin mend
   local -a cfields fields append opts all
 
-  zparseopts -D -E -a opts x: X: J: V: a=all
+  zparseopts -D -E -a opts M+: x+: X+: J+: V+: o+: 1 2 a=all
 
   if compset -P 1 '(#b)(*):'; then
     case $match[1] in
@@ -6737,7 +6737,7 @@ __git_tags_of_type () {
   tags=(${${(M)${(f)"$(_call_program ${(q)type}-tag-refs "git for-each-ref --format='%(*objecttype)%(objecttype) %(refname)' refs/tags 2>/dev/null")"}:#$type(tag|) *}#$type(tag|) refs/tags/})
   __git_command_successful $pipestatus || return 1
 
-  _wanted $type-tags expl "$type tag" compadd -M 'r:|/=* r:|=*' "$@" -a - tags
+  _wanted $type-tags expl "$type tag" compadd -M 'r:|/=* r:|=*' "$@" -o numeric -a - tags
 }
 
 # Reference Argument Types
@@ -6832,7 +6832,7 @@ __git_files_relative () {
 __git_files () {
   local compadd_opts opts tag description gitcdup gitprefix files expl
 
-  zparseopts -D -E -a compadd_opts V: J: 1 2 n f X: M: P: S: r: R: q F:
+  zparseopts -D -E -a compadd_opts V+: J+: 1 2 o+: n f x+: X+: M+: P: S: r: R: q F:
   zparseopts -D -E -a opts -- -cached -deleted -modified -others -ignored -unmerged -killed x+: --exclude+:
   tag=$1 description=$2; shift 2
 
@@ -6963,7 +6963,7 @@ __git_tree_files () {
     shift
   fi
 
-  zparseopts -D -E -a compadd_opts V: J: 1 2 n f X: M: P: S: r: R: q F:
+  zparseopts -D -E -a compadd_opts V+: J+: 1 2 o+: n f x+: X+: M+: P: S: r: R: q F:
 
   [[ "$1" == */ ]] && Path="$1" || Path="${1:h}/"
   shift
@@ -7043,7 +7043,7 @@ __git_any_repositories_or_references () {
 __git_guard () {
   declare -A opts
 
-  zparseopts -K -D -A opts M: J: V: 1 2 n F: X:
+  zparseopts -K -D -A opts M+: J+: V+: 1 2 o+: n F: x+: X+:
 
   [[ "$PREFIX$SUFFIX" != $~1 ]] && return 1
 
@@ -7081,7 +7081,7 @@ __git_guard_diff-stat-width () {
 __git_guard_number () {
   declare -A opts
 
-  zparseopts -K -D -A opts M: J: V: 1 2 n F: X:
+  zparseopts -K -D -A opts M+: J+: V+: 1 2 o+: n F: x+: X+:
 
   _guard '[[:digit:]]#' ${1:-number}
 }
diff --git a/Completion/Unix/Type/_baudrates b/Completion/Unix/Type/_baudrates
index add359d13..6e9ba4d97 100644
--- a/Completion/Unix/Type/_baudrates
+++ b/Completion/Unix/Type/_baudrates
@@ -72,7 +72,6 @@ if (( ${+opts[-f]} )); then
   done
 fi
 
-# -1V removes dupes (which there shouldn't be) and otherwise leaves the
-# order in the $rates array intact.
-_description -1V baud-rates expl 'baud rate'
-compadd "${(@)argv/#-J/-V}" "$expl[@]" -- "${rates[@]}"
+# -1 removes dupes (which there shouldn't be)
+_description -1 -o numeric baud-rates expl 'baud rate'
+compadd "${argv[@]}" "$expl[@]" -- "${rates[@]}"
diff --git a/Completion/Unix/Type/_canonical_paths b/Completion/Unix/Type/_canonical_paths
index 6eab7b677..cddc3b405 100644
--- a/Completion/Unix/Type/_canonical_paths
+++ b/Completion/Unix/Type/_canonical_paths
@@ -5,13 +5,14 @@
 # (relative path when an absolute path is given, and vice versa; when ..'s are
 # present in the word to be completed, and some paths got from symlinks).
 
-# Usage: _canonical_paths [-A var] [-N] [-MJV12nfX] tag desc [paths...]
+# Usage: _canonical_paths [-A var] [-N] [-MJV12onfX] tag desc [paths...]
 
 # -A, if specified, takes the paths from the array variable specified. Paths
 # can also be specified on the command line as shown above. -N, if specified,
 # prevents canonicalizing the paths given before using them for completion, in
 # case they are already so. `tag' and `desc' arguments are well, obvious :) In
-# addition, the options -M, -J, -V, -1, -2, -n, -F, -X are passed to compadd.
+# addition, the options -M, -J, -V, -1, -2, -o, -n, -F, -x, -X are passed to
+# compadd.
 
 _canonical_paths_add_paths () {
   # origpref = original prefix
@@ -59,7 +60,7 @@ _canonical_paths() {
   local __index
   typeset -a __gopts __opts
 
-  zparseopts -D -a __gopts M: J: V: 1 2 n F: X: A:=__opts N=__opts
+  zparseopts -D -a __gopts M+: J+: V+: o+: 1 2 n F: x+: X+: A:=__opts N=__opts
 
   : ${1:=canonical-paths} ${2:=path}
 
diff --git a/Completion/Unix/Type/_files b/Completion/Unix/Type/_files
index 2b0c5580a..6276ff451 100644
--- a/Completion/Unix/Type/_files
+++ b/Completion/Unix/Type/_files
@@ -23,7 +23,7 @@ local opts tmp glob pat pats expl tag i def descr end ign tried
 local type sdef ignvars ignvar prepath oprefix rfiles rfile
 
 zparseopts -a opts \
-    '/=tmp' 'f=tmp' 'g+:-=tmp' q n 1 2 P: S: r: R: W: X+: M+: F: J+: V+:
+    '/=tmp' 'f=tmp' 'g+:-=tmp' q n 1 2 P: S: r: R: W: x+: X+: M+: F: J+: V+: o+:
 
 type="${(@j::M)${(@)tmp#-}#?}"
 if (( $tmp[(I)-g*] )); then
diff --git a/Completion/Unix/Type/_list_files b/Completion/Unix/Type/_list_files
index 6c52bc1f4..0ea02a55a 100644
--- a/Completion/Unix/Type/_list_files
+++ b/Completion/Unix/Type/_list_files
@@ -64,6 +64,6 @@ for f in ${(PQ)1}; do
  ${(r:8:)stat[gid]} ${(l:8:)stat[size]} $stat[mtime] $f")
 done
 
-(( ${#listfiles} )) && listopts=(-d listfiles -l -o)
+(( ${#listfiles} )) && listopts=(-d listfiles -l -o match)
 
 return 0
diff --git a/Completion/Unix/Type/_path_files b/Completion/Unix/Type/_path_files
index 9fa6ae9fc..d8af018a0 100644
--- a/Completion/Unix/Type/_path_files
+++ b/Completion/Unix/Type/_path_files
@@ -54,7 +54,7 @@ exppaths=()
 zparseopts -a mopts \
     'P:=pfx' 'S:=pfxsfx' 'q=pfxsfx' 'r:=pfxsfx' 'R:=pfxsfx' \
     'W:=prepaths' 'F:=ignore' 'M+:=matcher' \
-    J+: V+: X+: 1 2 n 'f=tmp1' '/=tmp1' 'g+:-=tmp1'
+    J+: V+: x+: X+: 1 2 o+: n 'f=tmp1' '/=tmp1' 'g+:-=tmp1'
 
 sopt="-${(@j::M)${(@)tmp1#-}#?}"
 (( $tmp1[(I)-[/g]*] )) && haspats=yes
@@ -163,7 +163,7 @@ if zstyle -s ":completion:${curcontext}:" file-sort tmp1; then
   if [[ "$sort" = on ]]; then
     sort=
   else
-    mopts=( "${(@)mopts/#-J/-V}" )
+    mopts=( -o nosort "${mopts[@]}" )
 
     tmp2=()
     for tmp1 in "$pats[@]"; do
diff --git a/Completion/Zsh/Type/_file_descriptors b/Completion/Zsh/Type/_file_descriptors
index 3e9f4968b..be96dd0e4 100644
--- a/Completion/Zsh/Type/_file_descriptors
+++ b/Completion/Zsh/Type/_file_descriptors
@@ -56,4 +56,4 @@ fi
 fds=( 0 1 2 $fds )
 
 _description -V file-descriptors expl 'file descriptor'
-compadd $disp "${@/-J/-V}" "$expl[@]" -a fds
+compadd $disp -o nosort "$@" "$expl[@]" -a fds

  parent reply	other threads:[~2018-11-26  1:26 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-11-04  0:13 [PATCH] Completion: Sort lz4 compression levels properly (+ a question) dana
2018-11-07 10:35 ` Oliver Kiddle
2018-11-07 17:52   ` dana
2018-11-26  1:25   ` Oliver Kiddle [this message]
2018-11-26  3:09     ` completion match ordering Daniel Shahaf
2018-11-26  5:18       ` dana
2018-11-26  9:37     ` Peter Stephenson
2018-11-26 23:07     ` dana
2019-05-06 21:16     ` PATCH: " Oliver Kiddle
2019-05-07  0:10       ` dana
2019-05-07 12:39         ` Oliver Kiddle
2019-08-22  8:39       ` Daniel Hahler
2019-08-23 19:05         ` Oliver Kiddle
2019-08-25 14:25           ` Daniel Hahler

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=76839-1543195550.251964@c6AU.RX4q.p78d \
    --to=okiddle@yahoo.co.uk \
    --cc=dana@dana.is \
    --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).