On Wed, 15 Oct 2008 13:34:47 +0900
Morita Sho <[EMAIL PROTECTED]> wrote:
> Thanks for detailed explanation! But I'm still confusing. Even with the old
> syntax, the completion Ą/[TAB] won't work.

You're right.  My explanation wasn't correct; it doesn't matter if you
use the m:{[lower]}={[upper]} syntax or the older one, so I've restored
the advice that the newer one is preferable.

> BTW, to find out why replacing _path_files with the old one solves the problem
> for me, I put a debug output into _path_files as below to watch the value of
> $tmp1 before the $~tmp1 expansion.
>     print "DEBUG: LINENO=$LINENO tmp1=$tmp1" > /dev/stderr
>     tmp1=( $~tmp1 ) 2> /dev/null
> 
> When I type Ą/[TAB], I got this debug output.
> DEBUG: LINENO=400 tmp1=ă�*(-/)
> DEBUG: LINENO=400 tmp1=ă�*(-/)

Thanks, this tells me that the compfiles utility isn't handling Meta
characters properly when performing matching.  Luckily this seems to be
a local problem within that command that I think the patch addresses.

Index: Doc/Zsh/compwid.yo
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/compwid.yo,v
retrieving revision 1.44
diff -u -r1.44 compwid.yo
--- Doc/Zsh/compwid.yo  14 Oct 2008 12:59:04 -0000      1.44
+++ Doc/Zsh/compwid.yo  18 Oct 2008 18:44:08 -0000
@@ -942,16 +942,14 @@
 completion you can use `tt(m:{[:lower:]}={[:upper:]})'.  Although the
 matching system does not yet handle multibyte characters, this is likely
 to be a future extension, at which point this syntax will handle
-arbitrary alphabets; until then it is safer to use the older syntax
-that only handles ASCII characters, `tt(m:{a-z}={A-Z}) as this does
-not have side effects in the case of multibyte characters.
-
-In other cases `tt([:)var(name)tt(:])' forms are allowed.  If the two forms
-on the left and right are the same, the characters must match exactly.  In
-remaining cases, the corresponding tests are applied to both characters,
-but they are not otherwise constrained; any matching character in one set
-goes with any matching character in the other set:  this is equivalent to
-the behaviour of ordinary character classes.
+arbitrary alphabets; hence this form, rather than the use of explicit
+ranges, is the recommended form.  In other cases
+`tt([:)var(name)tt(:])' forms are allowed.  If the two forms on the left
+and right are the same, the characters must match exactly.  In remaining
+cases, the corresponding tests are applied to both characters, but they
+are not otherwise constrained; any matching character in one set goes
+with any matching character in the other set:  this is equivalent to the
+behaviour of ordinary character classes.
 
 The pattern var(tpat) may also be one or two stars, `tt(*)' or
 `tt(**)'. This means that the pattern on the command line can match
