summary refs log tree commit diff
path: root/Src
diff options
context:
space:
mode:
authorDaniel Shahaf <d.s@daniel.shahaf.name>2015-05-14 11:04:19 +0000
committerDaniel Shahaf <d.s@daniel.shahaf.name>2015-05-23 10:05:06 +0000
commit9fcc105ff68b4556883ef42d7c2959ada20a65d1 (patch)
tree85d9c69b63306585afafd620157b270997d09462 /Src
parent2f6a8a6c6c3774ac6f9317288adf03e2a065cb42 (diff)
downloadzsh-9fcc105ff68b4556883ef42d7c2959ada20a65d1.tar.gz
zsh-9fcc105ff68b4556883ef42d7c2959ada20a65d1.tar.xz
zsh-9fcc105ff68b4556883ef42d7c2959ada20a65d1.zip
35127#1: Fix _describe/compdescribe problem with unsorted groups
Diffstat (limited to 'Src')
-rw-r--r--Src/Zle/compcore.c9
-rw-r--r--Src/Zle/computil.c40
2 files changed, 42 insertions, 7 deletions
diff --git a/Src/Zle/compcore.c b/Src/Zle/compcore.c
index 000f9da2a..d4051bda0 100644
--- a/Src/Zle/compcore.c
+++ b/Src/Zle/compcore.c
@@ -2996,9 +2996,9 @@ mod_export void
 begcmgroup(char *n, int flags)
 {
     if (n) {
-	Cmgroup p = amatches;
-
-	while (p) {
+	/* If a group named <n> already exists, reuse it. */
+	Cmgroup p;
+	for (p = amatches; p; p = p->next) {
 #ifdef ZSH_HEAP_DEBUG
 	    if (memory_validate(p->heap_id)) {
 		HEAP_ERROR(p->heap_id);
@@ -3016,9 +3016,10 @@ begcmgroup(char *n, int flags)
 
 		return;
 	    }
-	    p = p->next;
 	}
     }
+
+    /* Create a new group. */
     mgroup = (Cmgroup) zhalloc(sizeof(struct cmgroup));
 #ifdef ZSH_HEAP_DEBUG
     mgroup->heap_id = last_heap_id;
diff --git a/Src/Zle/computil.c b/Src/Zle/computil.c
index a81d1ddad..27938c17f 100644
--- a/Src/Zle/computil.c
+++ b/Src/Zle/computil.c
@@ -210,6 +210,25 @@ cd_calc()
     }
 }
 
+/* Return 1 if cd_state specifies unsorted groups, 0 otherwise. */
+static int
+cd_groups_want_sorting(void)
+{
+    Cdset set;
+    char *const *i;
+
+    for (set = cd_state.sets; set; set = set->next)
+        for (i = set->opts; *i; i++) {
+            if (!strncmp(*i, "-V", 2))
+                return 0;
+            else if (!strncmp(*i, "-J", 2))
+                return 1;
+        }
+
+    /* Sorted by default */
+    return 1;
+}
+
 static int
 cd_sort(const void *a, const void *b)
 {
@@ -283,7 +302,8 @@ cd_prep()
 	    unmetafy(s->sortstr, &dummy);
 	}
 
-        qsort(grps, preplines, sizeof(Cdstr), cd_sort);
+        if (cd_groups_want_sorting())
+            qsort(grps, preplines, sizeof(Cdstr), cd_sort);
 
         for (i = preplines, strp = grps; i > 1; i--, strp++) {
             strp2 = strp + 1;
@@ -441,7 +461,17 @@ cd_arrcat(char **a, char **b)
     }
 }
 
-/* Initialisation. Store and calculate the string and matches and so on. */
+/* Initialisation. Store and calculate the string and matches and so on.
+ *
+ * nam: argv[0] of the builtin
+ * hide: ???
+ * mlen: see max-matches-width style
+ * sep: see list-seperator style
+ * opts: options to (eventually) pass to compadd.
+ *       Returned via 2nd return parameter of 'compdescribe -g'.
+ * args: ??? (the positional arguments to 'compdescribe')
+ * disp: 1 if descriptions should be shown, 0 otherwise
+ */
 
 static int
 cd_init(char *nam, char *hide, char *mlen, char *sep,
@@ -699,8 +729,12 @@ cd_get(char **params)
             dpys[0] = ztrdup(run->strs->str);
             mats[1] = dpys[1] = NULL;
             opts = cd_arrdup(run->strs->set->opts);
+
+            /* Set -2V, possibly reusing the group name from an existing -J/-V
+             * flag. */
             for (dp = opts + 1; *dp; dp++)
-                if (dp[0][0] == '-' && dp[0][1] == 'J')
+                if ((dp[0][0] == '-' && dp[0][1] == 'J') ||
+		    (dp[0][0] == '-' && dp[0][1] == 'V'))
                     break;
             if (*dp) {
                 char *s = tricat("-2V", "", dp[0] + 2);