zsh-workers
 help / color / mirror / code / Atom feed
From: Daniel Shahaf <d.s@daniel.shahaf.name>
To: Daniel Hahler <genml+zsh-workers@thequod.de>
Cc: Zsh Hackers' List <zsh-workers@zsh.org>
Subject: [PATCH] compdescribe fix for unsorted groups (workers/34814) (was: Re: completion: git: --fixup: problem with _describe -2V and duplicate commit subjects)
Date: Thu, 14 May 2015 14:36:27 +0000	[thread overview]
Message-ID: <20150514143627.GE1932@tarsus.local2> (raw)
In-Reply-To: <20150329054753.GA2766@tarsus.local2>

[-- Attachment #1: Type: text/plain, Size: 1854 bytes --]

Daniel Shahaf wrote on Sun, Mar 29, 2015 at 05:47:53 +0000:
> [ compdescribe question inside ]

This is the problem:

% autoload compinit
% compinit
% a=(dalton:bar charlie:bar bob:foo alice:foo)
% compdef '_describe -2 -V -x person a' f
% compdef '_describe -2 -J -x person a' g
% zstyle ':completion:*:descriptions' format '%b> %u%d%u%b'
% zstyle ':completion:*' group-name ''
% f <TAB>
> person
-- foo
-- bar
> person
alice   charlie   bob   dalton
% g <TAB>
> person
alice    bob     -- foo
charlie  dalton  -- bar

The expected output for f is to the same output as for g, but in reverse
order (the 'bar' lines should be first because they came first in the
array).

The executions on f and g diverge in begcmgroup() (callstack at that
point: addmatches(), bin_compadd(), Completion/Base/Utility/_describe).
When completing 'g', the 'alice' and 'bob' candidates get added to an
existing group that already contains an empty match; when completing
'f', that group exists, but isn't matched due to flags differences (the
CGF_NOSORT flag corresponds to -V), so those two matches get added to
a new group, resulting in the above output.

The first attached patch seems to address this.  However, I encountered
an odd problem with it, which I have not been able to narrow down.  When
I apply the first patch, Daniel Hahler's recent series, and the second
attached patch, and then try to complete 'git checkout 1<TAB>',¹ I get
first a screenful of hashes, and then a screenful of descriptions, and
so on alternating.  I'm not sure whether this indicates a bug in the
first patch or an independent problem.

In any case, I'm leaning towards waiting with these changes until after
5.0.8, to give them as much testing time as possible.

Cheers,

Daniel

¹ Those completions are generated by the function __git_commit_objects
in Completion/Unix/Command/_git.

[-- Attachment #2: 0001-Fix-_describe-compdescribe-problem-with-unsorted-gro.patch --]
[-- Type: text/x-patch, Size: 3377 bytes --]

>From 38c05e49a4beaa1dcd0398bbe6674294ab5c4a5c Mon Sep 17 00:00:00 2001
From: Daniel Shahaf <d.s@daniel.shahaf.name>
Date: Thu, 14 May 2015 11:04:19 +0000
Subject: [PATCH 1/3] Fix _describe/compdescribe problem with unsorted groups
 (see 34814)

---
 Src/Zle/compcore.c |  9 +++++----
 Src/Zle/computil.c | 40 +++++++++++++++++++++++++++++++++++++---
 2 files changed, 42 insertions(+), 7 deletions(-)

diff --git a/Src/Zle/compcore.c b/Src/Zle/compcore.c
index 000f9da..d4051bd 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 a81d1dd..27938c1 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);
-- 
1.9.1


