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(&regmatch, buf, p_wic); 2801 if (!fuzzy)
2802 p = buflist_match(&regmatch, 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);