aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/doc/options.txt25
-rw-r--r--runtime/lua/vim/_meta/options.lua25
-rw-r--r--src/nvim/insexpand.c7
-rw-r--r--src/nvim/options.lua25
-rw-r--r--src/nvim/search.c16
-rw-r--r--test/old/testdir/test_ins_complete.vim6
6 files changed, 69 insertions, 35 deletions
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index a6078849fc..ea9fe7e71a 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -1520,14 +1520,23 @@ A jump table for the options with a short description can be found at |Q_op|.
*'completefuzzycollect'* *'cfc'*
'completefuzzycollect' 'cfc' string (default "")
global
- This option enables fuzzy collection for (only some) specific
- |ins-completion| modes, adjusting how items are gathered for fuzzy
- matching based on input.
- The option can contain the following values (separated by commas),
- each enabling fuzzy collection for a specific completion mode:
- files file names
- keyword keyword completion in 'complete' and current file
- whole_line whole lines
+ A comma-separated list of option enables fuzzy collection for specific
+ |ins-completion| modes, affecting how items are gathered during
+ completion. When set, fuzzy matching is used to find completion
+ candidates instead of the standard prefix-based matching. This option
+ can contain the following values are:
+
+ keyword keywords in the current file |i_CTRL-X_CTRL-N|
+ keywords with the ".", "w", "b", "u", "U" and
+ "k{dict}" flags in 'complete'. |i_CTRL-N| |i_CTRL-P|
+
+ files file names |i_CTRL-X_CTRL-F|
+
+ whole_line whole lines |i_CTRL-X_CTRL-L|
+
+ When used with 'completeopt' "longest" option, fuzzy collection can
+ identify the longest common string among the best fuzzy matches and
+ automatically insert it.
*'completeitemalign'* *'cia'*
'completeitemalign' 'cia' string (default "abbr,kind,menu")
diff --git a/runtime/lua/vim/_meta/options.lua b/runtime/lua/vim/_meta/options.lua
index e473558207..e1e793b533 100644
--- a/runtime/lua/vim/_meta/options.lua
+++ b/runtime/lua/vim/_meta/options.lua
@@ -1044,14 +1044,23 @@ vim.o.cfu = vim.o.completefunc
vim.bo.completefunc = vim.o.completefunc
vim.bo.cfu = vim.bo.completefunc
---- This option enables fuzzy collection for (only some) specific
---- `ins-completion` modes, adjusting how items are gathered for fuzzy
---- matching based on input.
---- The option can contain the following values (separated by commas),
---- each enabling fuzzy collection for a specific completion mode:
---- files file names
---- keyword keyword completion in 'complete' and current file
---- whole_line whole lines
+--- A comma-separated list of option enables fuzzy collection for specific
+--- `ins-completion` modes, affecting how items are gathered during
+--- completion. When set, fuzzy matching is used to find completion
+--- candidates instead of the standard prefix-based matching. This option
+--- can contain the following values are:
+---
+--- keyword keywords in the current file `i_CTRL-X_CTRL-N`
+--- keywords with the ".", "w", "b", "u", "U" and
+--- "k{dict}" flags in 'complete'. `i_CTRL-N` `i_CTRL-P`
+---
+--- files file names `i_CTRL-X_CTRL-F`
+---
+--- whole_line whole lines `i_CTRL-X_CTRL-L`
+---
+--- When used with 'completeopt' "longest" option, fuzzy collection can
+--- identify the longest common string among the best fuzzy matches and
+--- automatically insert it.
---
--- @type string
vim.o.completefuzzycollect = ""
diff --git a/src/nvim/insexpand.c b/src/nvim/insexpand.c
index 0e8b135812..47238468db 100644
--- a/src/nvim/insexpand.c
+++ b/src/nvim/insexpand.c
@@ -3219,7 +3219,7 @@ enum {
/// the "st->e_cpt" option value and process the next matching source.
/// INS_COMPL_CPT_END if all the values in "st->e_cpt" are processed.
static int process_next_cpt_value(ins_compl_next_state_T *st, int *compl_type_arg,
- pos_T *start_match_pos, bool in_fuzzy)
+ pos_T *start_match_pos, bool fuzzy_collect)
{
int compl_type = -1;
int status = INS_COMPL_CPT_OK;
@@ -3235,7 +3235,7 @@ static int process_next_cpt_value(ins_compl_next_state_T *st, int *compl_type_ar
st->first_match_pos = *start_match_pos;
// Move the cursor back one character so that ^N can match the
// word immediately after the cursor.
- if (ctrl_x_mode_normal() && (!in_fuzzy && dec(&st->first_match_pos) < 0)) {
+ if (ctrl_x_mode_normal() && (!fuzzy_collect && dec(&st->first_match_pos) < 0)) {
// Move the cursor to after the last character in the
// buffer, so that word at start of buffer is found
// correctly.
@@ -3924,7 +3924,6 @@ static int ins_compl_get_exp(pos_T *ini)
static bool st_cleared = false;
int found_new_match;
int type = ctrl_x_mode;
- bool in_fuzzy = (get_cot_flags() & kOptCotFlagFuzzy) != 0;
assert(curbuf != NULL);
@@ -3961,7 +3960,7 @@ static int ins_compl_get_exp(pos_T *ini)
// entries from 'complete' that look in loaded buffers.
if ((ctrl_x_mode_normal() || ctrl_x_mode_line_or_eval())
&& (!compl_started || st.found_all)) {
- int status = process_next_cpt_value(&st, &type, ini, in_fuzzy);
+ int status = process_next_cpt_value(&st, &type, ini, cfc_has_mode());
if (status == INS_COMPL_CPT_END) {
break;
}
diff --git a/src/nvim/options.lua b/src/nvim/options.lua
index 71c96b6770..1a66b32ccc 100644
--- a/src/nvim/options.lua
+++ b/src/nvim/options.lua
@@ -1466,14 +1466,23 @@ local options = {
flags = true,
deny_duplicates = true,
desc = [=[
- This option enables fuzzy collection for (only some) specific
- |ins-completion| modes, adjusting how items are gathered for fuzzy
- matching based on input.
- The option can contain the following values (separated by commas),
- each enabling fuzzy collection for a specific completion mode:
- files file names
- keyword keyword completion in 'complete' and current file
- whole_line whole lines
+ A comma-separated list of option enables fuzzy collection for specific
+ |ins-completion| modes, affecting how items are gathered during
+ completion. When set, fuzzy matching is used to find completion
+ candidates instead of the standard prefix-based matching. This option
+ can contain the following values are:
+
+ keyword keywords in the current file |i_CTRL-X_CTRL-N|
+ keywords with the ".", "w", "b", "u", "U" and
+ "k{dict}" flags in 'complete'. |i_CTRL-N| |i_CTRL-P|
+
+ files file names |i_CTRL-X_CTRL-F|
+
+ whole_line whole lines |i_CTRL-X_CTRL-L|
+
+ When used with 'completeopt' "longest" option, fuzzy collection can
+ identify the longest common string among the best fuzzy matches and
+ automatically insert it.
]=],
full_name = 'completefuzzycollect',
list = 'onecomma',
diff --git a/src/nvim/search.c b/src/nvim/search.c
index 2b7739292b..6db5fc159b 100644
--- a/src/nvim/search.c
+++ b/src/nvim/search.c
@@ -3629,7 +3629,7 @@ garray_T *fuzzy_match_str_with_pos(char *const str, const char *const pat)
/// - `*len` is set to the length of the matched word.
/// - `*score` contains the match score.
///
-/// If no match is found, `*ptr` is updated to to the end of the line.
+/// If no match is found, `*ptr` is updated to the end of the line.
bool fuzzy_match_str_in_line(char **ptr, char *pat, int *len, pos_T *current_pos, int *score)
{
char *str = *ptr;
@@ -3699,9 +3699,6 @@ bool search_for_fuzzy_match(buf_T *buf, pos_T *pos, char *pattern, int dir, pos_
bool looped_around = false;
bool whole_line = ctrl_x_mode_whole_line();
- if (whole_line) {
- current_pos.lnum += dir;
- }
if (buf == curbuf) {
circly_end = *start_pos;
@@ -3711,6 +3708,10 @@ bool search_for_fuzzy_match(buf_T *buf, pos_T *pos, char *pattern, int dir, pos_
circly_end.coladd = 0;
}
+ if (whole_line && start_pos->lnum != pos->lnum) {
+ current_pos.lnum += dir;
+ }
+
while (true) {
// Check if looped around and back to start position
if (looped_around && equalpos(current_pos, circly_end)) {
@@ -3721,11 +3722,14 @@ bool search_for_fuzzy_match(buf_T *buf, pos_T *pos, char *pattern, int dir, pos_
if (current_pos.lnum >= 1 && current_pos.lnum <= buf->b_ml.ml_line_count) {
// Get the current line buffer
*ptr = ml_get_buf(buf, current_pos.lnum);
+ if (!whole_line) {
+ *ptr += current_pos.col;
+ }
+
// If ptr is end of line is reached, move to next line
// or previous line based on direction
if (*ptr != NULL && **ptr != NUL) {
if (!whole_line) {
- *ptr += current_pos.col;
// Try to find a fuzzy match in the current line starting
// from current position
found_new_match = fuzzy_match_str_in_line(ptr, pattern,
@@ -3743,8 +3747,6 @@ bool search_for_fuzzy_match(buf_T *buf, pos_T *pos, char *pattern, int dir, pos_
}
next_word_end += l;
}
- } else if (looped_around) {
- found_new_match = false;
}
*len = (int)(next_word_end - *ptr);
current_pos.col = *len;
diff --git a/test/old/testdir/test_ins_complete.vim b/test/old/testdir/test_ins_complete.vim
index 51c1cc3359..31991dd6f0 100644
--- a/test/old/testdir/test_ins_complete.vim
+++ b/test/old/testdir/test_ins_complete.vim
@@ -2982,6 +2982,12 @@ func Test_complete_fuzzy_collect()
call feedkeys("STe\<C-X>\<C-N>x\<CR>\<Esc>0", 'tx!')
call assert_equal('Tex', getline(line('.') - 1))
+ call setline(1, ['fuzzy', 'fuzzycollect', 'completefuzzycollect'])
+ call feedkeys("Gofuzzy\<C-X>\<C-N>\<C-N>\<C-N>\<CR>\<Esc>0", 'tx!')
+ call assert_equal('fuzzycollect', getline(line('.') - 1))
+ call feedkeys("Gofuzzy\<C-X>\<C-N>\<C-N>\<C-N>\<C-N>\<CR>\<Esc>0", 'tx!')
+ call assert_equal('completefuzzycollect', getline(line('.') - 1))
+
bw!
bw!
set completeopt& cfc& cpt&