]> git.eshelyaron.com Git - emacs.git/commitdiff
(file_name_completion): Fix up the encoding/decoding issue
authorStefan Monnier <monnier@iro.umontreal.ca>
Wed, 30 Apr 2008 07:16:08 +0000 (07:16 +0000)
committerStefan Monnier <monnier@iro.umontreal.ca>
Wed, 30 Apr 2008 07:16:08 +0000 (07:16 +0000)
some more.  Copy some of the code from Ftry_completions.
Remove special case code that dates back to initial revision when the
slash was only added when necessary and that can't trigger nowadays.

src/ChangeLog
src/dired.c

index 0cf948fb616e57cb586a7762c6e4c3a162926510..125ed7a94786b1c930041ff3802f8aebd0d637c5 100644 (file)
@@ -1,3 +1,10 @@
+2008-04-30  Stefan Monnier  <monnier@iro.umontreal.ca>
+
+       * dired.c (file_name_completion): Fix up the encoding/decoding issue
+       some more.  Copy some of the code from Ftry_completions.
+       Remove special case code that dates back to initial revision when the
+       slash was only added when necessary and that can't trigger nowadays.
+
 2008-04-27  Kenichi Handa  <handa@m17n.org>
 
        * font.c (font_prop_validate): Signal `error' instead of `font'.
index dda5fdeabc6c92462a4efff34e0e53fe3251f661..e11c37ca5b7f8c3ad5d0895a14798c1d28e574da 100644 (file)
@@ -465,7 +465,6 @@ file_name_completion (file, dirname, all_flag, ver_flag, predicate)
   DIR *d;
   int bestmatchsize = 0, skip;
   register int compare, matchsize;
-  unsigned char *p1, *p2;
   int matchcount = 0;
   /* If ALL_FLAG is 1, BESTMATCH is the list of all matches, decoded.
      If ALL_FLAG is 0, BESTMATCH is either nil
@@ -508,6 +507,9 @@ file_name_completion (file, dirname, all_flag, ver_flag, predicate)
   /* Do completion on the encoded file name
      because the other names in the directory are (we presume)
      encoded likewise.  We decode the completed string at the end.  */
+  /* Actually, this is not quite true any more: we do most of the completion
+     work with decoded file names, but we still do some filtering based
+     on the encoded file name.  */
   encoded_file = STRING_MULTIBYTE (file) ? ENCODE_FILE (file) : file;
 
   encoded_dir = ENCODE_FILE (dirname);