[-- Attachment #3: 0002-git-completion-offer-HEAD-n-as-completions-in-git-re.patch --]
[-- Type: text/x-patch, Size: 2152 bytes --]

>From 4fdb3036dae738df6c10e959db3acf5e7575b504 Mon Sep 17 00:00:00 2001
From: Daniel Shahaf <d.s@daniel.shahaf.name>
Date: Thu, 14 May 2015 11:04:51 +0000
Subject: [PATCH 2/3] git completion: offer HEAD~$n as completions in git,
 remove 34814 workaround

---
 Completion/Unix/Command/_git | 21 +++++++++++----------
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/Completion/Unix/Command/_git b/Completion/Unix/Command/_git
index 9304fbb..378dc4c 100644
--- a/Completion/Unix/Command/_git
+++ b/Completion/Unix/Command/_git
@@ -5658,9 +5658,7 @@ __git_commit_objects () {
   # Abort if the argument does not match a commit hash (including empty).
   _guard '[[:xdigit:]](#c,40)' || return 1
 
-  # Note: the after-the-colon part must be unique across the entire array;
-  # see workers/34768
-  : ${(A)commits::=${(f)"$(_call_program commits git --no-pager log -1000 --all --reflog --format='%h:\[%h\]\ %s\ \(%cr\)')"}}
+  : ${(A)commits::=${(f)"$(_call_program commits git --no-pager log -1000 --all --reflog --format='%h:%s\ \(%cr\)')"}}
   __git_command_successful $pipestatus || return 1
 
   _describe -V -t commits 'commit object name' commits
@@ -5679,18 +5677,21 @@ __git_recent_commits () {
   __git_command_successful $pipestatus || return 1
 
   for i j k in "$commits[@]" ; do
-    # Note: the after-the-colon part must be unique across the entire array;
-    # see workers/34768
     if (( distance_from_head == 0 )); then
-      descr+=($i:"[HEAD]    $k")
+      descr+=("HEAD:$k")
+      descr+=("$i:$k")
     elif (( distance_from_head == 1 )); then
-      descr+=($i:"[HEAD^]   $k")
+      descr+=("HEAD^:$k")
+      descr+=("$i:$k")
     elif (( distance_from_head == 2 )); then
-      descr+=($i:"[HEAD^^]  $k")
+      descr+=("HEAD^^:$k")
+      descr+=($i:"$k")
     elif (( distance_from_head < 10 )); then
-      descr+=($i:"[HEAD~$distance_from_head]  $k")
+      descr+=("HEAD~$distance_from_head:$k")
+      descr+=($i:"$k")
     else
-      descr+=($i:"[HEAD~$distance_from_head] $k")
+      descr+=($i:"$k")
+      descr+=("HEAD~$distance_from_head:$k")
     fi
     (( ++distance_from_head ))
 
-- 
1.9.1


  parent reply	other threads:[~2015-05-14 14:36 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-03-23 22:05 completion: git: --fixup: problem with _describe -2V and duplicate commit subjects Daniel Hahler
2015-03-24  0:07 ` Daniel Hahler
2015-03-29  5:47   ` Daniel Shahaf
2015-03-30 18:21     ` Daniel Shahaf
2015-05-13 12:41       ` Daniel Hahler
2015-05-14 14:28         ` Daniel Shahaf
2015-05-13 12:44     ` Daniel Hahler
2015-05-14 14:36     ` Daniel Shahaf [this message]
2015-05-16 22:54       ` [PATCH] compdescribe fix for unsorted groups (workers/34814) (was: Re: completion: git: --fixup: problem with _describe -2V and duplicate commit subjects) Daniel Shahaf
2015-05-17  4:07         ` Bart Schaefer
2015-05-17 23:40           ` Daniel Shahaf
2015-05-18  4:00             ` Bart Schaefer
2015-05-19  1:36               ` Daniel Shahaf
2015-05-19  4:37                 ` Bart Schaefer
2015-05-19 20:41                   ` Daniel Shahaf
2015-05-19 22:03                     ` Bart Schaefer
2015-05-19 20:44       ` Daniel Shahaf
2015-05-19 21:01         ` Daniel Shahaf
2015-05-19 22:23         ` Bart Schaefer
2015-05-20 23:51           ` Daniel Shahaf
2015-05-22  5:02             ` Bart Schaefer
2015-05-23 10:03             ` Daniel Shahaf

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=20150514143627.GE1932@tarsus.local2 \
    --to=d.s@daniel.shahaf.name \
    --cc=genml+zsh-workers@thequod.de \
    --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).