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:
committed by
Bram Moolenaar
parent
475d9521ba
commit
e982586f8e
119
src/insexpand.c
119
src/insexpand.c
@@ -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,16 +1682,15 @@ 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return TRUE when we need to find matches again, ins_compl_restart() is to
|
* Return TRUE when we need to find matches again, ins_compl_restart() is to
|
||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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 = [
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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,
|
||||||
/**/
|
/**/
|
||||||
|
|||||||
Reference in New Issue
Block a user