diff options
author | zeertzjq <zeertzjq@outlook.com> | 2022-08-25 07:45:00 +0800 |
---|---|---|
committer | zeertzjq <zeertzjq@outlook.com> | 2022-08-25 08:27:44 +0800 |
commit | cabc1861c478b36570bc8d6633097cd4729b8303 (patch) | |
tree | a5a36689b6c39c5523257ff452bcdb9c15f6d1a9 /src | |
parent | 6c9a91bebeaef7e863f4b37e8656f49e9aaf33ab (diff) | |
download | rneovim-cabc1861c478b36570bc8d6633097cd4729b8303.tar.gz rneovim-cabc1861c478b36570bc8d6633097cd4729b8303.tar.bz2 rneovim-cabc1861c478b36570bc8d6633097cd4729b8303.zip |
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 vim/vim#9460)
https://github.com/vim/vim/commit/e982586f8eebf2b055987218f6d3f7a084c4bf69
vim-patch:9.0.0254: typo in function name
Problem: Typo in function name.
Solution: Rename the function. (closes vim/vim#10971)
https://github.com/vim/vim/commit/5fb3aabc2b0edd5573e107bb3bc103c348771f61
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/insexpand.c | 93 | ||||
-rw-r--r-- | src/nvim/testdir/test_edit.vim | 27 | ||||
-rw-r--r-- | src/nvim/testdir/test_ins_complete.vim | 101 |
3 files changed, 185 insertions, 36 deletions
diff --git a/src/nvim/insexpand.c b/src/nvim/insexpand.c index d22c1ff980..21285a4365 100644 --- a/src/nvim/insexpand.c +++ b/src/nvim/insexpand.c @@ -1005,6 +1005,8 @@ static dict_T *ins_compl_dict_alloc(compl_T *match) return dict; } +/// Trigger the CompleteChanged autocmd event. Invoked each time the Insert mode +/// completion menu is changed. static void trigger_complete_changed_event(int cur) { static bool recursive = false; @@ -1181,8 +1183,8 @@ void ins_compl_show_pum(void) #define DICT_FIRST (1) ///< use just first element in "dict" #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 -/// files "dict_start" to the list of completions. +/// Add any identifiers that match the given pattern "pat" in the list of +/// dictionary files "dict_start" to the list of completions. /// /// @param flags DICT_FIRST and/or DICT_EXACT /// @param thesaurus Thesaurus completion @@ -1283,6 +1285,54 @@ theend: xfree(buf); } +/// Add all the words in the line "*buf_arg" from the thesaurus file "fname" +/// skipping the word at 'skip_word'. +/// +/// @return OK on success. +static int thesaurus_add_words_in_line(char *fname, char_u **buf_arg, int dir, char_u *skip_word) +{ + int status = OK; + + // Add the other matches on the line + char_u *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; + } + char_u *wstart = ptr; + + // Find end of the word. + // Japanese words may have characters in + // different classes, only separate words + // with single-byte non-word characters. + while (*ptr != NUL) { + const int l = utfc_ptr2len((const char *)ptr); + + if (l < 2 && !vim_iswordc(*ptr)) { + break; + } + ptr += l; + } + + // Add the word. Skip the regexp match. + if (wstart != skip_word) { + status = ins_compl_add_infercase(wstart, (int)(ptr - wstart), p_ic, + (char_u *)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 ins_compl_files(int count, char **files, int thesaurus, int flags, regmatch_T *regmatch, char_u *buf, Direction *dir) FUNC_ATTR_NONNULL_ARG(2, 7) @@ -1320,38 +1370,10 @@ static void ins_compl_files(int count, char **files, int thesaurus, int flags, r (int)(ptr - regmatch->startp[0]), p_ic, (char_u *)files[i], *dir, false); if (thesaurus) { - char_u *wstart; - - // Add the other matches on the line + // For a thesaurus, add all the words in the line ptr = buf; - 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. - // Japanese words may have characters in - // different classes, only separate words - // with single-byte non-word characters. - while (*ptr != NUL) { - const int l = utfc_ptr2len((char *)ptr); - - if (l < 2 && !vim_iswordc(*ptr)) { - break; - } - ptr += l; - } - - // Add the word. Skip the regexp match. - if (wstart != regmatch->startp[0]) { - add_r = ins_compl_add_infercase(wstart, (int)(ptr - wstart), - p_ic, (char_u *)files[i], *dir, false); - } - } + add_r = thesaurus_add_words_in_line(files[i], &ptr, *dir, + regmatch->startp[0]); } if (add_r == OK) { // if dir was BACKWARD then honor it just once @@ -1536,12 +1558,12 @@ int ins_compl_bs(void) xfree(compl_leader); compl_leader = vim_strnsave(line + compl_col, (size_t)(p_off - (ptrdiff_t)compl_col)); + ins_compl_new_leader(); if (compl_shown_match != NULL) { // Make sure current match is not a hidden item. compl_curr_match = compl_shown_match; } - return NUL; } @@ -2401,6 +2423,8 @@ static char_u *ins_compl_mode(void) return (char_u *)""; } +/// Assign the sequence number to all the completion matches which don't have +/// one assigned yet. static void ins_compl_update_sequence_numbers(void) { int number = 0; @@ -4154,6 +4178,7 @@ int ins_complete(int c, bool enable_pum) return OK; } +/// Remove (if needed) and show the popup menu static void show_pum(int prev_w_wrow, int prev_w_leftcol) { // RedrawingDisabled may be set when invoked through complete(). diff --git a/src/nvim/testdir/test_edit.vim b/src/nvim/testdir/test_edit.vim index fa288df0d9..679b877ef6 100644 --- a/src/nvim/testdir/test_edit.vim +++ b/src/nvim/testdir/test_edit.vim @@ -730,8 +730,13 @@ func Test_edit_CTRL_N() call feedkeys("Ii\<c-n>\<cr>\<esc>", "tnix") call feedkeys("ILO\<c-n>\<cr>\<esc>", 'tnix') call assert_equal(['INFER', 'loWER', 'infer', 'LOWER', '', ''], getline(1, '$'), e) - - set noignorecase noinfercase complete& + set noignorecase noinfercase + %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! endfor endfunc @@ -897,6 +902,24 @@ func Test_edit_CTRL_T() bw! 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'] + for e in ['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' func MyThesaurus(findstart, base) let mythesaurus = [ diff --git a/src/nvim/testdir/test_ins_complete.vim b/src/nvim/testdir/test_ins_complete.vim index 8f7d2cb278..914d818eef 100644 --- a/src/nvim/testdir/test_ins_complete.vim +++ b/src/nvim/testdir/test_ins_complete.vim @@ -682,6 +682,21 @@ func Test_complete_func_error() call assert_equal([], complete_info(['items']).items) 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 func Test_complete_wrapscan() " complete words from another buffer @@ -905,6 +920,92 @@ func Test_issue_7021() set completeslash= endfunc +" Test for 'longest' setting in 'completeopt' with latin1 and utf-8 encodings +func Test_complete_longest_match() + " for e in ['latin1', 'utf-8'] + for e in ['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 func Test_z1_complete_no_history() new |