Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: Problem with completion matching control
- X-seq: zsh-workers 5399
- From: Sven Wischnowsky <wischnow@xxxxxxxxxxxxxxxxxxxxxxx>
- To: zsh-workers@xxxxxxxxxxxxxx
- Subject: Re: Problem with completion matching control
- Date: Tue, 16 Feb 1999 14:58:15 +0100 (MET)
- In-reply-to: Sven Wischnowsky's message of Tue, 16 Feb 1999 09:30:54 +0100 (MET)
- Mailing-list: contact zsh-workers-help@xxxxxxxxxxxxxx; run by ezmlm
I wrote:
> I'm tempted to remove the test that avoids calling the match-
> generation again, at least if the command line was changed. But then
> I'll have to make sure the interaction between listambiguous,
> automenu, autolist, bashautolist, and recexact still gives reasonable
> results, so this may take a while.
The patch below is a bit of an overhaul for the usage of completion
options in do_ambiguous(). A not-so-funny side effect is that the
match-generation code now gets called even if there is already a
list. This is needed to be able to detect when to use recexact
correctly, however.
User visible changes are that strings resulting from a `-M'-spec
behave the same as those from normal matching - this is in fact a bug
fix.
Another effect is that the automatically-use-automenu-if-recexact-is-set-
and-what-we-inserted-is-an-exact-match now magically appears after the
list is shown, i.e. with possible matches `foo' and `foobar' and
listambiguous, automenu, and recexact set it completes `f' to `foo' of
the first TAB, shows the list on the second TAB, and starts
menucompletion with the third TAB. This is the way automenu normally
behaves, so I hope you find it better than the `start menu-completion
and show the list now, ignoring listambiguous'-behavior we had before.
Bye
Sven
diff -u os/Zle/zle_tricky.c Src/Zle/zle_tricky.c
--- os/Zle/zle_tricky.c Mon Feb 15 12:51:57 1999
+++ Src/Zle/zle_tricky.c Tue Feb 16 14:57:58 1999
@@ -287,6 +287,12 @@
static int lastambig;
+/* Non-zero if the string on the line came from a previous completion. *
+ * This is used to detect if the string should be taken as an exact *
+ * match (see do_ambiguous()). */
+
+static int fromcomp;
+
/**/
void
completecall(void)
@@ -2586,10 +2592,10 @@
s = quotename(s, &e, te, &pl);
sl = strlen(s);
}
- if (!ms && ai->firstm) {
+ if (!ms) {
if (sl < ai->minlen)
ai->minlen = sl;
- if ((i = sfxlen(ai->firstm->str, s)) < ai->suflen)
+ if (ai->firstm && (i = sfxlen(ai->firstm->str, s)) < ai->suflen)
ai->suflen = i;
}
t = s;
@@ -2854,10 +2860,11 @@
}
if (!test)
return;
- if (!ms && !ispattern && ai->firstm) {
+ if (!ms) {
if (sl < ai->minlen)
ai->minlen = sl;
- if ((test = sfxlen(ai->firstm->str, s)) < ai->suflen)
+ if (!ispattern && ai->firstm &&
+ (test = sfxlen(ai->firstm->str, s)) < ai->suflen)
ai->suflen = test;
}
@@ -3464,14 +3471,13 @@
static unsigned long ccont;
-/* Create the completion list. This is called whenever some bit of *
- * completion code needs the list. If the list is already available *
- * (validlist!=0), this function doesn't do anything. Along with *
- * the list is maintained the prefixes/suffixes etc. When any of *
- * this becomes invalid -- e.g. if some text is changed on the *
- * command line -- invalidatelist() should be called, to set *
- * validlist to zero and free up the memory used. This function *
- * returns non-zero on error. */
+/* Create the completion list. This is called whenever some bit of *
+ * completion code needs the list. *
+ * Along with the list is maintained the prefixes/suffixes etc. When *
+ * any of this becomes invalid -- e.g. if some text is changed on the *
+ * command line -- invalidatelist() should be called, to set *
+ * validlist to zero and free up the memory used. This function *
+ * returns non-zero on error. */
/**/
static int
@@ -3482,8 +3488,6 @@
/* If we already have a list from a previous execution of this *
* function, skip the list building code. */
- if (validlist)
- return !nmatches;
if ((m = cmatcher)) {
Cmlist mm, *mp = &mm;
@@ -3515,7 +3519,8 @@
freecl = NULL;
- lastambig = 0;
+ if (!validlist)
+ lastambig = 0;
amatches = 0;
mnum = 0;
begcmgroup("default", 0);
@@ -5001,7 +5006,7 @@
listmatches();
if(validlist)
freematches();
- lastambig = menucmp = validlist = showinglist = 0;
+ lastambig = menucmp = validlist = showinglist = fromcomp = 0;
menucur = NULL;
compwidget = NULL;
}
@@ -5437,14 +5442,13 @@
do_ambiguous(void)
{
int p = (usemenu || ispattern), atend = (cs == we);
- int am = 0;
menucmp = 0;
/* If we have to insert the first match, call do_single(). This is *
* how REC_EXACT takes effect. We effectively turn the ambiguous *
* completion into an unambiguous one. */
- if (ainfo && ainfo->exact == 1 && isset(RECEXACT) &&
+ if (ainfo && ainfo->exact == 1 && isset(RECEXACT) && !fromcomp &&
(usemenu == 0 || unset(AUTOMENU))) {
do_single(ainfo->exactm);
invalidatelist();
@@ -5464,7 +5468,7 @@
* normal menu completion options. */
do_ambig_menu();
} else {
- int ics = cs, ocs, pl = 0, l, lp, ls;
+ int ics = cs, ocs, pl = 0, l, lp, ls, la = 0;
char *ps;
Cline lc;
@@ -5473,9 +5477,8 @@
fixsuffix();
- /* Delete the old stuff from the command line. */
+ /* Prepare to delete the old stuff from the command line. */
cs = wb;
- foredel(we - wb);
/* Sort-of general case: we have an ambiguous completion, and aren't *
* starting menu completion or doing anything really weird. We need *
@@ -5499,7 +5502,13 @@
ls = ainfo->csl;
}
if (lc) {
- int sl = 0;
+ VARARR(char, oline, ll);
+ int sl = 0, oll = ll;
+
+ memcpy(oline, line, ll);
+
+ /* First remove the old string from the line. */
+ foredel(we - wb);
if (lp) {
if (ls) {
@@ -5514,7 +5523,21 @@
merge_cline(lc, ps, lp, NULL, 0, 0);
}
inst_cline(lc, pl, sl);
+
+ /* la is non-zero if listambiguous may be used. Copying and
+ * comparing the line looks like BFI but it is the easiest
+ * solution. Really. */
+ la = (ll != oll || strncmp(oline, (char *) line, ll));
+
+ /* If REC_EXACT and AUTO_MENU are set and what we inserted is an *
+ * exact match, we want menu completion the next time round *
+ * so we set fromcomp,to ensure that the word on the line is not *
+ * taken as an exact match. */
+ fromcomp = isset(AUTOMENU);
} else {
+ /* First remove the old string from the line. */
+ foredel(we - wb);
+
inststrlen(ps, 1, -1);
ocs = cs;
if (brbeg && *brbeg) {
@@ -5535,24 +5558,21 @@
inststrlen(brend, 1, -1);
}
cs = ocs;
- }
- /* If REC_EXACT and AUTO_MENU are set and what we inserted is an *
- * exact match, we want to start menu completion now. Otherwise *
- * on the next call to completion the inserted string would be *
- * taken as a match and no menu completion would be started. */
-
- if (isset(RECEXACT) && !lc && ps && ainfo->minlen == strlen(ps))
- am = 1;
+ la = (ics != cs || (ainfo->suflen && !atend ));
+ fromcomp = isset(AUTOMENU);
+ }
/*
* If the LIST_AMBIGUOUS option (meaning roughly `show a list only *
* if the completion is completely ambiguous') is set, and some *
* prefix was inserted, return now, bypassing the list-displaying *
* code. On the way, invalidate the list and note that we don't *
* want to enter an AUTO_MENU imediately. */
- if(isset(LISTAMBIGUOUS) && !am &&
- (ics != cs || (ainfo->suflen && !atend))) {
+ if(isset(LISTAMBIGUOUS) && la) {
+ int fc = fromcomp;
+
invalidatelist();
+ fromcomp = fc;
lastambig = 0;
return;
}
--
Sven Wischnowsky wischnow@xxxxxxxxxxxxxxxxxxxxxxx
Messages sorted by:
Reverse Date,
Date,
Thread,
Author