1
0
forked from aniani/vim

patch 8.2.3989: some insert completion code is not tested

Problem:    Some insert completion code is not tested.
Solution:   Add a few tests.  Refactor thesaurus completion. (Yegappan
            Lakshmanan, closes #9460)
This commit is contained in:
Yegappan Lakshmanan
2022-01-03 11:03:48 +00:00
committed by Bram Moolenaar
parent 475d9521ba
commit e982586f8e
4 changed files with 210 additions and 47 deletions

View File

@@ -1017,6 +1017,10 @@ ins_compl_dict_alloc(compl_T *match)
return dict; return dict;
} }
/*
* Trigger the CompleteChanged autocmd event. Invoked each time the Insert mode
* completion menu is changed.
*/
static void static void
trigger_complete_changed_event(int cur) trigger_complete_changed_event(int cur)
{ {
@@ -1219,8 +1223,8 @@ ins_compl_show_pum(void)
#define DICT_EXACT (2) // "dict" is the exact name of a file #define DICT_EXACT (2) // "dict" is the exact name of a file
/* /*
* Add any identifiers that match the given pattern in the list of dictionary * Add any identifiers that match the given pattern "pat" in the list of
* files "dict_start" to the list of completions. * dictionary files "dict_start" to the list of completions.
*/ */
static void static void
ins_compl_dictionaries( ins_compl_dictionaries(
@@ -1346,6 +1350,66 @@ theend:
vim_free(buf); vim_free(buf);
} }
/*
* Add all the words in the line "*buf_arg" from the thesaurus file "fname"
* skipping the word at 'skip_word'. Returns OK on success.
*/
static int
thesarurs_add_words_in_line(
char_u *fname,
char_u **buf_arg,
int dir,
char_u *skip_word)
{
int status = OK;
char_u *ptr;
char_u *wstart;
// Add the other matches on the line
ptr = *buf_arg;
while (!got_int)
{
// Find start of the next word. Skip white
// space and punctuation.
ptr = find_word_start(ptr);
if (*ptr == NUL || *ptr == NL)
break;
wstart = ptr;
// Find end of the word.
if (has_mbyte)
// Japanese words may have characters in
// different classes, only separate words
// with single-byte non-word characters.
while (*ptr != NUL)
{
int l = (*mb_ptr2len)(ptr);
if (l < 2 && !vim_iswordc(*ptr))
break;
ptr += l;
}
else
ptr = find_word_end(ptr);
// Add the word. Skip the regexp match.
if (wstart != skip_word)
{
status = ins_compl_add_infercase(wstart, (int)(ptr - wstart), p_ic,
fname, dir, FALSE);
if (status == FAIL)
break;
}
}
*buf_arg = ptr;
return status;
}
/*
* Process "count" dictionary/thesaurus "files" and add the text matching
* "regmatch".
*/
static void static void
ins_compl_files( ins_compl_files(
int count, int count,
@@ -1392,41 +1456,10 @@ ins_compl_files(
p_ic, files[i], *dir, FALSE); p_ic, files[i], *dir, FALSE);
if (thesaurus) if (thesaurus)
{ {
char_u *wstart; // For a thesaurus, add all the words in the line
// Add the other matches on the line
ptr = buf; ptr = buf;
while (!got_int) add_r = thesarurs_add_words_in_line(files[i], &ptr, *dir,
{ regmatch->startp[0]);
// Find start of the next word. Skip white
// space and punctuation.
ptr = find_word_start(ptr);
if (*ptr == NUL || *ptr == NL)
break;
wstart = ptr;
// Find end of the word.
if (has_mbyte)
// Japanese words may have characters in
// different classes, only separate words
// with single-byte non-word characters.
while (*ptr != NUL)
{
int l = (*mb_ptr2len)(ptr);
if (l < 2 && !vim_iswordc(*ptr))
break;
ptr += l;
}
else
ptr = find_word_end(ptr);
// Add the word. Skip the regexp match.
if (wstart != regmatch->startp[0])
add_r = ins_compl_add_infercase(wstart,
(int)(ptr - wstart),
p_ic, files[i], *dir, FALSE);
}
} }
if (add_r == OK) if (add_r == OK)
// if dir was BACKWARD then honor it just once // if dir was BACKWARD then honor it just once
@@ -1649,15 +1682,14 @@ ins_compl_bs(void)
vim_free(compl_leader); vim_free(compl_leader);
compl_leader = vim_strnsave(line + compl_col, (p - line) - compl_col); compl_leader = vim_strnsave(line + compl_col, (p - line) - compl_col);
if (compl_leader != NULL) if (compl_leader == NULL)
{ return K_BS;
ins_compl_new_leader(); ins_compl_new_leader();
if (compl_shown_match != NULL) if (compl_shown_match != NULL)
// Make sure current match is not a hidden item. // Make sure current match is not a hidden item.
compl_curr_match = compl_shown_match; compl_curr_match = compl_shown_match;
return NUL; return NUL;
}
return K_BS;
} }
/* /*
@@ -2795,6 +2827,10 @@ ins_compl_mode(void)
return (char_u *)""; return (char_u *)"";
} }
/*
* Assign the sequence number to all the completion matches which don't have
* one assigned yet.
*/
static void static void
ins_compl_update_sequence_numbers() ins_compl_update_sequence_numbers()
{ {
@@ -4853,6 +4889,9 @@ ins_complete(int c, int enable_pum)
return OK; return OK;
} }
/*
* Remove (if needed) and show the popup menu
*/
static void static void
show_pum(int prev_w_wrow, int prev_w_leftcol) show_pum(int prev_w_wrow, int prev_w_leftcol)
{ {

View File

@@ -733,8 +733,13 @@ func Test_edit_CTRL_N()
call feedkeys("Ii\<c-n>\<cr>\<esc>", "tnix") call feedkeys("Ii\<c-n>\<cr>\<esc>", "tnix")
call feedkeys("ILO\<c-n>\<cr>\<esc>", 'tnix') call feedkeys("ILO\<c-n>\<cr>\<esc>", 'tnix')
call assert_equal(['INFER', 'loWER', 'infer', 'LOWER', '', ''], getline(1, '$'), e) call assert_equal(['INFER', 'loWER', 'infer', 'LOWER', '', ''], getline(1, '$'), e)
set noignorecase noinfercase
set noignorecase noinfercase complete& %d
call setline(1, ['one word', 'two word'])
exe "normal! Goo\<C-P>\<C-X>\<C-P>"
call assert_equal('one word', getline(3))
%d
set complete&
bw! bw!
endfor endfor
endfunc endfunc
@@ -900,6 +905,23 @@ func Test_edit_CTRL_T()
bw! bw!
endfunc endfunc
" Test thesaurus completion with different encodings
func Test_thesaurus_complete_with_encoding()
call writefile(['angry furious mad enraged'], 'Xthesaurus')
set thesaurus=Xthesaurus
for e in ['latin1', 'utf-8']
exe 'set encoding=' .. e
new
call setline(1, 'mad')
call cursor(1, 1)
call feedkeys("A\<c-x>\<c-t>\<cr>\<esc>", 'tnix')
call assert_equal(['mad', ''], getline(1, '$'))
bw!
endfor
set thesaurus=
call delete('Xthesaurus')
endfunc
" Test 'thesaurusfunc' " Test 'thesaurusfunc'
func MyThesaurus(findstart, base) func MyThesaurus(findstart, base)
let mythesaurus = [ let mythesaurus = [

View File

@@ -709,6 +709,21 @@ func Test_complete_func_error()
call assert_equal([], complete_info(['items']).items) call assert_equal([], complete_info(['items']).items)
endfunc endfunc
" Test for recursively starting completion mode using complete()
func Test_recursive_complete_func()
func ListColors()
call complete(5, ["red", "blue"])
return ''
endfunc
new
call setline(1, ['a1', 'a2'])
set complete=.
exe "normal Goa\<C-X>\<C-L>\<C-R>=ListColors()\<CR>\<C-N>"
call assert_equal('a2blue', getline(3))
delfunc ListColors
bw!
endfunc
" Test for completing words following a completed word in a line " Test for completing words following a completed word in a line
func Test_complete_wrapscan() func Test_complete_wrapscan()
" complete words from another buffer " complete words from another buffer
@@ -932,6 +947,91 @@ func Test_issue_7021()
set completeslash= set completeslash=
endfunc endfunc
" Test for 'longest' setting in 'completeopt' with latin1 and utf-8 encodings
func Test_complete_longest_match()
for e in ['latin1', 'utf-8']
exe 'set encoding=' .. e
new
set complete=.
set completeopt=menu,longest
call setline(1, ['pfx_a1', 'pfx_a12', 'pfx_a123', 'pfx_b1'])
exe "normal Gopfx\<C-P>"
call assert_equal('pfx_', getline(5))
bw!
endfor
" Test for completing additional words with longest match set
new
call setline(1, ['abc1', 'abd2'])
exe "normal Goab\<C-P>\<C-X>\<C-P>"
call assert_equal('ab', getline(3))
bw!
set complete& completeopt&
endfunc
" Test for removing the first displayed completion match and selecting the
" match just before that.
func Test_complete_erase_firstmatch()
new
call setline(1, ['a12', 'a34', 'a56'])
set complete=.
exe "normal Goa\<C-P>\<BS>\<BS>3\<CR>"
call assert_equal('a34', getline('$'))
set complete&
bw!
endfunc
" Test for completing whole lines from unloaded buffers
func Test_complete_wholeline_unloadedbuf()
call writefile(['a line1', 'a line2', 'a line3'], "Xfile1")
edit Xfile1
enew
set complete=u
exe "normal! ia\<C-X>\<C-L>\<C-P>"
call assert_equal('a line2', getline(1))
%d
" completing from an unlisted buffer should fail
bdel Xfile1
exe "normal! ia\<C-X>\<C-L>\<C-P>"
call assert_equal('a', getline(1))
set complete&
%bw!
call delete("Xfile1")
endfunc
" Test for completing whole lines from unlisted buffers
func Test_complete_wholeline_unlistedbuf()
call writefile(['a line1', 'a line2', 'a line3'], "Xfile1")
edit Xfile1
enew
set complete=U
" completing from a unloaded buffer should fail
exe "normal! ia\<C-X>\<C-L>\<C-P>"
call assert_equal('a', getline(1))
%d
bdel Xfile1
exe "normal! ia\<C-X>\<C-L>\<C-P>"
call assert_equal('a line2', getline(1))
set complete&
%bw!
call delete("Xfile1")
endfunc
" Test for adding a multibyte character using CTRL-L in completion mode
func Test_complete_mbyte_char_add()
new
set complete=.
call setline(1, 'abė')
exe "normal! oa\<C-P>\<BS>\<BS>\<C-L>\<C-L>"
call assert_equal('abė', getline(2))
" Test for a leader with multibyte character
%d
call setline(1, 'abėĕ')
exe "normal! oabė\<C-P>"
call assert_equal('abėĕ', getline(2))
bw!
endfunc
" Test to ensure 'Scanning...' messages are not recorded in messages history " Test to ensure 'Scanning...' messages are not recorded in messages history
func Test_z1_complete_no_history() func Test_z1_complete_no_history()
new new

View File

@@ -750,6 +750,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
3989,
/**/ /**/
3988, 3988,
/**/ /**/