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

all completions



I tried again yesterday evening and now it seems to work...

The patch below (not committed) adds the C-code to add a match
representing all other matches. It is really only that, i.e. one can
add this special match even as the first one and it will still cause
all matches be inserted when selecting it in a menu completion. It's
just that this was easiest to implement.

There are two small problems. First, the option name to add that
special match is currently -C which doesn't mean anything. If we
decide to put something like this into the baseline, we should try to
find a better option character. Second, currently it only displays the 
string `<all>' in the list (one can give it a display string with -d,
though). Of course it would be better to show the real string,
concatenated from the other matches. But that can get pretty long, so
I would want it to be truncated to, say, screen-width (like _expand
does it). And: that string can only be computed pretty late. But of
course, it's possible to implement it and when the patch makes it in
and people want to have this, I'll try to implement it.

The patch also contains a completer, _all_matches, which uses
this. It's a bit of a hybrid, having two `modes'. If the old-matches
style is set to `true' and there is an old list, all the matches from
it will be inserted. Otherwise, if the style is not set to `only', it
will add the special all-matches-match to the list currently being
generated. Since I wanted that to be the last match, I made it use
comppostfuncs to register a function which checks if any matches were
generated at all and if there are at least two matches, adds the
special match. Of course, there are several things we could do to
_all_matches, for example allowing users to specify if the special
match should be shown as the first one or not at all or if only all
matches should be inserted in the line even for the list currently
being generated. All that could be implemented without too much work,
I think.


Two other remarks: Andrej complained about the suffix handling. I've
kept it because, as I said, I think it isn't to irritating and,
probably more important, because it looks like the right thing when
completing inside braces.

