1
0
Fork 0
mirror of https://github.com/vim/vim synced 2025-04-01 15:36:44 +02:00

patch 9.1.0503: cannot use fuzzy keyword completion

Problem:  cannot use fuzzy keyword completion
          (Maxim Kim)
Solution: add the "fuzzycollect" value for the 'completeopt'
          setting, to gather matches using fuzzy logic (glepnir)

fixes: 
closes: 

Signed-off-by: glepnir <glephunter@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
glepnir 2024-06-19 20:20:48 +02:00 committed by Christian Brabandt
parent 94c5d8a5e2
commit 43eef882ff
No known key found for this signature in database
GPG key ID: F3F92DA383FDDE09
7 changed files with 92 additions and 14 deletions

View file

@ -1,4 +1,4 @@
*options.txt* For Vim version 9.1. Last change: 2024 Jun 17
*options.txt* For Vim version 9.1. Last change: 2024 Jun 19
VIM REFERENCE MANUAL by Bram Moolenaar
@ -2151,6 +2151,11 @@ A jump table for the options with a short description can be found at |Q_op|.
difference how completion candidates are reduced from the
list of alternatives, but not how the candidates are
collected (using different completion types).
fuzzycollect
Enable fuzzy collection for default keyword completion.
This allows the collection of matches using fuzzy matching
criteria, providing more comprehensive and flexible
results. Works in combination with other fuzzy options.
*'completepopup'* *'cpp'*
'completepopup' 'cpp' string (default empty)

View file

@ -1,4 +1,4 @@
*version9.txt* For Vim version 9.1. Last change: 2024 Jun 18
*version9.txt* For Vim version 9.1. Last change: 2024 Jun 19
VIM REFERENCE MANUAL by Bram Moolenaar
@ -41554,7 +41554,7 @@ Enum support for Vim9 script |:enum|
*new-other-9.2*
Other new features ~
------------------
The comment plugin |comment-install| is included.
The new plugins |comment-install| and |nohlsearch-install| are included.
Support for Wayland UI.
@ -41634,7 +41634,8 @@ Improved visual highlighting.
Python3 support in OpenVMS.
Support |fuzzy-matching| during |ins-completion| with "fuzzy" item for 'completeopt'
Support for |fuzzy-matching| during |ins-completion| with the "fuzzy" and
"fuzzycollect" values of the 'completeopt' setting
==============================================================================
COMPILE TIME CHANGES *compile-changes-9.2*
@ -41643,6 +41644,8 @@ Support for building with Ruby 3.3.
Support for building Vim 9 in z/OS (MVS).
Clean-up old MS-Windows code.
==============================================================================
PATCHES *patches-9.2* *bug-fixes-9.2*
*patches-after-9.1*

View file

