zsh-workers
 help / color / mirror / code / Atom feed
* PATCH: Re: Bug w/matching control + feature request
@ 2001-01-10  9:20 Sven Wischnowsky
  0 siblings, 0 replies; 2+ messages in thread
From: Sven Wischnowsky @ 2001-01-10  9:20 UTC (permalink / raw)
  To: zsh-workers


Felix Rosencrantz wrote:

> I'm seeing a problem with matching control and cursor placement.  I suspect
> the problem might be related to too many match points...
> 
> Here's the case:
> 
> zsh@ zsh -f
> host% echo $ZSH_VERSION
> 3.1.9-dev-8
> host% autoload -U compinit ; compinit -D ; compdef _tst tst
> host% _tst () {
> function> compadd -M 'r:|[.,_-]=** r:[^0-9]||[0-9]=**' glibc-2.1.94-3.i386.rpm
> glibc-devel-2.1.94-3.i386.rpm glibc-profile-2.1.94-3.i386.rpm
> function> }
> host% tst glibc-2.1<TAB>
> results in: 
> host% tst glibc-2[.]1.94-3.i386.rpm
> 
> With the cursor sitting on the dot after the 2, rather than before the 2,
> which seems like the place it would end up.

Here is the patch. With matching control (especially with as, erm...
`flexible' match specs as these) I can't really be sure if I haven't
broken something else, but at least it still passes the tests in
54compmatch (with one change in that file for a case where cursor
positioning is now much better than before).

> Hmm...  Since the matching specs and cursor positioning came up again,
> it got me thinking about a feature request I've wanted.   There are times
> when matching places the cursor at the undesired spot for finishing the
> completion of the word I'm completing.  The matching code has an idea of
> where several other reasonable cursor positions are (see the code
> at  zsh/Src/Zle/compresult.c:415, which picks from several possible
> cursor locations as hot spots, there are probably a few more.) 
> 
> It seems like there would need to be a global array that is accessible to the
> completion functions, that would hold valid hot spots in the current word.
> It would then be possible to write a widget that would cycle the cursor
> between these spots.

I haven't done this yet, although it would be rather simpler. I was
pretty exhausted after fixing the other stuff.

I may have a look and if it's as simple to implement as I think it is...


Bye
 Sven

Index: Src/Zle/compmatch.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Zle/compmatch.c,v
retrieving revision 1.27
diff -u -r1.27 compmatch.c
--- Src/Zle/compmatch.c	2000/10/13 08:44:58	1.27
+++ Src/Zle/compmatch.c	2001/01/10 09:15:41
@@ -416,13 +416,32 @@
 
     /* And add the cline. */
     if (wl || ll) {
-	n = get_cline(l, ll, w, wl, NULL, 0,
-		      flags | ((m && m->wlen == -2) ? CLF_SKIP : 0));
-	if (matchlastsub)
-	    matchlastsub->next = n;
-	else
-	    matchsubs = n;
-	matchlastsub = n;
+	Cline p, lp;
+
+	if ((p = n = bld_parts(w, wl, ll, &lp)) && n != lp) {
+	    for (; p->next != lp; p = p->next);
+
+	    if (matchsubs) {
+		matchlastsub->next = n->prefix;
+		n->prefix = matchsubs;
+	    }
+	    matchsubs = matchlastsub = lp;
+
+	    if (matchlastpart)
+		matchlastpart->next = n;
+	    else
+		matchparts = n;
+	    p->next = 0;
+	    matchlastpart = p;
+	} else {
+	    n = get_cline(l, ll, w, wl, NULL, 0,
+			  flags | ((m && m->wlen == -2) ? CLF_SKIP : 0));
+	    if (matchlastsub)
+		matchlastsub->next = n;
+	    else
+		matchsubs = n;
+	    matchlastsub = n;
+	}
     }
 }
 
@@ -792,7 +811,6 @@
 			    add_match_sub(NULL, NULL, 0, w, ow - w);
 			else
 			    add_match_sub(NULL, NULL, 0, ow, w - ow);
-
 			add_match_sub(mp, tl, mp->llen, tw, mp->wlen);
 		    }
 		    if (sfx) {
@@ -1870,31 +1888,29 @@
 	    if ((o->flags & CLF_NEW) && !(n->flags & CLF_NEW)) {
 		Cline t, tn;
 
-		for (t = o; (tn = t->next) && (tn->flags & CLF_NEW); t = tn);
-		if (tn && cmp_anchors(tn, n, 0)) {
+		for (t = o; (tn = t->next) &&
+			 ((tn->flags & CLF_NEW) || !cmp_anchors(tn, n, 0));
+		     t = tn);
+		if (tn) {
 		    diff = sub_join(n, o, tn, 1);
 
 		    if (po)
 			po->next = tn;
 		    else
 			oo = tn;
+
 		    t->next = NULL;
 		    free_cline(o);
 		    x = o;
 		    o = tn;
-#if 0
-		    /*** These should be handled different from the ones
-			 that compare anchors. */
+
 		    if (po && po->prefix && cmp_anchors(x, po, 0)) {
 			po->flags |= CLF_MISS;
 			po->max += diff;
 		    } else {
-#endif
 			o->flags |= CLF_MISS;
 			o->max += diff;
-#if 0
 		    }
-#endif
 		    continue;
 		}
 	    }
@@ -1907,19 +1923,13 @@
 		if (tn) {
 		    diff = sub_join(o, n, tn, 0);
 
-#if 0
-		    /*** These should be handled different from the ones
-			 that compare anchors. */
 		    if (po && po->prefix && cmp_anchors(n, pn, 0)) {
 			po->flags |= CLF_MISS;
 			po->max += diff;
 		    } else {
-#endif
 			o->flags |= CLF_MISS;
 			o->max += diff;
-#if 0
 		    }
-#endif
 		    n = tn;
 		    continue;
 		}
@@ -1989,13 +1999,13 @@
 		    else
 			oo = to;
 		    o = to;
-		} else
-		    for (t = n; (tn = t->next) && !cmp_anchors(o, tn, 1); t = tn);
-
+		}
 		if (tn) {
 		    diff = sub_join(o, n, tn, 0);
+
 		    o->flags |= CLF_MISS;
 		    o->max += diff;
+
 		    n = tn;
 		    po = o;
 		    o = o->next;
@@ -2099,4 +2109,3 @@
 	return oo;
     }
 }
-
Index: Src/Zle/compresult.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Zle/compresult.c,v
retrieving revision 1.28
diff -u -r1.28 compresult.c
--- Src/Zle/compresult.c	2001/01/08 15:25:04	1.28
+++ Src/Zle/compresult.c	2001/01/10 09:15:43
@@ -163,13 +163,14 @@
 cline_str(Cline l, int ins, int *csp)
 {
     Cline s;
-    int ocs = cs, ncs, pcs, scs, pm, pmax, pmm, sm, smax, smm, d, dm, mid;
+    int ocs = cs, ncs, pcs, scs;
+    int pm, pmax, pmm, pma, sm, smax, smm, sma, d, dm, mid;
     int i, j, li = 0, cbr;
     Brinfo brp, brs;
 
     l = cut_cline(l);
 
-    pmm = smm = dm = pcs = scs = 0;
+    pmm = pma = smm = sma = dm = pcs = scs = 0;
     pm = pmax = sm = smax = d = mid = cbr = -1;
     brp = brs = NULL;
 
@@ -242,9 +243,11 @@
 	/* Remember the position if this is the first prefix with
 	 * missing characters. */
 	if ((l->flags & CLF_MISS) && !(l->flags & CLF_SUF) &&
-	    ((pmax < (l->min - l->max) && (!pmm || (l->flags & CLF_MATCHED))) ||
+	    (((pmax < (l->max - l->min) || (pma && l->max != l->min)) &&
+	      (!pmm || (l->flags & CLF_MATCHED))) ||
 	     ((l->flags & CLF_MATCHED) && !pmm))) {
-	    pm = cs; pmax = l->min - l->max; pmm = l->flags & CLF_MATCHED;
+	    pm = cs; pmax = l->max - l->min; pmm = l->flags & CLF_MATCHED;
+	    pma = ((l->prefix || l->suffix) && l->min == cline_sublen(l));
 	}
 	if (ins) {
 	    int ocs, bl;
@@ -289,10 +292,11 @@
 	    if (l->flags & CLF_MID)
 		mid = cs;
 	    else if ((l->flags & CLF_SUF) && 
-		     ((smax < (l->min - l->max) &&
+		     (((smax < (l->min - l->max) || (sma && l->max != l->min)) &&
 		       (!smm || (l->flags & CLF_MATCHED))) ||
 		      ((l->flags & CLF_MATCHED) && !smm))) {
 		sm = cs; smax = l->min - l->max; smm = l->flags & CLF_MATCHED;
+		sma = ((l->prefix || l->suffix) && l->min == cline_sublen(l));
 	    }
 	}
 	if (ins) {
Index: Test/54compmatch.ztst
===================================================================
RCS file: /cvsroot/zsh/zsh/Test/54compmatch.ztst,v
retrieving revision 1.6
diff -u -r1.6 54compmatch.ztst
--- Test/54compmatch.ztst	2000/10/16 10:55:56	1.6
+++ Test/54compmatch.ztst	2001/01/10 09:15:43
@@ -414,9 +414,9 @@
  test_code 'r:|[A-Z0-9]=** r:|=*' example6_list
  comptest $'tst 2\t\t'
 0:Documentation example using "r:|[A-Z0-9]=* r:|=*", input 2
->line: {tst 523}{}
+>line: {tst 5}{23}
 >COMPADD:{}
->line: {tst 523}{}
+>line: {tst 5}{23}
 >COMPADD:{}
 >NO:{5bar234}
 >NO:{5foo123}

--
Sven Wischnowsky                         wischnow@informatik.hu-berlin.de


^ permalink raw reply	[flat|nested] 2+ messages in thread

* PATCH: Re: Bug w/matching control + feature request
@ 2001-01-12 13:48 Sven Wischnowsky
  0 siblings, 0 replies; 2+ messages in thread
From: Sven Wischnowsky @ 2001-01-12 13:48 UTC (permalink / raw)
  To: zsh-workers


Felix Rosencrantz wrote:

> Thanks for adding the cycle-completion-positions code, Sven! 

Thanks for helping to debug it.

> Though, there
> seems to be a problem with it.
> 
> Check out
> % zsh -f
> host% autoload -U compinit cycle-completion-positions ; compinit -D 
> host% compdef _tst tst
> host% _tst () {compadd -M 'r:|[.,_-]=** r:[^0-9]||[0-9]=**' _cd a_c ab_c
> _b_cde_c}
> host% zle -N cycle cycle-completion-positions
> host% bindkey "^T" cycle
> host% tst _c<TAB><^T>
> 
> After the tab it lists the possible completions.  But the value of
> $_lastcomp[insert_positions] is 4:6:6, which causes the
> cycle-completion-positions to get stuck at cursor position 6.  Not sure
> if there should be unique values or cycle-completion-positions should
> be able to deal with the duplicate values.

In this case it was because the position after the word is always
unconditionally added (that seemed sensible, even if there may be
cases when there is nothing missing at the end).

I've added code to make sure every position is added only once.

> There are other cases, where there is only one value but there should be
> multiple positions.  But I wasn't sure if it would be possible to list all the
> positions. (Use same input but with
> 	_tst () {compadd -M 'r:|[.,_-]=** r:[^0-9]||[0-9]=**' _cd a_c ab_c }
> 
> and the positions are 6:6, and there should be two positions.)

This was actually caused by a flaw deeper down in the engine room. The 
code didn't mark the first cline as having missing characters. With
the patch below this also means that by default the cursor is placed
there (at the beginning) because it looks friendlier to the code in
cline_str().


Bye
 Sven

Index: Src/Zle/compmatch.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Zle/compmatch.c,v
retrieving revision 1.28
diff -u -r1.28 compmatch.c
--- Src/Zle/compmatch.c	2001/01/10 09:24:46	1.28
+++ Src/Zle/compmatch.c	2001/01/12 13:47:34
@@ -1627,6 +1627,8 @@
 	    *orest = NULL;
 	if (nrest)
 	    *nrest = n;
+	if (n)
+	    ot->flags |= CLF_MISS;
 
 	return;
     }
Index: Src/Zle/compresult.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Zle/compresult.c,v
retrieving revision 1.30
diff -u -r1.30 compresult.c
--- Src/Zle/compresult.c	2001/01/11 10:06:50	1.30
+++ Src/Zle/compresult.c	2001/01/12 13:47:35
@@ -165,7 +165,7 @@
 cline_str(Cline l, int ins, int *csp, LinkList posl)
 {
     Cline s;
-    int ocs = cs, ncs, pcs, scs;
+    int ocs = cs, ncs, pcs, scs, opos, npos;
     int pm, pmax, pmm, pma, sm, smax, smm, sma, d, dm, mid;
     int i, j, li = 0, cbr, padd = (ins ? wb - ocs : -ocs);
     Brinfo brp, brs;
@@ -224,8 +224,10 @@
 
 		if ((s->flags & CLF_DIFF) && (!dm || (s->flags & CLF_MATCHED))) {
 		    d = cs; dm = s->flags & CLF_MATCHED;
-		    if (posl)
-			addlinknode(posl, (void *) ((long) (cs + padd)));
+		    if (posl && (npos = cs + padd) != opos) {
+			opos = npos;
+			addlinknode(posl, (void *) ((long) npos));
+		    }
 		}
 		li += s->llen;
 	    }
@@ -247,8 +249,10 @@
 	/* Remember the position if this is the first prefix with
 	 * missing characters. */
 	if ((l->flags & CLF_MISS) && !(l->flags & CLF_SUF)) {
-	    if (posl && l->min != l->max)
-		addlinknode(posl, (void *) ((long) (cs + padd)));
+	    if (posl && l->min != l->max && (npos = cs + padd) != opos) {
+		opos = npos;
+		addlinknode(posl, (void *) ((long) npos));
+	    }
 	    if (((pmax < (l->max - l->min) || (pma && l->max != l->min)) &&
 		 (!pmm || (l->flags & CLF_MATCHED))) ||
 		((l->flags & CLF_MATCHED) && !pmm)) {
@@ -299,8 +303,10 @@
 	    if (l->flags & CLF_MID)
 		mid = cs;
 	    else if (l->flags & CLF_SUF) {
-		if (posl && l->min != l->max)
-		    addlinknode(posl, (void *) ((long) (cs + padd)));
+		if (posl && l->min != l->max && (npos = cs + padd) != opos) {
+		    opos = npos;
+		    addlinknode(posl, (void *) ((long) npos));
+		}
 		if (((smax < (l->min - l->max) || (sma && l->max != l->min)) &&
 		     (!smm || (l->flags & CLF_MATCHED))) ||
 		    ((l->flags & CLF_MATCHED) && !smm)) {
@@ -399,14 +405,16 @@
 	    cs += i;
 	    if (j >= 0 && (!dm || (js->flags & CLF_MATCHED))) {
 		d = cs - j; dm = js->flags & CLF_MATCHED;
-		if (posl)
-		    addlinknode(posl, (void *) ((long) (cs - j + padd)));
+		if (posl && (npos = cs - j + padd) != opos) {
+		    opos = npos;
+		    addlinknode(posl, (void *) ((long) npos));
+		}
 	    }
 	}
 	l = l->next;
     }
-    if (posl)
-	addlinknode(posl, (void *) ((long) (cs + padd)));
+    if (posl && (npos = cs + padd) != opos)
+	addlinknode(posl, (void *) ((long) npos));
     if (ins) {
 	int ocs = cs;
 

--
Sven Wischnowsky                         wischnow@informatik.hu-berlin.de


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2001-01-12 13:48 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-01-10  9:20 PATCH: Re: Bug w/matching control + feature request Sven Wischnowsky
2001-01-12 13:48 Sven Wischnowsky

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).