Skip to content

Commit 73655cf

Browse files
committed
patch 8.1.1123: no way to avoid filtering for autocomplete function
Problem: No way to avoid filtering for autocomplete function, causing flickering of the popup menu. Solution: Add the "equal" field to complete items. (closes #3887)
1 parent 9d40128 commit 73655cf

4 files changed

Lines changed: 70 additions & 22 deletions

File tree

runtime/doc/insert.txt

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1105,17 +1105,20 @@ items:
11051105
icase when non-zero case is to be ignored when comparing
11061106
items to be equal; when omitted zero is used, thus
11071107
items that only differ in case are added
1108+
equal when non-zero, always treat this item to be equal when
1109+
comparing. Which means, "equal=1" disables filtering
1110+
of this item.
11081111
dup when non-zero this match will be added even when an
11091112
item with the same word is already present.
11101113
empty when non-zero this match will be added even when it is
11111114
an empty string
11121115
user_data custom data which is associated with the item and
11131116
available in |v:completed_item|
11141117

1115-
All of these except "icase", "dup" and "empty" must be a string. If an item
1116-
does not meet these requirements then an error message is given and further
1117-
items in the list are not used. You can mix string and Dictionary items in
1118-
the returned list.
1118+
All of these except "icase", "equal", "dup" and "empty" must be a string. If
1119+
an item does not meet these requirements then an error message is given and
1120+
further items in the list are not used. You can mix string and Dictionary
1121+
items in the returned list.
11191122

11201123
The "menu" item is used in the popup menu and may be truncated, thus it should
11211124
be relatively short. The "info" item can be longer, it will be displayed in

src/insexpand.c

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -101,16 +101,18 @@ struct compl_S
101101
{
102102
compl_T *cp_next;
103103
compl_T *cp_prev;
104-
char_u *cp_str; /* matched text */
105-
char cp_icase; /* TRUE or FALSE: ignore case */
106-
char_u *(cp_text[CPT_COUNT]); /* text for the menu */
107-
char_u *cp_fname; /* file containing the match, allocated when
108-
* cp_flags has FREE_FNAME */
109-
int cp_flags; /* ORIGINAL_TEXT, CONT_S_IPOS or FREE_FNAME */
110-
int cp_number; /* sequence number */
104+
char_u *cp_str; // matched text
105+
char cp_icase; // TRUE or FALSE: ignore case
106+
char cp_equal; // TRUE or FALSE: ins_compl_equal always ok
107+
char_u *(cp_text[CPT_COUNT]); // text for the menu
108+
char_u *cp_fname; // file containing the match, allocated when
109+
// cp_flags has FREE_FNAME
110+
int cp_flags; // ORIGINAL_TEXT, CONT_S_IPOS or FREE_FNAME
111+
int cp_number; // sequence number
111112
};
112113

113-
# define ORIGINAL_TEXT (1) /* the original text when the expansion begun */
114+
// flags for ins_compl_add()
115+
# define ORIGINAL_TEXT (1) // the original text when the expansion begun
114116
# define FREE_FNAME (2)
115117

116118
static char e_hitend[] = N_("Hit end of paragraph");
@@ -183,7 +185,7 @@ static expand_T compl_xp;
183185
static int compl_opt_refresh_always = FALSE;
184186
static int compl_opt_suppress_empty = FALSE;
185187

186-
static int ins_compl_add(char_u *str, int len, int icase, char_u *fname, char_u **cptext, int cdir, int flags, int adup);
188+
static int ins_compl_add(char_u *str, int len, int icase, char_u *fname, char_u **cptext, int cdir, int flags, int adup, int equal);
187189
static void ins_compl_longest_match(compl_T *match);
188190
static void ins_compl_del_pum(void);
189191
static void ins_compl_files(int count, char_u **files, int thesaurus, int flags, regmatch_T *regmatch, char_u *buf, int *dir);
@@ -413,13 +415,14 @@ ins_compl_accept_char(int c)
413415
*/
414416
int
415417
ins_compl_add_infercase(
416-
char_u *str,
418+
char_u *str_arg,
417419
int len,
418420
int icase,
419421
char_u *fname,
420422
int dir,
421423
int flags)
422424
{
425+
char_u *str = str_arg;
423426
char_u *p;
424427
int i, c;
425428
int actual_len; // Take multi-byte characters
@@ -550,10 +553,11 @@ ins_compl_add_infercase(
550553
vim_free(wca);
551554
}
552555

553-
return ins_compl_add(IObuff, len, icase, fname, NULL, dir,
554-
flags, FALSE);
556+
str = IObuff;
555557
}
556-
return ins_compl_add(str, len, icase, fname, NULL, dir, flags, FALSE);
558+
559+
return ins_compl_add(str, len, icase, fname, NULL, dir,
560+
flags, FALSE, FALSE);
557561
}
558562

