Mercurial > vim
comparison src/buffer.c @ 27875:ae38d2e81fca v8.2.4463
patch 8.2.4463: completion only uses strict matching
Commit: https://github.com/vim/vim/commit/38b85cb4d7216705058708bacbc25ab90cd61595
Author: Yegappan Lakshmanan <yegappan@yahoo.com>
Date: Thu Feb 24 13:28:41 2022 +0000
patch 8.2.4463: completion only uses strict matching
Problem: Completion only uses strict matching.
Solution: Add the "fuzzy" item for 'wildoptions'. (Yegappan Lakshmanan,
closes #9803)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Thu, 24 Feb 2022 14:30:05 +0100 |
parents | fa675efa1e75 |
children | 6efa2f193c94 |
comparison
equal
deleted
inserted
replaced
27874:f4a227222e7a | 27875:ae38d2e81fca |
---|---|
2726 int count = 0; | 2726 int count = 0; |
2727 buf_T *buf; | 2727 buf_T *buf; |
2728 int round; | 2728 int round; |
2729 char_u *p; | 2729 char_u *p; |
2730 int attempt; | 2730 int attempt; |
2731 char_u *patc; | 2731 char_u *patc = NULL; |
2732 #ifdef FEAT_VIMINFO | 2732 #ifdef FEAT_VIMINFO |
2733 bufmatch_T *matches = NULL; | 2733 bufmatch_T *matches = NULL; |
2734 #endif | 2734 #endif |
2735 int fuzzy; | |
2736 fuzmatch_str_T *fuzmatch = NULL; | |
2735 | 2737 |
2736 *num_file = 0; // return values in case of FAIL | 2738 *num_file = 0; // return values in case of FAIL |
2737 *file = NULL; | 2739 *file = NULL; |
2738 | 2740 |
2739 #ifdef FEAT_DIFF | 2741 #ifdef FEAT_DIFF |
2740 if ((options & BUF_DIFF_FILTER) && !curwin->w_p_diff) | 2742 if ((options & BUF_DIFF_FILTER) && !curwin->w_p_diff) |
2741 return FAIL; | 2743 return FAIL; |
2742 #endif | 2744 #endif |
2743 | 2745 |
2744 // Make a copy of "pat" and change "^" to "\(^\|[\/]\)". | 2746 fuzzy = cmdline_fuzzy_complete(pat); |
2745 if (*pat == '^') | 2747 |
2746 { | 2748 // Make a copy of "pat" and change "^" to "\(^\|[\/]\)" (if doing regular |
2747 patc = alloc(STRLEN(pat) + 11); | 2749 // expression matching) |
2748 if (patc == NULL) | 2750 if (!fuzzy) |
2749 return FAIL; | 2751 { |
2750 STRCPY(patc, "\\(^\\|[\\/]\\)"); | 2752 if (*pat == '^') |
2751 STRCPY(patc + 11, pat + 1); | 2753 { |
2752 } | 2754 patc = alloc(STRLEN(pat) + 11); |
2753 else | 2755 if (patc == NULL) |
2754 patc = pat; | 2756 return FAIL; |
2757 STRCPY(patc, "\\(^\\|[\\/]\\)"); | |
2758 STRCPY(patc + 11, pat + 1); | |
2759 } | |
2760 else | |
2761 patc = pat; | |
2762 } | |
2755 | 2763 |
2756 // attempt == 0: try match with '\<', match at start of word | 2764 // attempt == 0: try match with '\<', match at start of word |
2757 // attempt == 1: try match without '\<', match anywhere | 2765 // attempt == 1: try match without '\<', match anywhere |
2758 for (attempt = 0; attempt <= 1; ++attempt) | 2766 for (attempt = 0; attempt <= (fuzzy ? 0 : 1); ++attempt) |
2759 { | 2767 { |
2760 regmatch_T regmatch; | 2768 regmatch_T regmatch; |
2761 | 2769 int score = 0; |
2762 if (attempt > 0 && patc == pat) | 2770 |
2763 break; // there was no anchor, no need to try again | 2771 if (!fuzzy) |
2764 regmatch.regprog = vim_regcomp(patc + attempt * 11, RE_MAGIC); | 2772 { |
2765 if (regmatch.regprog == NULL) | 2773 if (attempt > 0 && patc == pat) |
2766 { | 2774 break; // there was no anchor, no need to try again |
2767 if (patc != pat) | 2775 regmatch.regprog = vim_regcomp(patc + attempt * 11, RE_MAGIC); |
2768 vim_free(patc); | 2776 if (regmatch.regprog == NULL) |
2769 return FAIL; | 2777 { |
2778 if (patc != pat) | |
2779 vim_free(patc); | |
2780 return FAIL; | |
2781 } | |
2770 } | 2782 } |
2771 | 2783 |
2772 // round == 1: Count the matches. | 2784 // round == 1: Count the matches. |
2773 // round == 2: Build the array to keep the matches. | 2785 // round == 2: Build the array to keep the matches. |
2774 for (round = 1; round <= 2; ++round) | 2786 for (round = 1; round <= 2; ++round) |
2784 // :diffget or :diffput completion. | 2796 // :diffget or :diffput completion. |
2785 if (buf == curbuf || !diff_mode_buf(buf)) | 2797 if (buf == curbuf || !diff_mode_buf(buf)) |
2786 continue; | 2798 continue; |
2787 #endif | 2799 #endif |
2788 | 2800 |
2789 p = buflist_match(®match, buf, p_wic); | 2801 if (!fuzzy) |
2802 p = buflist_match(®match, buf, p_wic); | |
2803 else | |
2804 { | |
2805 p = NULL; | |
2806 // first try matching with the short file name | |
2807 if ((score = fuzzy_match_str(buf->b_sfname, pat)) != 0) | |
2808 p = buf->b_sfname; | |
2809 if (p == NULL) | |
2810 { | |
2811 // next try matching with the full path file name | |
2812 if ((score = fuzzy_match_str(buf->b_ffname, pat)) != 0) | |
2813 p = buf->b_ffname; | |
2814 } | |
2815 } | |
2816 | |
2790 if (p != NULL) | 2817 if (p != NULL) |
2791 { | 2818 { |
2792 if (round == 1) | 2819 if (round == 1) |
2793 ++count; | 2820 ++count; |
2794 else | 2821 else |
2795 { | 2822 { |
2796 if (options & WILD_HOME_REPLACE) | 2823 if (options & WILD_HOME_REPLACE) |
2797 p = home_replace_save(buf, p); | 2824 p = home_replace_save(buf, p); |
2798 else | 2825 else |
2799 p = vim_strsave(p); | 2826 p = vim_strsave(p); |
2827 | |
2828 if (!fuzzy) | |
2829 { | |
2800 #ifdef FEAT_VIMINFO | 2830 #ifdef FEAT_VIMINFO |
2801 if (matches != NULL) | 2831 if (matches != NULL) |
2832 { | |
2833 matches[count].buf = buf; | |
2834 matches[count].match = p; | |
2835 count++; | |
2836 } | |
2837 else | |
2838 #endif | |
2839 (*file)[count++] = p; | |
2840 } | |
2841 else | |
2802 { | 2842 { |
2803 matches[count].buf = buf; | 2843 fuzmatch[count].idx = count; |
2804 matches[count].match = p; | 2844 fuzmatch[count].str = p; |
2845 fuzmatch[count].score = score; | |
2805 count++; | 2846 count++; |
2806 } | 2847 } |
2807 else | |
2808 #endif | |
2809 (*file)[count++] = p; | |
2810 } | 2848 } |
2811 } | 2849 } |
2812 } | 2850 } |
2813 if (count == 0) // no match found, break here | 2851 if (count == 0) // no match found, break here |
2814 break; | 2852 break; |
2815 if (round == 1) | 2853 if (round == 1) |
2816 { | 2854 { |
2817 *file = ALLOC_MULT(char_u *, count); | 2855 if (!fuzzy) |
2818 if (*file == NULL) | |
2819 { | 2856 { |
2820 vim_regfree(regmatch.regprog); | 2857 *file = ALLOC_MULT(char_u *, count); |
2821 if (patc != pat) | 2858 if (*file == NULL) |
2822 vim_free(patc); | 2859 { |
2823 return FAIL; | 2860 vim_regfree(regmatch.regprog); |
2861 if (patc != pat) | |
2862 vim_free(patc); | |
2863 return FAIL; | |
2864 } | |
2865 #ifdef FEAT_VIMINFO | |
2866 if (options & WILD_BUFLASTUSED) | |
2867 matches = ALLOC_MULT(bufmatch_T, count); | |
2868 #endif | |
2824 } | 2869 } |
2870 else | |
2871 { | |
2872 fuzmatch = ALLOC_MULT(fuzmatch_str_T, count); | |
2873 if (fuzmatch == NULL) | |
2874 { | |
2875 *num_file = 0; | |
2876 *file = NULL; | |
2877 return FAIL; | |
2878 } | |
2879 } | |
2880 } | |
2881 } | |
2882 | |
2883 if (!fuzzy) | |
2884 { | |
2885 vim_regfree(regmatch.regprog); | |
2886 if (count) // match(es) found, break here | |
2887 break; | |
2888 } | |
2889 } | |
2890 | |
2891 if (!fuzzy && patc != pat) | |
2892 vim_free(patc); | |
2893 | |
2825 #ifdef FEAT_VIMINFO | 2894 #ifdef FEAT_VIMINFO |
2826 if (options & WILD_BUFLASTUSED) | 2895 if (!fuzzy) |
2827 matches = ALLOC_MULT(bufmatch_T, count); | 2896 { |
2828 #endif | 2897 if (matches != NULL) |
2829 } | 2898 { |
2830 } | 2899 int i; |
2831 vim_regfree(regmatch.regprog); | 2900 if (count > 1) |
2832 if (count) // match(es) found, break here | 2901 qsort(matches, count, sizeof(bufmatch_T), buf_compare); |
2833 break; | 2902 // if the current buffer is first in the list, place it at the end |
2834 } | 2903 if (matches[0].buf == curbuf) |
2835 | 2904 { |
2836 if (patc != pat) | 2905 for (i = 1; i < count; i++) |
2837 vim_free(patc); | 2906 (*file)[i-1] = matches[i].match; |
2838 | 2907 (*file)[count-1] = matches[0].match; |
2839 #ifdef FEAT_VIMINFO | 2908 } |
2840 if (matches != NULL) | 2909 else |
2841 { | 2910 { |
2842 int i; | 2911 for (i = 0; i < count; i++) |
2843 if (count > 1) | 2912 (*file)[i] = matches[i].match; |
2844 qsort(matches, count, sizeof(bufmatch_T), buf_compare); | 2913 } |
2845 // if the current buffer is first in the list, place it at the end | 2914 vim_free(matches); |
2846 if (matches[0].buf == curbuf) | 2915 } |
2847 { | 2916 } |
2848 for (i = 1; i < count; i++) | 2917 else |
2849 (*file)[i-1] = matches[i].match; | 2918 { |
2850 (*file)[count-1] = matches[0].match; | 2919 if (fuzzymatches_to_strmatches(fuzmatch, file, count, FALSE) == FAIL) |
2851 } | 2920 return FAIL; |
2852 else | |
2853 { | |
2854 for (i = 0; i < count; i++) | |
2855 (*file)[i] = matches[i].match; | |
2856 } | |
2857 vim_free(matches); | |
2858 } | 2921 } |
2859 #endif | 2922 #endif |
2860 | 2923 |
2861 *num_file = count; | 2924 *num_file = count; |
2862 return (count == 0 ? FAIL : OK); | 2925 return (count == 0 ? FAIL : OK); |