]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.1.1610: completion: hang or E684 when 'tagfunc' calls complete() v9.1.1610
authorzeertzjq <zeertzjq@outlook.com>
Fri, 8 Aug 2025 14:03:43 +0000 (16:03 +0200)
committerChristian Brabandt <cb@256bit.org>
Fri, 8 Aug 2025 14:05:23 +0000 (16:05 +0200)
Problem:  completion: hang (after 9.1.1471) or E684 (after 9.1.1410)
          when 'tagfunc' calls complete().
Solution: Check if complete() has been called immediately after getting
          matches instead of in the next loop iteration (zeertzjq).

related: #1668
related: neovim/neovim#34416
related: neovim/neovim#35163
closes: #17929

Signed-off-by: zeertzjq <zeertzjq@outlook.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
src/insexpand.c
src/testdir/test_ins_complete.vim
src/version.c

index 5b4afb9e4320cf4435ef3a4dfe6540001dc61fa4..3a775422d77d605c9320b288802edba3254563ac 100644 (file)
@@ -5515,11 +5515,6 @@ ins_compl_get_exp(pos_T *ini)
            }
        }
 
-       // If complete() was called then compl_pattern has been reset.  The
-       // following won't work then, bail out.
-       if (compl_pattern.string == NULL)
-           break;
-
        if (compl_autocomplete && type == CTRL_X_FUNCTION)
            // LSP servers may sporadically take >1s to respond (e.g., while
            // loading modules), but other sources might already have matches.
@@ -5532,6 +5527,11 @@ ins_compl_get_exp(pos_T *ini)
        // get the next set of completion matches
        found_new_match = get_next_completion_match(type, &st, &start_pos);
 
+       // If complete() was called then compl_pattern has been reset.  The
+       // following won't work then, bail out.
+       if (compl_pattern.string == NULL)
+           break;
+
        if (may_advance_cpt_idx)
        {
            if (!advance_cpt_sources_index_safe())
index 560b2c424eceee22b2a24f237abe32dfa425959a..1ec71118c941491cc843786156c62b1ab704dc45 100644 (file)
@@ -3221,6 +3221,35 @@ func Test_tagfunc_wipes_out_buffer()
   bwipe!
 endfunc
 
+func s:TagfuncComplete(t,f,o)
+  call complete(1, ['ddd', 'eee', 'fff'])
+  return []
+endfunc
+
+" 'tagfunc' calling complete() should not cause hang or E684.
+func Test_tagfunc_calls_complete()
+  new
+  call setline(1, ['aaa', 'bbb', 'ccc'])
+  setlocal tagfunc=s:TagfuncComplete
+  setlocal completeopt=menu,noselect
+
+  let v:errmsg = ''
+
+  " This used to hang.
+  setlocal complete=.,t
+  call feedkeys("Go\<C-N>\<C-E>\<Esc>", 'tx')
+  call assert_equal('', getline('.'))
+  call assert_equal('', v:errmsg)
+
+  " This used to cause E684.
+  setlocal complete=t,.
+  call feedkeys("cc\<C-N>\<C-E>\<Esc>", 'tx')
+  call assert_equal('', getline('.'))
+  call assert_equal('', v:errmsg)
+
+  bwipe!
+endfunc
+
 func Test_ins_complete_popup_position()
   CheckScreendump
 
index 4abf6025d2aa6b6a6a1fcc9dd59082247423ddbc..e2c46855e43be1b3325acfc204cc2db182f9ddf7 100644 (file)
@@ -719,6 +719,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1610,
 /**/
     1609,
 /**/