Mercurial > emacs
changeset 94493:41892e1c80a1
(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 revision 1.1 when the
slash was only added when necessary and that can't trigger nowadays.
author | Stefan Monnier <monnier@iro.umontreal.ca> |
---|---|
date | Wed, 30 Apr 2008 07:16:08 +0000 |
parents | 15e98f48709e |
children | 07fb6a1d5233 |
files | src/ChangeLog src/dired.c |
diffstat | 2 files changed, 52 insertions(+), 40 deletions(-) [+] |
line wrap: on
line diff
--- a/src/ChangeLog Wed Apr 30 05:50:02 2008 +0000 +++ b/src/ChangeLog Wed Apr 30 07:16:08 2008 +0000 @@ -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 revision 1.1 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'.
--- a/src/dired.c Wed Apr 30 05:50:02 2008 +0000 +++ b/src/dired.c Wed Apr 30 07:16:08 2008 +0000 @@ -465,7 +465,6 @@ 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 @@ /* 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 @@ { DIRENTRY *dp; int len; - Lisp_Object decoded_name; #ifdef VMS dp = (*readfunc) (d); @@ -589,6 +590,7 @@ CONSP (tem); tem = XCDR (tem)) { int elt_len; + unsigned char *p1; elt = XCAR (tem); if (!STRINGP (elt)) @@ -641,8 +643,10 @@ 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 @@ /* 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 @@ 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 @@ { 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 @@ matchcount++; if (all_flag) - bestmatch = Fcons (decoded_name, bestmatch); + bestmatch = Fcons (name, bestmatch); else if (NILP (bestmatch)) { bestmatch = name; @@ -699,12 +700,21 @@ } 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 @@ 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 @@ 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 @@ 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; }