The second thing Andrej mentioned: leaving menu selection. After I
tried it at the weekend, I agree that having a insert-all-matches key
binding work when inside menu selection would be nice. One can already 
almost get there by adding a `bindkey -s -M menuselect' binding that
call undo and the completion bindable command. But of course, that's
ugly (and doesn't always do the right thing and invalidates the
current list of matches). So maybe I'll try to build another not-yet-
to-be-committed patch for his suggestion of making completion widgets
leave menu selection without invalidating the current list so that we
can try it...


The patch also removes the completions style.

Bye
 Sven

diff -u -r ../oz/Completion/Commands/_expand_word ./Completion/Commands/_expand_word
--- ../oz/Completion/Commands/_expand_word	Mon Oct  9 20:39:10 2000
+++ ./Completion/Commands/_expand_word	Mon Oct  9 21:21:37 2000
@@ -6,7 +6,6 @@
 unsetopt markdirs globsubst shwordsplit shglob ksharrays cshnullglob
 
 local curcontext="$curcontext"
-local -ah completers
 
 if [[ -z "$curcontext" ]]; then
   curcontext="expand-word:::"
@@ -14,12 +13,4 @@
   curcontext="expand-word:${curcontext#*:}"
 fi
 
-if zstyle -t ":completion:${curcontext}:" completions; then
-    zstyle -a ":completion:${curcontext}:" completer completers
-    completers[1,(i)_expand]=_expand
-    (( $#completers == 1 )) && completers=(_expand _complete)
-else
-    completers=(_expand)
-fi
-
-_main_complete $completers
+_main_complete _expand
diff -u -r ../oz/Completion/Core/_expand ./Completion/Core/_expand
--- ../oz/Completion/Core/_expand	Mon Oct  9 20:39:10 2000
+++ ./Completion/Core/_expand	Mon Oct  9 21:21:21 2000
@@ -18,14 +18,6 @@
       force="$force$opt"
     done
 
-# First, see if we should insert all *completions*.
-
-if [[ "$force" = *c* ]] ||
-   zstyle -t ":completion:${curcontext}:" completions; then
-  compstate[insert]=all
-  return 1
-fi
-
 if [[ "$funcstack[2]" = _prefix ]]; then
   word="$IPREFIX$PREFIX$SUFFIX"
 else
diff -u -r ../oz/Doc/Zsh/compsys.yo ./Doc/Zsh/compsys.yo
--- ../oz/Doc/Zsh/compsys.yo	Mon Oct  9 20:39:10 2000
+++ ./Doc/Zsh/compsys.yo	Mon Oct  9 22:03:22 2000
@@ -966,14 +966,6 @@
 tt(ignored-patterns) style and the tt($fignore) array and then without 
 ignoring matches.
 )
-kindex(completions, completion style)
-item(tt(completions))(
-This style is used by the tt(_expand) completer function. If it is set 
-to `true', the completer will not generate expansions, but instead the
-completions will be generated as normal and all of them will be
-inserted into the command line.  This style is most useful when set
-only for very specific completion contexts.
-)
 kindex(condition, completion style)
 item(tt(condition))(
 This style is used by the tt(_list) completer function to decide if
@@ -1148,7 +1140,7 @@
 )
 kindex(glob, completion style)
 item(tt(glob))(
-Like tt(completions), this is used by the tt(_expand) completer.  If
+This is used by the tt(_expand) completer.  If
 it is set to `true' (the default), globbing will be attempted on the
 words resulting from substitution (see the tt(substitute) style) or
 the original string from the line.
@@ -1639,6 +1631,15 @@
 to tt(_match), the list of matches generated on the first attempt will be
 used again.
 )
+kindex(old-matches, completion style)
+item(tt(old-matches))(
+This is used by the tt(_all_matches) completer to decide if an old
+list of matches should be used if one exists.  It may be set to one of 
+the `true' values or to the string `tt(only)' to use such a list.  If
+it is set to `tt(only)', tt(_all_matches) will only use an old list
+and won't have any effect on the list of matches currently being
+generated.
+)
 kindex(old-menu, completion style)
 item(tt(old-menu))(
 This is used by the tt(_oldlist) completer.  It controls how menu
@@ -2098,6 +2099,31 @@
 
 cindex(completion system, completers)
 startitem()
+findex(_all_matches)
+item(tt(_all_matches))(
+This completer can be used to add a string consisting of all other
+matches.  To ensure, that this string is always added, this completer
+has to be used as the first completer in the list.
+
+This function also uses the style tt(old-matches).  If it is set to
+`true' or to the string `tt(only)' and there is a list of matches from 
+a previous completion, those matches will be inserted in the command
+line.  If it is set to the the string `tt(only)', it will only insert
+an old list and won't add the string for all matches of the list
+currently being generated.
+
+With the tt(old-matches) style set, this completer should probably not 
+be called unconditionally.  Instead one could use the tt(-e) option of 
+the tt(zstyle) builtin command to add a condition to the tt(completer) 
+or to the tt(old-matches) style.  Alternatively, one could use the
+tt(_generic) function to bind tt(_all_matches) to a separate key
+binding, for example:
+
+example(zle -C all-matches complete-word _generic
+bindkey '^Xa' all-matches
+zstyle ':completion:all-matches:*' old-matches only
+zstyle ':completion:all-matches:*' completer _all_matches)
+)
 findex(_approximate)
 item(tt(_approximate))(
 This completer function uses the tt(_complete) completer to generate
@@ -2301,14 +2327,9 @@
 Which kind of expansion is tried is controlled by the tt(substitute),
 tt(glob) and tt(subst-globs-only) styles.
 
-There is another style, tt(completions), which causes tt(_expand) to
-unconditionally insert all em(completions) generated for the current
-word (even if the word is empty).
-
 When tt(_expand) is called as a function, the different modes may be
-selected with options.  The tt(-c) corresponds to the tt(completions)
-style, tt(-s) to tt(substitute), tt(-g) to tt(glob) and tt(-o) to
-tt(subst-globs-only).
+selected with options.  The tt(-s) to tt(substitute), tt(-g) to
+tt(glob) and tt(-o) to tt(subst-globs-only).
 )
 findex(_history)
 item(tt(_history))(
@@ -2484,12 +2505,6 @@
 Performs expansion on the current word:  equivalent to the standard
 tt(expand-word) command, but using the tt(_expand) completer.  Before
 calling it, the var(function) field is set to `tt(expand-word)'.
-
-The tt(completions) style is also tested in the resulting context.  When
-it is true, the list of functions from the tt(completer) style is shifted
-to remove any that would be called ahead of tt(_expand).  If tt(_expand)
-does not appear in the tt(completer) style, then only the two completers
-tt(_expand) and tt(_complete) are used (in that order).
 )
 findex(_generic)
 item(tt(_generic))(
diff -u -r ../oz/Src/Zle/comp.h ./Src/Zle/comp.h
--- ../oz/Src/Zle/comp.h	Sun Oct  8 21:52:41 2000
+++ ./Src/Zle/comp.h	Mon Oct  9 18:49:09 2000
@@ -124,6 +124,7 @@
 #define CMF_ROWS     (1<<10)	/* prefer LIST_ROWS_FIRST */
 #define CMF_MULT     (1<<11)	/* string appears more than once */
 #define CMF_FMULT    (1<<12)	/* first of multiple equal strings */
+#define CMF_ALL      (1<<13)	/* a match representing all other matches */
 
 /* Stuff for completion matcher control. */
 
@@ -236,6 +237,7 @@
 #define CAF_UNIQALL 16
 #define CAF_ARRAYS  32
 #define CAF_KEYS    64
+#define CAF_ALL    128
 
 /* Data for compadd and addmatches() */
 
diff -u -r ../oz/Src/Zle/compcore.c ./Src/Zle/compcore.c
--- ../oz/Src/Zle/compcore.c	Sun Oct  8 21:52:41 2000
+++ ./Src/Zle/compcore.c	Mon Oct  9 20:20:43 2000
@@ -366,41 +366,8 @@
 	cs = origcs;
 	showinglist = -2;
     } else if (useline == 2 && nmatches > 1) {
-	int first = 1, nm = nmatches;
-	Cmatch *mc;
+	do_allmatches(1);
 
-	menucmp = 1;
-	menuacc = 0;
-
-	for (minfo.group = amatches;
-	     minfo.group && !(minfo.group)->mcount;
-	     minfo.group = (minfo.group)->next);
-
-	mc = (minfo.group)->matches;
-
-	while (1) {
-	    if (!first)
-		accept_last();
-	    first = 0;
-
-	    if (!--nm)
-		menucmp = 0;
-
-	    do_single(*mc);
-	    minfo.cur = mc;
-
-	    if (!*++(minfo.cur)) {
-		do {
-		    if (!(minfo.group = (minfo.group)->next))
-			break;
-		} while (!(minfo.group)->mcount);
-		if (!minfo.group)
-		    break;
-		minfo.cur = minfo.group->matches;
-	    }
-	    mc = minfo.cur;
-	}
-	menucmp = 0;
 	minfo.cur = NULL;
 
 	if (forcelist)
@@ -1602,7 +1569,7 @@
     Brinfo bp, bpl = brbeg, obpl, bsl = brend, obsl;
     Heap oldheap;
 
-    if (!*argv) {
+    if (!*argv && !(dat->aflags & CAF_ALL)) {
 	SWITCHHEAPS(oldheap, compheap) {
 	    /* Select the group in which to store the matches. */
 	    gflags = (((dat->aflags & CAF_NOSORT ) ? CGF_NOSORT  : 0) |
@@ -2040,6 +2007,31 @@
 	    set_list_array(dat->dpar, dparl);
 	if (dat->exp)
 	    addexpl();
+	if (dat->aflags & CAF_ALL) {
+	    Cmatch cm = (Cmatch) zhalloc(sizeof(struct cmatch));
+
+	    memset(cm, 0, sizeof(struct cmatch));
+	    cm->str = dupstring("<all>");
+	    if (disp) {
+		if (!*++disp)
+		    disp = NULL;
+		if (disp)
+		    cm->disp = dupstring(*disp);
+	    }
+	    cm->flags = (dat->flags | CMF_ALL |
+			 (complist ?
+			  ((strstr(complist, "packed") ? CMF_PACKED : 0) |
+			   (strstr(complist, "rows")   ? CMF_ROWS   : 0)) : 0));
+	    mnum++;
+	    ainfo->count++;
+	    if (curexpl)
+		curexpl->count++;
+
+	    addlinknode(matches, cm);
+
+	    newmatches = 1;
+	    mgroup->new = 1;
+	}
     } SWITCHBACKHEAPS(oldheap);
 
     /* We switched back to the current heap, now restore the stack of
@@ -2693,7 +2685,7 @@
     r->pre = ztrdup(m->pre);
     r->suf = ztrdup(m->suf);
     r->flags = m->flags;
-    if (nbeg) {
+    if (m->brpl) {
 	int *p, *q, i;
 
 	r->brpl = (int *) zalloc(nbeg * sizeof(int));
@@ -2702,7 +2694,7 @@
 	    *p = *q;
     } else
 	r->brpl = NULL;
-    if (nend) {
+    if (m->brsl) {
 	int *p, *q, i;
 
 	r->brsl = (int *) zalloc(nend * sizeof(int));
@@ -2886,8 +2878,10 @@
     zsfree(m->remf);
     zsfree(m->disp);
     zsfree(m->autoq);
-    zfree(m->brpl, nbeg * sizeof(int));
-    zfree(m->brsl, nend * sizeof(int));
+    if (m->brpl)
+	zfree(m->brpl, nbeg * sizeof(int));
+    if (m->brsl)
+	zfree(m->brsl, nend * sizeof(int));
 
     zfree(m, sizeof(m));
 }
diff -u -r ../oz/Src/Zle/complete.c ./Src/Zle/complete.c
--- ../oz/Src/Zle/complete.c	Sun Oct  8 21:52:41 2000
+++ ./Src/Zle/complete.c	Mon Oct  9 19:32:29 2000
@@ -452,6 +452,9 @@
 	    case 'Q':
 		dat.aflags |= CAF_QUOTE;
 		break;
+	    case 'C':
+		dat.aflags |= CAF_ALL;
+		break;
 	    case 'f':
 		dat.flags |= CMF_FILE;
 		break;
@@ -604,7 +607,7 @@
  ca_args:
 
     if (!*argv && !dat.group && !dat.mesg &&
-	!(dat.aflags & (CAF_NOSORT|CAF_UNIQALL|CAF_UNIQCON)))
+	!(dat.aflags & (CAF_NOSORT|CAF_UNIQALL|CAF_UNIQCON|CAF_ALL)))
 	return 1;
 
     dat.match = match = cpcmatcher(match);
diff -u -r ../oz/Src/Zle/compresult.c ./Src/Zle/compresult.c
--- ../oz/Src/Zle/compresult.c	Sun Oct  8 21:52:42 2000
+++ ./Src/Zle/compresult.c	Mon Oct  9 20:12:32 2000
@@ -570,36 +570,40 @@
 mod_export int
 hasbrpsfx(Cmatch m, char *pre, char *suf)
 {
-    char *op = lastprebr, *os = lastpostbr;
-    VARARR(char, oline, ll);
-    int oll = ll, ocs = cs, ole = lastend, opcs = brpcs, oscs = brscs, ret;
-
-    memcpy(oline, line, ll);
-
-    lastprebr = lastpostbr = NULL;
-
-    instmatch(m, NULL);
-
-    cs = 0;
-    foredel(ll);
-    spaceinline(oll);
-    memcpy(line, oline, oll);
-    cs = ocs;
-    lastend = ole;
-    brpcs = opcs;
-    brscs = oscs;
-
-    ret = (((!pre && !lastprebr) ||
-	    (pre && lastprebr && !strcmp(pre, lastprebr))) &&
-	   ((!suf && !lastpostbr) ||
-	    (suf && lastpostbr && !strcmp(suf, lastpostbr))));
-
-    zsfree(lastprebr);
-    zsfree(lastpostbr);
-    lastprebr = op;
-    lastpostbr = os;
+    if (m->flags & CMF_ALL)
+	return 1;
+    else {
+	char *op = lastprebr, *os = lastpostbr;
+	VARARR(char, oline, ll);
+	int oll = ll, ocs = cs, ole = lastend, opcs = brpcs, oscs = brscs, ret;
+
+	memcpy(oline, line, ll);
+
+	lastprebr = lastpostbr = NULL;
+
+	instmatch(m, NULL);
+
+	cs = 0;
+	foredel(ll);
+	spaceinline(oll);
+	memcpy(line, oline, oll);
+	cs = ocs;
+	lastend = ole;
+	brpcs = opcs;
+	brscs = oscs;
+
+	ret = (((!pre && !lastprebr) ||
+		(pre && lastprebr && !strcmp(pre, lastprebr))) &&
+	       ((!suf && !lastpostbr) ||
+		(suf && lastpostbr && !strcmp(suf, lastpostbr))));
+
+	zsfree(lastprebr);
+	zsfree(lastpostbr);
+	lastprebr = op;
+	lastpostbr = os;
 
-    return ret;
+	return ret;
+    }
 }
 
 /* Handle the case were we found more than one match. */
@@ -748,6 +752,65 @@
     }
 }
 
+/* Insert all matches in the command line. */
+
+/**/
+void
+do_allmatches(int end)
+{
+    int first = 1, nm = nmatches - 1, omc = menucmp, oma = menuacc, e;
+    Cmatch *mc;
+    struct menuinfo mi;
+    char *p = (brbeg ? ztrdup(lastbrbeg->str) : NULL);
+
+    memcpy(&mi, &minfo, sizeof(struct menuinfo));
+    menucmp = 1;
+    menuacc = 0;
+
+    for (minfo.group = amatches;
+	 minfo.group && !(minfo.group)->mcount;
+	 minfo.group = (minfo.group)->next);
+
+    mc = (minfo.group)->matches;
+
+    while (1) {
+	if (!((*mc)->flags & CMF_ALL)) {
+	    if (!first)
+		accept_last();
+	    first = 0;
+
+	    if (!omc && !--nm)
+		menucmp = 0;
+
+	    do_single(*mc);
+	}
+	minfo.cur = mc;
+
+	if (!*++(minfo.cur)) {
+	    do {
+		if (!(minfo.group = (minfo.group)->next))
+		    break;
+	    } while (!(minfo.group)->mcount);
+	    if (!minfo.group)
+		break;
+	    minfo.cur = minfo.group->matches;
+	}
+	mc = minfo.cur;
+    }
+    menucmp = omc;
+    menuacc = oma;
+
+    e = minfo.end;
+    memcpy(&minfo, &mi, sizeof(struct menuinfo));
+    minfo.end = e;
+    minfo.len = e - minfo.pos;
+
+    if (p) {
+	zsfree(lastbrbeg->str);
+	lastbrbeg->str = p;
+    }
+}
+
 /* Insert a single match in the command line. */
 
 /**/
@@ -785,6 +848,10 @@
     cs = minfo.pos;
     foredel(l);
 
+    if (m->flags & CMF_ALL)
+	do_allmatches(0);
+    else {
+
     /* And then we insert the new string. */
     minfo.len = instmatch(m, &scs);
     minfo.end = cs;
@@ -955,6 +1022,7 @@
 	    minfo.cur = &m;
 	runhookdef(INSERTMATCHHOOK, (void *) &dat);
 	minfo.cur = om;
+    }
     }
 }
 

--
Sven Wischnowsky                         wischnow@xxxxxxxxxxxxxxxxxxxxxxx



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