From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 2961 invoked from network); 26 Apr 2000 06:43:54 -0000 Received: from sunsite.auc.dk (130.225.51.30) by ns1.primenet.com.au with SMTP; 26 Apr 2000 06:43:54 -0000 Received: (qmail 15896 invoked by alias); 26 Apr 2000 06:43:46 -0000 Mailing-List: contact zsh-workers-help@sunsite.auc.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 10925 Received: (qmail 15884 invoked from network); 26 Apr 2000 06:43:46 -0000 Date: Wed, 26 Apr 2000 08:43:40 +0200 (MET DST) Message-Id: <200004260643.IAA10016@beta.informatik.hu-berlin.de> From: Sven Wischnowsky To: zsh-workers@sunsite.auc.dk In-reply-to: Felix Rosencrantz's message of Tue, 25 Apr 2000 00:52:12 -0700 (PDT) Subject: PATCH: Re: Compadd churning on matching specs Felix Rosencrantz wrote: > Here is a possible problem with compadd and matching. I was trying to complete > the pathname of the completion function directory in a zsh release tree. > Completion goes quickly until trying to complete the last component of the > path, then there is a big pause. Starting with the path (I add the build date > to the version): > cd /drive2/tools/zsh/share/zsh/3.1.7-pre-1-000421/ work > > This directory has only one sub-directory "functions", so it would > seem that completion should go quickly. I hit TAB, and there is a big > pause. > > ... > > With all the matching specifications that I provided and the ones > _path_files provided, this causes match_str to chew for a while. This > seems wasteful, since we already know that the first part of the path is > fully specified. Would it be possible to just do matching on the last > part of the path, where "function" should be added? As I said, this isn't really possible. And apart from what I said in my first reply: *we* know that, the completion code doesn't (and it doesn't trust us). But here is a very simple-to-implement optimisation for match_str(). I have been tempted to do something almost like this for quite some time but only had the idea that made me try it yesterday. It makes direct character matching (as opposed to using match specs) be preferred in recursive invocations of match_str() (which are used when testing `*'-patterns). There may be problems with complicated patterns or comlicated combinations of patterns, but everything I tried worked nicely, even the substring-match example from the manual, which is quite a good test. So I thought we should just try it. If anyone finds a case where he thinks that something should have matched, but it didn't, tell us. Bye Sven Index: Src/Zle/compmatch.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/Zle/compmatch.c,v retrieving revision 1.7 diff -u -r1.7 compmatch.c --- Src/Zle/compmatch.c 2000/04/26 06:34:10 1.7 +++ Src/Zle/compmatch.c 2000/04/26 06:42:37 @@ -469,7 +469,39 @@ bp = bp->next; } while (ll && lw) { - /* First try the matchers. */ + + /* Hm, we unconditionally first tried the matchers for the cases + * where the beginnings of the line and word patterns match the + * same character(s). + * But first testing if the characters are the same is sooo + * much faster... + * Maybe it's OK to make same-character matching be preferred in + * recursive calls. At least, it /seems/ to work. + * + * Let's try. + */ + + bslash = 0; + if (test && (l[ind] == w[ind] || + (bslash = (lw > 1 && w[ind] == '\\' && + (ind ? (w[0] == l[0]) : (w[1] == l[0])))))) { + /* No matcher could be used, but the strings have the same + * character here, skip over it. */ + l += add; w += (bslash ? (add + add ) : add); + il++; iw += 1 + bslash; + ll--; lw -= 1 + bslash; + bc++; + if (!test) + while (bp && bc >= (useqbr ? bp->qpos : bp->pos)) { + bp->curpos = matchbufadded + (sfx ? (ow - w) : (w - ow)) + obc; + bp = bp->next; + } + lm = NULL; + he = 0; + + continue; + } + /* First try the matchers. Err... see above. */ for (mp = NULL, ms = mstack; !mp && ms; ms = ms->next) { for (mp = ms->matcher; mp; mp = mp->next) { t = 1; @@ -737,10 +769,12 @@ if (mp) continue; + /* Same code as at the beginning, used in top-level calls. */ + bslash = 0; - if (l[ind] == w[ind] || - (bslash = (lw > 1 && w[ind] == '\\' && - (ind ? (w[0] == l[0]) : (w[1] == l[0]))))) { + if (!test && (l[ind] == w[ind] || + (bslash = (lw > 1 && w[ind] == '\\' && + (ind ? (w[0] == l[0]) : (w[1] == l[0])))))) { /* No matcher could be used, but the strings have the same * character here, skip over it. */ l += add; w += (bslash ? (add + add ) : add); -- Sven Wischnowsky wischnow@informatik.hu-berlin.de