559563
/*
@@ -571,7 +575,8 @@ ins_compl_add(
571575
char_u **cptext, // extra text for popup menu or NULL
572576
int cdir,
573577
int flags,
574-
int adup) // accept duplicate match
578+
int adup, // accept duplicate match
579+
int equal) // match is always accepted by ins_compl_equal
575580
{
576581
compl_T *match;
577582
int dir = (cdir == 0 ? compl_direction : cdir);
@@ -613,6 +618,7 @@ ins_compl_add(
613618
return FAIL;
614619
}
615620
match->cp_icase = icase;
621+
match->cp_equal = equal;
616622

617623
// match-fname is:
618624
// - compl_curr_match->cp_fname if it is a string equal to fname.
@@ -676,6 +682,8 @@ ins_compl_add(
676682
static int
677683
ins_compl_equal(compl_T *match, char_u *str, int len)
678684
{
685+
if (match->cp_equal)
686+
return TRUE;
679687
if (match->cp_icase)
680688
return STRNICMP(match->cp_str, str, (size_t)len) == 0;
681689
return STRNCMP(match->cp_str, str, (size_t)len) == 0;
@@ -776,7 +784,7 @@ ins_compl_add_matches(
776784

777785
for (i = 0; i < num_matches && add_r != FAIL; i++)
778786
if ((add_r = ins_compl_add(matches[i], -1, icase,
779-
NULL, NULL, dir, 0, FALSE)) == OK)
787+
NULL, NULL, dir, 0, FALSE, FALSE)) == OK)
780788
// if dir was BACKWARD then honor it just once
781789
dir = FORWARD;
782790
FreeWild(num_matches, matches);
@@ -868,7 +876,7 @@ set_completion(colnr_T startcol, list_T *list)
868876
// compl_pattern doesn't need to be set
869877
compl_orig_text = vim_strnsave(ml_get_curline() + compl_col, compl_length);
870878
if (compl_orig_text == NULL || ins_compl_add(compl_orig_text,
871-
-1, p_ic, NULL, NULL, 0, ORIGINAL_TEXT, FALSE) != OK)
879+
-1, p_ic, NULL, NULL, 0, ORIGINAL_TEXT, FALSE, FALSE) != OK)
872880
return;
873881

874882
ctrl_x_mode = CTRL_X_EVAL;
@@ -2365,6 +2373,7 @@ ins_compl_add_tv(typval_T *tv, int dir)
23652373
int icase = FALSE;
23662374
int adup = FALSE;
23672375
int aempty = FALSE;
2376+
int aequal = FALSE;
23682377
char_u *(cptext[CPT_COUNT]);
23692378

23702379
if (tv->v_type == VAR_DICT && tv->vval.v_dict != NULL)
@@ -2386,6 +2395,8 @@ ins_compl_add_tv(typval_T *tv, int dir)
23862395
adup = dict_get_number(tv->vval.v_dict, (char_u *)"dup");
23872396
if (dict_get_string(tv->vval.v_dict, (char_u *)"empty", FALSE) != NULL)
23882397
aempty = dict_get_number(tv->vval.v_dict, (char_u *)"empty");
2398+
if (dict_get_string(tv->vval.v_dict, (char_u *)"equal", FALSE) != NULL)
2399+
aequal = dict_get_number(tv->vval.v_dict, (char_u *)"equal");
23892400
}
23902401
else
23912402
{
@@ -2394,7 +2405,7 @@ ins_compl_add_tv(typval_T *tv, int dir)
23942405
}
23952406
if (word == NULL || (!aempty && *word == NUL))
23962407
return FAIL;
2397-
return ins_compl_add(word, -1, icase, NULL, cptext, dir, 0, adup);
2408+
return ins_compl_add(word, -1, icase, NULL, cptext, dir, 0, adup, aequal);
23982409
}
23992410
#endif
24002411

@@ -3694,7 +3705,7 @@ ins_complete(int c, int enable_pum)
36943705
vim_free(compl_orig_text);
36953706
compl_orig_text = vim_strnsave(line + compl_col, compl_length);
36963707
if (compl_orig_text == NULL || ins_compl_add(compl_orig_text,
3697-
-1, p_ic, NULL, NULL, 0, ORIGINAL_TEXT, FALSE) != OK)
3708+
-1, p_ic, NULL, NULL, 0, ORIGINAL_TEXT, FALSE, FALSE) != OK)
36983709
{
36993710
VIM_CLEAR(compl_pattern);
37003711
VIM_CLEAR(compl_orig_text);

src/testdir/test_popup.vim

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,38 @@ func Test_noinsert_complete()
276276
iunmap <F5>
277277
endfunc
278278

279+
func Test_complete_no_filter()
280+
func! s:complTest1() abort
281+
call complete(1, [{'word': 'foobar'}])
282+
return ''
283+
endfunc
284+
func! s:complTest2() abort
285+
call complete(1, [{'word': 'foobar', 'equal': 1}])
286+
return ''
287+
endfunc
288+
289+
let completeopt = &completeopt
290+
291+
" without equal=1
292+
new
293+
set completeopt=menuone,noinsert,menu
294+
inoremap <F5> <C-R>=s:complTest1()<CR>
295+
call feedkeys("i\<F5>z\<CR>\<CR>\<ESC>.", 'tx')
296+
call assert_equal('z', getline(1))
297+
bwipe!
298+
299+
" with equal=1
300+
new
301+
set completeopt=menuone,noinsert,menu
302+
inoremap <F5> <C-R>=s:complTest2()<CR>
303+
call feedkeys("i\<F5>z\<CR>\<CR>\<ESC>.", 'tx')
304+
call assert_equal('foobar', getline(1))
305+
bwipe!
306+
307+
let &completeopt = completeopt
308+
iunmap <F5>
309+
endfunc
310+
279311
func Test_compl_vim_cmds_after_register_expr()
280312
func! s:test_func()
281313
return 'autocmd '

src/version.c

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

772772
static int included_patches[] =
773773
{ /* Add new patch number below this line */
774+
/**/
775+
1123,
774776
/**/
775777
1122,
776778
/**/

0 commit comments

Comments
 (0)