aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2008-04-30 07:16:08 +0000
committerStefan Monnier2008-04-30 07:16:08 +0000
commit2a54a229c04c243442622a4daae34da5cc273289 (patch)
tree49826cb426cbd1fa9052d096ddcf145c617374d6
parent15947a4464cc7c5fc93bfe1cec2d94cd6624b6ee (diff)
downloademacs-2a54a229c04c243442622a4daae34da5cc273289.tar.gz
emacs-2a54a229c04c243442622a4daae34da5cc273289.zip
(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.
-rw-r--r--src/ChangeLog7
-rw-r--r--src/dired.c85
2 files changed, 52 insertions, 40 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 0cf948fb616..125ed7a9478 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,10 @@
12008-04-30 Stefan Monnier <monnier@iro.umontreal.ca>
2
3 * dired.c (file_name_completion): Fix up the encoding/decoding issue
4 some more. Copy some of the code from Ftry_completions.
5 Remove special case code that dates back to initial revision when the
6 slash was only added when necessary and that can't trigger nowadays.
7
12008-04-27 Kenichi Handa <handa@m17n.org> 82008-04-27 Kenichi Handa <handa@m17n.org>
2 9
3 * font.c (font_prop_validate): Signal `error' instead of `font'. 10 * font.c (font_prop_validate): Signal `error' instead of `font'.
diff --git a/src/dired.c b/src/dired.c
index dda5fdeabc6..e11c37ca5b7 100644
--- a/src/dired.c
+++ b/src/dired.c
@@ -465,7 +465,6 @@ file_name_completion (file, dirname, all_flag, ver_flag, predicate)
465 DIR *d; 465 DIR *d;
466 int bestmatchsize = 0, skip; 466 int bestmatchsize = 0, skip;
467 register int compare, matchsize; 467 register int compare, matchsize;
468 unsigned char *p1, *p2;
469 int matchcount = 0; 468 int matchcount = 0;
470 /* If ALL_FLAG is 1, BESTMATCH is the list of all matches, decoded. 469 /* If ALL_FLAG is 1, BESTMATCH is the list of all matches, decoded.
471 If ALL_FLAG is 0, BESTMATCH is either nil 470 If ALL_FLAG is 0, BESTMATCH is either nil
@@ -508,6 +507,9 @@ file_name_completion (file, dirname, all_flag, ver_flag, predicate)
508 /* Do completion on the encoded file name 507 /* Do completion on the encoded file name
509 because the other names in the directory are (we presume) 508 because the other names in the directory are (we presume)
510 encoded likewise. We decode the completed string at the end. */ 509 encoded likewise. We decode the completed string at the end. */
510 /* Actually, this is not quite true any more: we do most of the completion
511 work with decoded file names, but we still do some filtering based
512 on the encoded file name. */
511 encoded_file = STRING_MULTIBYTE (file) ? ENCODE_FILE (file) : file; 513 encoded_file = STRING_MULTIBYTE (file) ? ENCODE_FILE (file) : file;
512 514
513 encoded_dir = ENCODE_FILE (dirname); 515 encoded_dir = ENCODE_FILE (dirname);
@@ -539,7 +541,6 @@ file_name_completion (file, dirname, all_flag, ver_flag, predicate)
539 { 541 {
540 DIRENTRY *dp; 542 DIRENTRY *dp;
541 int len; 543 int len;
542 Lisp_Object decoded_name;
543 544
544#ifdef VMS 545#ifdef VMS
545 dp = (*readfunc) (d); 546 dp = (*readfunc) (d);
@@ -589,6 +590,7 @@ file_name_completion (file, dirname, all_flag, ver_flag, predicate)
589 CONSP (tem); tem = XCDR (tem)) 590 CONSP (tem); tem = XCDR (tem))
590 { 591 {
591 int elt_len; 592 int elt_len;
593 unsigned char *p1;
592 594
593 elt = XCAR (tem); 595 elt = XCAR (tem);
594 if (!STRINGP (elt)) 596 if (!STRINGP (elt))
@@ -641,8 +643,10 @@ file_name_completion (file, dirname, all_flag, ver_flag, predicate)
641 if (!passcount && CONSP (tem)) 643 if (!passcount && CONSP (tem))
642 continue; 644 continue;
643 645
646 /* FIXME: If we move this `decode' earlier we can eliminate
647 the repeated ENCODE_FILE on Vcompletion_ignored_extensions. */
644 name = make_unibyte_string (dp->d_name, len); 648 name = make_unibyte_string (dp->d_name, len);
645 decoded_name = DECODE_FILE (name); 649 name = DECODE_FILE (name);
646 650
647 if (!passcount) 651 if (!passcount)
648 { 652 {
@@ -653,11 +657,8 @@ file_name_completion (file, dirname, all_flag, ver_flag, predicate)
653 /* Ignore this element if it fails to match all the regexps. */ 657 /* Ignore this element if it fails to match all the regexps. */
654 for (regexps = Vcompletion_regexp_list; CONSP (regexps); 658 for (regexps = Vcompletion_regexp_list; CONSP (regexps);
655 regexps = XCDR (regexps)) 659 regexps = XCDR (regexps))
656 { 660 if (fast_string_match (XCAR (regexps), name) < 0)
657 tem = Fstring_match (XCAR (regexps), decoded_name, zero); 661 break;
658 if (NILP (tem))
659 break;
660 }
661 if (CONSP (regexps)) 662 if (CONSP (regexps))
662 continue; 663 continue;
663 } 664 }
@@ -666,7 +667,7 @@ file_name_completion (file, dirname, all_flag, ver_flag, predicate)
666 if (directoryp) 667 if (directoryp)
667 { 668 {
668 /* This completion is a directory; make it end with '/' */ 669 /* This completion is a directory; make it end with '/' */
669 name = ENCODE_FILE (Ffile_name_as_directory (decoded_name)); 670 name = Ffile_name_as_directory (name);
670 } 671 }
671 672
672 /* Test the predicate, if any. */ 673 /* Test the predicate, if any. */
@@ -675,10 +676,10 @@ file_name_completion (file, dirname, all_flag, ver_flag, predicate)
675 { 676 {
676 Lisp_Object decoded; 677 Lisp_Object decoded;
677 Lisp_Object val; 678 Lisp_Object val;
678 struct gcpro gcpro1, gcpro2; 679 struct gcpro gcpro1;
679 680
680 GCPRO2 (name, decoded_name); 681 GCPRO1 (name);
681 decoded = Fexpand_file_name (decoded_name, dirname); 682 decoded = Fexpand_file_name (name, dirname);
682 val = call1 (predicate, decoded); 683 val = call1 (predicate, decoded);
683 UNGCPRO; 684 UNGCPRO;
684 685
@@ -691,7 +692,7 @@ file_name_completion (file, dirname, all_flag, ver_flag, predicate)
691 matchcount++; 692 matchcount++;
692 693
693 if (all_flag) 694 if (all_flag)
694 bestmatch = Fcons (decoded_name, bestmatch); 695 bestmatch = Fcons (name, bestmatch);
695 else if (NILP (bestmatch)) 696 else if (NILP (bestmatch))
696 { 697 {
697 bestmatch = name; 698 bestmatch = name;
@@ -699,12 +700,21 @@ file_name_completion (file, dirname, all_flag, ver_flag, predicate)
699 } 700 }
700 else 701 else
701 { 702 {
702 compare = min (bestmatchsize, len); 703 Lisp_Object zero = make_number (0);
703 p1 = SDATA (bestmatch); 704 /* FIXME: This is a copy of the code in Ftry_completion. */
704 p2 = (unsigned char *) dp->d_name; 705 compare = min (bestmatchsize, SCHARS (name));
705 matchsize = scmp (p1, p2, compare); 706 tem = Fcompare_strings (bestmatch, zero,
706 if (matchsize < 0) 707 make_number (compare),
708 name, zero,
709 make_number (compare),
710 completion_ignore_case ? Qt : Qnil);
711 if (EQ (tem, Qt))
707 matchsize = compare; 712 matchsize = compare;
713 else if (XINT (tem) < 0)
714 matchsize = - XINT (tem) - 1;
715 else
716 matchsize = XINT (tem) - 1;
717
708 if (completion_ignore_case) 718 if (completion_ignore_case)
709 { 719 {
710 /* If this is an exact match except for case, 720 /* If this is an exact match except for case,
@@ -713,9 +723,9 @@ file_name_completion (file, dirname, all_flag, ver_flag, predicate)
713 of the actual match. */ 723 of the actual match. */
714 /* This tests that the current file is an exact match 724 /* This tests that the current file is an exact match
715 but BESTMATCH is not (it is too long). */ 725 but BESTMATCH is not (it is too long). */
716 if ((matchsize == len 726 if ((matchsize == SCHARS (name)
717 && matchsize + !!directoryp 727 && matchsize + !!directoryp
718 < SCHARS (bestmatch)) 728 < SCHARS (bestmatch))
719 || 729 ||
720 /* If there is no exact match ignoring case, 730 /* If there is no exact match ignoring case,
721 prefer a match that does not change the case 731 prefer a match that does not change the case
@@ -725,21 +735,23 @@ file_name_completion (file, dirname, all_flag, ver_flag, predicate)
725 prefer that one. */ 735 prefer that one. */
726 /* This == checks that, of current file and BESTMATCH, 736 /* This == checks that, of current file and BESTMATCH,
727 either both or neither are exact. */ 737 either both or neither are exact. */
728 (((matchsize == len) 738 (((matchsize == SCHARS (name))
729 == 739 ==
730 (matchsize + !!directoryp == SCHARS (bestmatch))) 740 (matchsize + !!directoryp == SCHARS (bestmatch)))
731 && !bcmp (p2, SDATA (encoded_file), SCHARS (encoded_file)) 741 && (tem = Fcompare_strings (name, zero,
732 && bcmp (p1, SDATA (encoded_file), SCHARS (encoded_file)))) 742 make_number (SCHARS (file)),
743 file, zero,
744 Qnil,
745 Qnil),
746 EQ (Qt, tem))
747 && (tem = Fcompare_strings (bestmatch, zero,
748 make_number (SCHARS (file)),
749 file, zero,
750 Qnil,
751 Qnil),
752 ! EQ (Qt, tem))))
733 bestmatch = name; 753 bestmatch = name;
734 } 754 }
735
736 /* If this dirname all matches, see if implicit following
737 slash does too. */
738 if (directoryp
739 && compare == matchsize
740 && bestmatchsize > matchsize
741 && IS_ANY_SEP (p1[matchsize]))
742 matchsize++;
743 bestmatchsize = matchsize; 755 bestmatchsize = matchsize;
744 } 756 }
745 } 757 }
@@ -751,18 +763,11 @@ file_name_completion (file, dirname, all_flag, ver_flag, predicate)
751 bestmatch = unbind_to (count, bestmatch); 763 bestmatch = unbind_to (count, bestmatch);
752 764
753 if (all_flag || NILP (bestmatch)) 765 if (all_flag || NILP (bestmatch))
754 { 766 return bestmatch;
755 if (STRINGP (bestmatch)) 767 if (matchcount == 1 && bestmatchsize == SCHARS (file))
756 bestmatch = DECODE_FILE (bestmatch);
757 return bestmatch;
758 }
759 if (matchcount == 1 && bestmatchsize == SCHARS (encoded_file))
760 return Qt; 768 return Qt;
761 bestmatch = Fsubstring (bestmatch, make_number (0), 769 bestmatch = Fsubstring (bestmatch, make_number (0),
762 make_number (bestmatchsize)); 770 make_number (bestmatchsize));
763 /* Now that we got the right initial segment of BESTMATCH,
764 decode it from the coding system in use. */
765 bestmatch = DECODE_FILE (bestmatch);
766 return bestmatch; 771 return bestmatch;
767} 772}
768 773