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: #14912
closes: #14976
Signed-off-by: glepnir <glephunter@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
diff --git a/src/insexpand.c b/src/insexpand.c
index c673df9..78fea51 100644
--- a/src/insexpand.c
+++ b/src/insexpand.c
@@ -4100,8 +4100,7 @@
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 @@
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 @@
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;
}