To: vim_dev@googlegroups.com Subject: Patch 8.2.3989 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.3989 Problem: Some insert completion code is not tested. Solution: Add a few tests. Refactor thesaurus completion. (Yegappan Lakshmanan, closes #9460) Files: src/insexpand.c, src/testdir/test_edit.vim, src/testdir/test_ins_complete.vim *** ../vim-8.2.3988/src/insexpand.c 2022-01-01 15:58:19.114486366 +0000 --- src/insexpand.c 2022-01-03 11:02:39.358931895 +0000 *************** *** 1017,1022 **** --- 1017,1026 ---- 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) { *************** *** 1219,1226 **** #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. */ static void ins_compl_dictionaries( --- 1223,1230 ---- #define DICT_EXACT (2) // "dict" is the exact name of a file /* ! * Add any identifiers that match the given pattern "pat" in the list of ! * dictionary files "dict_start" to the list of completions. */ static void ins_compl_dictionaries( *************** *** 1346,1351 **** --- 1350,1415 ---- 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 ins_compl_files( int count, *************** *** 1392,1432 **** p_ic, files[i], *dir, FALSE); if (thesaurus) { ! char_u *wstart; ! ! // Add the other matches on 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. ! 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 dir was BACKWARD then honor it just once --- 1456,1465 ---- p_ic, files[i], *dir, FALSE); if (thesaurus) { ! // For a thesaurus, add all the words in the line ptr = buf; ! add_r = thesarurs_add_words_in_line(files[i], &ptr, *dir, ! regmatch->startp[0]); } if (add_r == OK) // if dir was BACKWARD then honor it just once *************** *** 1649,1663 **** vim_free(compl_leader); compl_leader = vim_strnsave(line + compl_col, (p - line) - compl_col); ! if (compl_leader != NULL) ! { ! 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; ! } ! return K_BS; } /* --- 1682,1695 ---- vim_free(compl_leader); compl_leader = vim_strnsave(line + compl_col, (p - line) - compl_col); ! if (compl_leader == NULL) ! return K_BS; ! ! 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; } /* *************** *** 2795,2800 **** --- 2827,2836 ---- 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() { *************** *** 4853,4858 **** --- 4889,4897 ---- return OK; } + /* + * Remove (if needed) and show the popup menu + */ static void show_pum(int prev_w_wrow, int prev_w_leftcol) { *** ../vim-8.2.3988/src/testdir/test_edit.vim 2021-12-26 10:51:33.711079465 +0000 --- src/testdir/test_edit.vim 2022-01-03 10:57:35.071793788 +0000 *************** *** 733,740 **** call feedkeys("Ii\\\", "tnix") call feedkeys("ILO\\\", 'tnix') call assert_equal(['INFER', 'loWER', 'infer', 'LOWER', '', ''], getline(1, '$'), e) ! ! set noignorecase noinfercase complete& bw! endfor endfunc --- 733,745 ---- call feedkeys("Ii\\\", "tnix") call feedkeys("ILO\\\", 'tnix') call assert_equal(['INFER', 'loWER', 'infer', 'LOWER', '', ''], getline(1, '$'), e) ! set noignorecase noinfercase ! %d ! call setline(1, ['one word', 'two word']) ! exe "normal! Goo\\\" ! call assert_equal('one word', getline(3)) ! %d ! set complete& bw! endfor endfunc *************** *** 900,905 **** --- 905,927 ---- 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'] + exe 'set encoding=' .. e + new + call setline(1, 'mad') + call cursor(1, 1) + call feedkeys("A\\\\", 'tnix') + call assert_equal(['mad', ''], getline(1, '$')) + bw! + endfor + set thesaurus= + call delete('Xthesaurus') + endfunc + " Test 'thesaurusfunc' func MyThesaurus(findstart, base) let mythesaurus = [ *** ../vim-8.2.3988/src/testdir/test_ins_complete.vim 2021-12-30 11:40:49.936654054 +0000 --- src/testdir/test_ins_complete.vim 2022-01-03 10:57:35.071793788 +0000 *************** *** 709,714 **** --- 709,729 ---- 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\\\=ListColors()\\" + 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 *************** *** 932,937 **** --- 947,1037 ---- 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'] + 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\" + 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\\\" + 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\\\3\" + 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\\\" + call assert_equal('a line2', getline(1)) + %d + " completing from an unlisted buffer should fail + bdel Xfile1 + exe "normal! ia\\\" + 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\\\" + call assert_equal('a', getline(1)) + %d + bdel Xfile1 + exe "normal! ia\\\" + 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\\\\\" + call assert_equal('abė', getline(2)) + " Test for a leader with multibyte character + %d + call setline(1, 'abėĕ') + exe "normal! oabė\" + 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 *** ../vim-8.2.3988/src/version.c 2022-01-02 21:46:25.313652743 +0000 --- src/version.c 2022-01-03 11:01:06.183196311 +0000 *************** *** 752,753 **** --- 752,755 ---- { /* Add new patch number below this line */ + /**/ + 3989, /**/ -- hundred-and-one symptoms of being an internet addict: 199. You read this entire list of symptoms, looking for something that doesn't describe you. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// \\\ \\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///