diff options
| author | Stefan Monnier | 2008-04-30 07:16:08 +0000 |
|---|---|---|
| committer | Stefan Monnier | 2008-04-30 07:16:08 +0000 |
| commit | 2a54a229c04c243442622a4daae34da5cc273289 (patch) | |
| tree | 49826cb426cbd1fa9052d096ddcf145c617374d6 | |
| parent | 15947a4464cc7c5fc93bfe1cec2d94cd6624b6ee (diff) | |
| download | emacs-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/ChangeLog | 7 | ||||
| -rw-r--r-- | src/dired.c | 85 |
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 @@ | |||
| 1 | 2008-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 | |||
| 1 | 2008-04-27 Kenichi Handa <handa@m17n.org> | 8 | 2008-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 | ||