@@ -539,7 +541,6 @@ file_name_completion (file, dirname, all_flag, ver_flag, predicate)
        {
          DIRENTRY *dp;
          int len;
-         Lisp_Object decoded_name;
 
 #ifdef VMS
          dp = (*readfunc) (d);
@@ -589,6 +590,7 @@ file_name_completion (file, dirname, all_flag, ver_flag, predicate)
                     CONSP (tem); tem = XCDR (tem))
                  {
                    int elt_len;
+                   unsigned char *p1;
 
                    elt = XCAR (tem);
                    if (!STRINGP (elt))
@@ -641,8 +643,10 @@ file_name_completion (file, dirname, all_flag, ver_flag, predicate)
          if (!passcount && CONSP (tem))
            continue;
 
+         /* FIXME: If we move this `decode' earlier we can eliminate
+            the repeated ENCODE_FILE on Vcompletion_ignored_extensions.  */
          name = make_unibyte_string (dp->d_name, len);
-         decoded_name = DECODE_FILE (name);
+         name = DECODE_FILE (name);
 
          if (!passcount)
            {
@@ -653,11 +657,8 @@ file_name_completion (file, dirname, all_flag, ver_flag, predicate)
              /* Ignore this element if it fails to match all the regexps.  */
              for (regexps = Vcompletion_regexp_list; CONSP (regexps);
                   regexps = XCDR (regexps))
-               {
-                 tem = Fstring_match (XCAR (regexps), decoded_name, zero);
-                 if (NILP (tem))
-                   break;
-               }
+               if (fast_string_match (XCAR (regexps), name) < 0)
+                 break;
              if (CONSP (regexps))
                continue;
            }
@@ -666,7 +667,7 @@ file_name_completion (file, dirname, all_flag, ver_flag, predicate)
          if (directoryp)
            {
              /* This completion is a directory; make it end with '/' */
-             name = ENCODE_FILE (Ffile_name_as_directory (decoded_name));
+             name = Ffile_name_as_directory (name);
            }
 
          /* Test the predicate, if any.  */
@@ -675,10 +676,10 @@ file_name_completion (file, dirname, all_flag, ver_flag, predicate)
            {
              Lisp_Object decoded;
              Lisp_Object val;
-             struct gcpro gcpro1, gcpro2;
+             struct gcpro gcpro1;
 
-             GCPRO2 (name, decoded_name);
-             decoded = Fexpand_file_name (decoded_name, dirname);
+             GCPRO1 (name);
+             decoded = Fexpand_file_name (name, dirname);
              val = call1 (predicate, decoded);
              UNGCPRO;
 
@@ -691,7 +692,7 @@ file_name_completion (file, dirname, all_flag, ver_flag, predicate)
          matchcount++;
 
          if (all_flag)
-           bestmatch = Fcons (decoded_name, bestmatch);
+           bestmatch = Fcons (name, bestmatch);
          else if (NILP (bestmatch))
            {
              bestmatch = name;
@@ -699,12 +700,21 @@ file_name_completion (file, dirname, all_flag, ver_flag, predicate)
            }
          else
            {
-             compare = min (bestmatchsize, len);
-             p1 = SDATA (bestmatch);
-             p2 = (unsigned char *) dp->d_name;
-             matchsize = scmp (p1, p2, compare);
-             if (matchsize < 0)
+             Lisp_Object zero = make_number (0);
+             /* FIXME: This is a copy of the code in Ftry_completion.  */
+             compare = min (bestmatchsize, SCHARS (name));
+             tem = Fcompare_strings (bestmatch, zero,
+                                     make_number (compare),
+                                     name, zero,
+                                     make_number (compare),
+                                     completion_ignore_case ? Qt : Qnil);
+             if (EQ (tem, Qt))
                matchsize = compare;
+             else if (XINT (tem) < 0)
+               matchsize = - XINT (tem) - 1;
+             else
+               matchsize = XINT (tem) - 1;
+
              if (completion_ignore_case)
                {
                  /* If this is an exact match except for case,
@@ -713,9 +723,9 @@ file_name_completion (file, dirname, all_flag, ver_flag, predicate)
                     of the actual match.  */
                  /* This tests that the current file is an exact match
                     but BESTMATCH is not (it is too long).  */
-                 if ((matchsize == len
+                 if ((matchsize == SCHARS (name)
                       && matchsize + !!directoryp
-                         < SCHARS (bestmatch))
+                         < SCHARS (bestmatch))
                      ||
                      /* If there is no exact match ignoring case,
                         prefer a match that does not change the case
@@ -725,21 +735,23 @@ file_name_completion (file, dirname, all_flag, ver_flag, predicate)
                         prefer that one.  */
                      /* This == checks that, of current file and BESTMATCH,
                         either both or neither are exact.  */
-                     (((matchsize == len)
+                     (((matchsize == SCHARS (name))
                        ==
                        (matchsize + !!directoryp == SCHARS (bestmatch)))
-                      && !bcmp (p2, SDATA (encoded_file), SCHARS (encoded_file))
-                      && bcmp (p1, SDATA (encoded_file), SCHARS (encoded_file))))
+                      && (tem = Fcompare_strings (name, zero,
+                                                  make_number (SCHARS (file)),
+                                                  file, zero,
+                                                  Qnil,
+                                                  Qnil),
+                          EQ (Qt, tem))
+                      && (tem = Fcompare_strings (bestmatch, zero,
+                                                  make_number (SCHARS (file)),
+                                                  file, zero,
+                                                  Qnil,
+                                                  Qnil),
+                          ! EQ (Qt, tem))))
                    bestmatch = name;
                }
-
-             /* If this dirname all matches, see if implicit following
-                slash does too.  */
-             if (directoryp
-                 && compare == matchsize
-                 && bestmatchsize > matchsize
-                 && IS_ANY_SEP (p1[matchsize]))
-               matchsize++;
              bestmatchsize = matchsize;
            }
        }
@@ -751,18 +763,11 @@ file_name_completion (file, dirname, all_flag, ver_flag, predicate)
   bestmatch = unbind_to (count, bestmatch);
 
   if (all_flag || NILP (bestmatch))
-    {
-      if (STRINGP (bestmatch))
-       bestmatch = DECODE_FILE (bestmatch);
-      return bestmatch;
-    }
-  if (matchcount == 1 && bestmatchsize == SCHARS (encoded_file))
+    return bestmatch;
+  if (matchcount == 1 && bestmatchsize == SCHARS (file))
     return Qt;
   bestmatch = Fsubstring (bestmatch, make_number (0),
                          make_number (bestmatchsize));
-  /* Now that we got the right initial segment of BESTMATCH,
-     decode it from the coding system in use.  */
-  bestmatch = DECODE_FILE (bestmatch);
   return bestmatch;
 }