diff --git a/src/nvim/fuzzy.c b/src/nvim/fuzzy.c index 9a9e95dda6..4d7f6a08e0 100644 --- a/src/nvim/fuzzy.c +++ b/src/nvim/fuzzy.c @@ -614,7 +614,8 @@ bool search_for_fuzzy_match(buf_T *buf, pos_T *pos, char *pattern, int dir, pos_ while (true) { // Check if looped around and back to start position - if (looped_around && equalpos(current_pos, circly_end)) { + if (looped_around && (whole_line ? current_pos.lnum == circly_end.lnum + : equalpos(current_pos, circly_end))) { break; } diff --git a/src/nvim/insexpand.c b/src/nvim/insexpand.c index f4e8f21b74..d7375fd9ee 100644 --- a/src/nvim/insexpand.c +++ b/src/nvim/insexpand.c @@ -1418,16 +1418,33 @@ static String *get_leader_for_startcol(compl_T *match, bool cached) return NULL; } - if (cpt_sources_array == NULL || compl_leader.data == NULL) { + if (cpt_sources_array == NULL) { goto theend; } int cpt_idx = match->cp_cpt_source_idx; - if (cpt_idx < 0 || compl_col <= 0) { + if (cpt_idx < 0) { goto theend; } int startcol = cpt_sources_array[cpt_idx].cs_startcol; + if (compl_leader.data == NULL) { + // When leader is not set (e.g. 'autocomplete' first fires before + // compl_leader is initialised), fall back to compl_orig_text for + // matches starting at or after compl_col. Matches starting before + // compl_col carry pre-compl_col text and must not be compared with + // compl_orig_text, so return &compl_leader (NULL string) to signal + // "pass through" (no prefix filter). + if (startcol < 0 || startcol >= compl_col) { + return &compl_orig_text; + } + return &compl_leader; // pass through (startcol < compl_col) + } + + if (compl_col <= 0) { + goto theend; + } + if (startcol >= 0 && startcol < compl_col) { int prepend_len = compl_col - startcol; int new_length = prepend_len + (int)compl_leader.size; diff --git a/test/old/testdir/test_ins_complete.vim b/test/old/testdir/test_ins_complete.vim index 15e7964c45..f844f44a2c 100644 --- a/test/old/testdir/test_ins_complete.vim +++ b/test/old/testdir/test_ins_complete.vim @@ -3946,6 +3946,31 @@ func Test_complete_fuzzy_collect() set completeopt& cpt& ignorecase& infercase& endfunc +" Issue #19434 +" Fuzzy whole-line completion should not loop infinitely when the cursor is in +" the middle of the line (non-zero column). +func Test_complete_fuzzy_wholeline_no_hang() + new + set completeopt=preview,fuzzy,noinsert,menuone + call setline(1, [ + \ '', + \ '', + \ '
', + \ ' ', + \ ' ', + \ '