@ -4100,8 +4100,7 @@ find_comp_when_fuzzy(void)
int is_backward = compl_shows_dir_backward();
compl_T *comp = NULL;
if (compl_match_array == NULL ||
(is_forward && compl_selected_item == compl_match_arraysize - 1)
if ((is_forward && compl_selected_item == compl_match_arraysize - 1)
|| (is_backward && compl_selected_item == 0))
return compl_first_match;
@ -4508,6 +4507,11 @@ ins_compl_use_match(int c)
static int
get_normal_compl_info(char_u *line, int startcol, colnr_T curs_col)
{
int i;
int char_len;
size_t fuzzy_len;
char_u *fuzzy_pattern;
if ((compl_cont_status & CONT_SOL) || ctrl_x_mode_path_defines())
{
if (!compl_status_adding())
@ -4622,6 +4626,38 @@ get_normal_compl_info(char_u *line, int startcol, colnr_T curs_col)
compl_patternlen = STRLEN(compl_pattern);
if ((get_cot_flags() & COT_FUZZYCOLLECT) != 0)
{
// Adjust size to avoid buffer overflow
fuzzy_len = (size_t)compl_length * 5 + 10;
// Allocate enough space
fuzzy_pattern = alloc(fuzzy_len);
if (fuzzy_pattern == NULL)
{
compl_patternlen = 0;
return FAIL;
}
// Use 'very magic' mode for simpler syntax
STRCPY(fuzzy_pattern, "\\v");
i = 2; // Start from 2 to skip "\\v"
while (i < compl_length + 2)
{
// Append "\\k*" before each character
STRNCAT(fuzzy_pattern, "\\k*", fuzzy_len - STRLEN(fuzzy_pattern) - 1);
// Get length of current multi-byte character
char_len = mb_ptr2len(compl_pattern + i);
// Concatenate the character safely
STRNCAT(fuzzy_pattern, compl_pattern + i, char_len);
// Move to the next character
i += char_len;
}
// Append "\\k*" at the end to match any characters after the pattern
STRNCAT(fuzzy_pattern, "\\k*", fuzzy_len - STRLEN(fuzzy_pattern) - 1);
vim_free(compl_pattern);
compl_pattern = fuzzy_pattern;
compl_patternlen = STRLEN(compl_pattern);
}
return OK;
}

View file

@ -520,13 +520,14 @@ EXTERN unsigned cot_flags; // flags from 'completeopt'
#define COT_ANY_MENU 0x003 // combination of menu flags
#define COT_LONGEST 0x004 // FALSE: insert full match,
// TRUE: insert longest prefix
#define COT_PREVIEW 0x008
#define COT_POPUP 0x010
#define COT_POPUPHIDDEN 0x020
#define COT_ANY_PREVIEW 0x038 // combination of preview flags
#define COT_NOINSERT 0x040 // FALSE: select & insert, TRUE: noinsert
#define COT_NOSELECT 0x080 // FALSE: select & insert, TRUE: noselect
#define COT_FUZZY 0x100 // TRUE: fuzzy match enabled
#define COT_PREVIEW 0x008
#define COT_POPUP 0x010
#define COT_POPUPHIDDEN 0x020
#define COT_ANY_PREVIEW 0x038 // combination of preview flags
#define COT_NOINSERT 0x040 // FALSE: select & insert, TRUE: noinsert
#define COT_NOSELECT 0x080 // FALSE: select & insert, TRUE: noselect
#define COT_FUZZY 0x100 // TRUE: fuzzy match enabled
#define COT_FUZZYCOLLECT 0x200 // TRUE: fuzzy collect enabled
#ifdef BACKSLASH_IN_FILENAME
EXTERN char_u *p_csl; // 'completeslash'
#endif

View file

@ -118,7 +118,7 @@ static char *(p_fdm_values[]) = {"manual", "expr", "marker", "indent", "syntax",
NULL};
static char *(p_fcl_values[]) = {"all", NULL};
#endif
static char *(p_cot_values[]) = {"menu", "menuone", "longest", "preview", "popup", "popuphidden", "noinsert", "noselect", "fuzzy", NULL};
static char *(p_cot_values[]) = {"menu", "menuone", "longest", "preview", "popup", "popuphidden", "noinsert", "noselect", "fuzzy", "fuzzycollect", NULL};
#ifdef BACKSLASH_IN_FILENAME
static char *(p_csl_values[]) = {"slash", "backslash", NULL};
#endif

View file

@ -2586,6 +2586,37 @@ func Test_complete_fuzzy_match()
call feedkeys("A\<C-X>\<C-N>\<Esc>0", 'tx!')
call assert_equal('hello help hero h', getline('.'))
set completeopt=fuzzycollect
call setline(1, ['xyz yxz x'])
call feedkeys("A\<C-X>\<C-N>\<Esc>0", 'tx!')
call assert_equal('xyz yxz xyz', getline('.'))
" can fuzzy get yxz when use Ctrl-N twice
call setline(1, ['xyz yxz x'])
call feedkeys("A\<C-X>\<C-N>\<C-N>\<Esc>0", 'tx!')
call assert_equal('xyz yxz yxz', getline('.'))
call setline(1, ['one two o'])
call feedkeys("A\<C-X>\<C-N>\<Esc>0", 'tx!')
call assert_equal('one two one', getline('.'))
call setline(1, ['你好 你'])
call feedkeys("A\<C-X>\<C-N>\<Esc>0", 'tx!')
call assert_equal('你好 你好', getline('.'))
call setline(1, ['你的 我的 的'])
call feedkeys("A\<C-X>\<C-N>\<Esc>0", 'tx!')
call assert_equal('你的 我的 你的', getline('.'))
" can fuzzy get multiple-byte word when use Ctrl-N twice
call setline(1, ['你的 我的 的'])
call feedkeys("A\<C-X>\<C-N>\<C-N>\<Esc>0", 'tx!')
call assert_equal('你的 我的 我的', getline('.'))
"respect noinsert
set completeopt=fuzzycollect,menu,menuone,noinsert
call setline(1, ['one two o'])
call feedkeys("A\<C-X>\<C-N>", 'tx')
call assert_equal('one', g:word)
call assert_equal('one two o', getline('.'))
" clean up
set omnifunc=
bw!

View file

@ -704,6 +704,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
503,
/**/
502,
/**/