Index: Src/Zle/computil.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Zle/computil.c,v
retrieving revision 1.110
diff -u -r1.110 computil.c
--- Src/Zle/computil.c  14 Oct 2008 22:09:11 -0000      1.110
+++ Src/Zle/computil.c  18 Oct 2008 18:44:09 -0000
@@ -4024,7 +4024,7 @@
      * management is difficult.
      */
     for (;;) {
-       for (mp = ms; *add; add++, mp++) {
+       for (mp = ms; *add; ) {
            if (!(m = *mp)) {
                /*
                 * No matcher, so just match the character
@@ -4034,13 +4034,13 @@
                 * metacharacter?
                 */
                if (ret) {
-                   if (imeta(*add)) {
+                   if (*add == Meta) {
                        *p++ = Meta;
-                       *p++ = *add ^ 32;
+                       *p++ = add[1];
                    } else
                        *p++ = *add;
                } else
-                   len += imeta(*add) ? 2 : 1;
+                   len += (*add == Meta) ? 2 : 1;
            } else if (m->flags & CMF_RIGHT) {
                /*
                 * Right-anchored:  match anything followed
@@ -4049,15 +4049,16 @@
                if (ret) {
                    *p++ = '*';
                    /* TODO: quote again? */
-                   if (imeta(*add)) {
+                   if (*add == Meta) {
                        *p++ = Meta;
-                       *p++ = *add ^ 32;
+                       *p++ = add[1];
                    } else
                        *p++ = *add;
                } else
-                   len += imeta(*add) ? 3 : 2;
+                   len += (*add == Meta) ? 3 : 2;
            } else {
                /* The usual set of matcher possibilities. */
+               int chr = (*add == Meta) ? add[1] ^ 32 : *add;
                int ind;
                if (m->line->tp == CPAT_EQUIV &&
                    m->word->tp == CPAT_EQUIV) {
@@ -4072,21 +4073,21 @@
                     */
                    if (ret) {
                        *p++ = '[';
-                       if (imeta(*add)) {
+                       if (*add == Meta) {
                            *p++ = Meta;
-                           *p++ = *add ^ 32;
+                           *p++ = add[1];
                        } else
                            *p++ = *add;
                    } else
-                       len += imeta(*add) ? 3 : 2;
-                   if (PATMATCHRANGE(m->line->u.str, CONVCAST(*add),
+                       len += (*add == Meta) ? 3 : 2;
+                   if (PATMATCHRANGE(m->line->u.str, CONVCAST(chr),
                                      &ind, &mt)) {
                        /*
                         * Find the equivalent match for ind in the
                         * word pattern.
                         */
                        if ((ind = pattern_match_equivalence
-                            (m->word, ind, mt, CONVCAST(*add))) != -1) {
+                            (m->word, ind, mt, CONVCAST(chr))) != -1) {
                            if (ret) {
                                if (imeta(ind)) {
                                    *p++ = Meta;
@@ -4158,7 +4159,7 @@
                         * if *add is ] and ] is also the first
                         * character in the range.
                         */
-                       addadd = !pattern_match1(m->word, CONVCAST(*add), &mt);
+                       addadd = !pattern_match1(m->word, CONVCAST(chr), &mt);
                        if (addadd && *add == ']') {
                            if (ret)
                                *p++ = *add;
@@ -4218,6 +4219,13 @@
                    }
                }
            }
+           if (*add == Meta) {
+               add += 2;
+               mp += 2;
+           } else {
+               add++;
+               mp++;
+           }
        }
        if (ret) {
            *p = '\0';
@@ -4236,19 +4244,19 @@
 
     if (m && m != pcm_err) {
        char *tmp;
-       int al = strlen(add), tl;
-       VARARR(Cmatcher, ms, al);
+       int al = strlen(add), zl = ztrlen(add), tl, cl;
+       VARARR(Cmatcher, ms, zl);
        Cmatcher *mp;
        Cpattern stopp;
        int stopl = 0;
 
-       memset(ms, 0, al * sizeof(Cmatcher));
+       memset(ms, 0, zl * sizeof(Cmatcher));
 
        for (; m && *add; m = m->next) {
            stopp = NULL;
            if (!(m->flags & (CMF_LEFT|CMF_RIGHT))) {
                if (m->llen == 1 && m->wlen == 1) {
-                   for (tmp = add, tl = al, mp = ms; tl; tl--, tmp++, mp++) {
+                   for (tmp = add, tl = al, mp = ms; tl; ) {
                        if (pattern_match(m->line, tmp, NULL, NULL)) {
                            if (*mp) {
                                *tmp = '\0';
@@ -4257,6 +4265,10 @@
                            } else
                                *mp = m;
                        }
+                       cl = (*tmp == Meta) ? 2 : 1;
+                       tl -= cl;
+                       tmp += cl;
+                       mp += cl;
                    }
                } else {
                    stopp = m->line;
@@ -4264,7 +4276,7 @@
                }
            } else if (m->flags & CMF_RIGHT) {
                if (m->wlen < 0 && !m->llen && m->ralen == 1) {
-                   for (tmp = add, tl = al, mp = ms; tl; tl--, tmp++, mp++) {
+                   for (tmp = add, tl = al, mp = ms; tl; ) {
                        if (pattern_match(m->right, tmp, NULL, NULL)) {
                            if (*mp || (tmp == add && *tmp == '.')) {
                                *tmp = '\0';
@@ -4273,6 +4285,10 @@
                            } else
                                *mp = m;
                        }
+                       cl = (*tmp == Meta) ? 2 : 1;
+                       tl -= cl;
+                       tmp += cl;
+                       mp += cl;
                    }
                } else if (m->llen) {
                    stopp = m->line;
@@ -4289,12 +4305,16 @@
                stopl = m->lalen;
            }
            if (stopp)
-               for (tmp = add, tl = al; tl >= stopl; tl--, tmp++)
+               for (tmp = add, tl = al; tl >= stopl; ) {
                    if (pattern_match(stopp, tmp, NULL, NULL)) {
                        *tmp = '\0';
                        al = tmp - add;
                        break;
                    }
+                   cl = (*tmp == Meta) ? 2 : 1;
+                   tl -= cl;
+                   tmp += cl;
+               }
        }
        if (*add)
            return cfp_matcher_range(ms, add);


-- 
Peter Stephenson <[EMAIL PROTECTED]>
Web page now at http://homepage.ntlworld.com/p.w.stephenson/



--
To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]

Reply via email to