Skip to content

Commit 6a230c6

Browse files
SilverGozasbrammool
authored andcommitted
patch 8.2.3293: finding completions may cause an endless loop
Problem: Finding completions may cause an endless loop. Solution: Use a better way to check coming back where the search started. (Andy Gozas, closes #8672, closes #8671)
1 parent bc67e5a commit 6a230c6

4 files changed

Lines changed: 82 additions & 1 deletion

File tree

src/insexpand.c

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2712,6 +2712,8 @@ ins_compl_get_exp(pos_T *ini)
27122712
char_u *dict = NULL;
27132713
int dict_f = 0;
27142714
int set_match_pos;
2715+
pos_T prev_pos = {0, 0, 0};
2716+
int looped_around = FALSE;
27152717

27162718
if (!compl_started)
27172719
{
@@ -2964,6 +2966,7 @@ ins_compl_get_exp(pos_T *ini)
29642966
p_ws = FALSE;
29652967
else if (*e_cpt == '.')
29662968
p_ws = TRUE;
2969+
looped_around = FALSE;
29672970
for (;;)
29682971
{
29692972
int cont_s_ipos = FALSE;
@@ -2991,8 +2994,31 @@ ins_compl_get_exp(pos_T *ini)
29912994
set_match_pos = FALSE;
29922995
}
29932996
else if (first_match_pos.lnum == last_match_pos.lnum
2994-
&& first_match_pos.col == last_match_pos.col)
2997+
&& first_match_pos.col == last_match_pos.col)
2998+
{
29952999
found_new_match = FAIL;
3000+
}
3001+
else if ((compl_direction == FORWARD)
3002+
&& (prev_pos.lnum > pos->lnum
3003+
|| (prev_pos.lnum == pos->lnum
3004+
&& prev_pos.col >= pos->col)))
3005+
{
3006+
if (looped_around)
3007+
found_new_match = FAIL;
3008+
else
3009+
looped_around = TRUE;
3010+
}
3011+
else if ((compl_direction != FORWARD)
3012+
&& (prev_pos.lnum < pos->lnum
3013+
|| (prev_pos.lnum == pos->lnum
3014+
&& prev_pos.col <= pos->col)))
3015+
{
3016+
if (looped_around)
3017+
found_new_match = FAIL;
3018+
else
3019+
looped_around = TRUE;
3020+
}
3021+
prev_pos = *pos;
29963022
if (found_new_match == FAIL)
29973023
{
29983024
if (ins_buf == curbuf)

src/testdir/Make_all.mak

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ NEW_TESTS = \
162162
test_increment_dbcs \
163163
test_indent \
164164
test_ins_complete \
165+
test_ins_complete_no_halt \
165166
test_interrupt \
166167
test_job_fails \
167168
test_join \
@@ -405,6 +406,7 @@ NEW_TESTS_RES = \
405406
test_increment_dbcs.res \
406407
test_indent.res \
407408
test_ins_complete.res \
409+
test_ins_complete_no_halt.res \
408410
test_interrupt.res \
409411
test_job_fails.res \
410412
test_join.res \
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
" Test insert mode completion does not get stuck when looping around.
2+
" In a separate file to avoid the settings to leak to other test cases.
3+
4+
set complete+=kspell
5+
set completeopt+=menu
6+
set completeopt+=menuone
7+
set completeopt+=noselect
8+
set completeopt+=noinsert
9+
let g:autocompletion = v:true
10+
11+
func Test_ins_complete_no_halt()
12+
function! OpenCompletion()
13+
if pumvisible() && (g:autocompletion == v:true)
14+
call feedkeys("\<C-e>\<C-n>", "i")
15+
return
16+
endif
17+
if ((v:char >= 'a' && v:char <= 'z') || (v:char >= 'A' && v:char <= 'Z')) && (g:autocompletion == v:true)
18+
call feedkeys("\<C-n>", "i")
19+
redraw
20+
endif
21+
endfunction
22+
23+
autocmd InsertCharPre * noautocmd call OpenCompletion()
24+
25+
setlocal spell! spelllang=en_us
26+
27+
call feedkeys("iauto-complete-halt-test test test test test test test test test test test test test test test test test test test\<C-c>", "tx!")
28+
call assert_equal(["auto-complete-halt-test test test test test test test test test test test test test test test test test test test"], getline(1, "$"))
29+
endfunc
30+
31+
func Test_auto_complete_backwards_no_halt()
32+
function! OpenCompletion()
33+
if pumvisible() && (g:autocompletion == v:true)
34+
call feedkeys("\<C-e>\<C-p>", "i")
35+
return
36+
endif
37+
if ((v:char >= 'a' && v:char <= 'z') || (v:char >= 'A' && v:char <= 'Z')) && (g:autocompletion == v:true)
38+
call feedkeys("\<C-p>", "i")
39+
redraw
40+
endif
41+
endfunction
42+
43+
autocmd InsertCharPre * noautocmd call OpenCompletion()
44+
45+
setlocal spell! spelllang=en_us
46+
47+
call feedkeys("iauto-complete-halt-test test test test test test test test test test test test test test test test test test test\<C-c>", "tx!")
48+
call assert_equal(["auto-complete-halt-test test test test test test test test test test test test test test test test test test test"], getline(1, "$"))
49+
endfunc
50+
51+
" vim: shiftwidth=2 sts=2 expandtab

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -755,6 +755,8 @@ static char *(features[]) =
755755

756756
static int included_patches[] =
757757
{ /* Add new patch number below this line */
758+
/**/
759+
3293,
758760
/**/
759761
3292,
760762
/**/

0 commit comments

Comments
 (0)