diff options
author | Shougo <Shougo.Matsu@gmail.com> | 2016-11-16 01:59:55 +0900 |
---|---|---|
committer | Justin M. Keyes <justinkz@gmail.com> | 2016-11-15 17:59:55 +0100 |
commit | c69cfd7d1c12fa895961289c7b2fcbeccff5a739 (patch) | |
tree | 80274c8d7b89d488cd75f8a6d3db49a2fc2938ec | |
parent | 10c72cd3658e17aafa41b5752c23d97df88fc71f (diff) | |
download | rneovim-c69cfd7d1c12fa895961289c7b2fcbeccff5a739.tar.gz rneovim-c69cfd7d1c12fa895961289c7b2fcbeccff5a739.tar.bz2 rneovim-c69cfd7d1c12fa895961289c7b2fcbeccff5a739.zip |
vim-patch:8.0.0035 (#5609)
Problem: Order of matches for 'omnifunc' is messed up. (Danny Su)
Solution: Do not set compl_curr_match when called from complete_check().
(closes vim/vim#1168)
https://github.com/vim/vim/commit/472e85970ee3a80abd824bef510df12e9cfe9e96
-rw-r--r-- | src/nvim/edit.c | 48 | ||||
-rw-r--r-- | src/nvim/eval.c | 2 | ||||
-rw-r--r-- | src/nvim/search.c | 2 | ||||
-rw-r--r-- | src/nvim/spell.c | 2 | ||||
-rw-r--r-- | src/nvim/tag.c | 2 | ||||
-rw-r--r-- | src/nvim/testdir/test_popup.vim | 113 | ||||
-rw-r--r-- | test/functional/legacy/076_completefunc_spec.lua | 68 |
7 files changed, 143 insertions, 94 deletions
diff --git a/src/nvim/edit.c b/src/nvim/edit.c index 24744f1437..dcb772e23c 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -669,7 +669,7 @@ static int insert_execute(VimState *state, int key) && (s->c == CAR || s->c == K_KENTER || s->c == NL))) && stop_arrow() == OK) { ins_compl_delete(); - ins_compl_insert(); + ins_compl_insert(false); } } } @@ -2775,7 +2775,7 @@ static void ins_compl_files(int count, char_u **files, int thesaurus, int flags, break; } line_breakcheck(); - ins_compl_check_keys(50); + ins_compl_check_keys(50, false); } fclose(fp); } @@ -3907,7 +3907,7 @@ static int ins_compl_get_exp(pos_T *ini) break; /* Fill the popup menu as soon as possible. */ if (type != -1) - ins_compl_check_keys(0); + ins_compl_check_keys(0, false); if ((l_ctrl_x_mode != 0 && !CTRL_X_MODE_LINE_OR_EVAL(l_ctrl_x_mode)) || compl_interrupted) { @@ -3969,8 +3969,9 @@ static void ins_compl_delete(void) set_vim_var_dict(VV_COMPLETED_ITEM, dict_alloc()); } -/* Insert the new text being completed. */ -static void ins_compl_insert(void) +// Insert the new text being completed. +// "in_compl_func" is TRUE when called from complete_check(). +static void ins_compl_insert(int in_compl_func) { ins_bytes(compl_shown_match->cp_str + ins_compl_len()); if (compl_shown_match->cp_flags & ORIGINAL_TEXT) @@ -3992,7 +3993,9 @@ static void ins_compl_insert(void) dict_add_nr_str(dict, "info", 0L, EMPTY_IF_NULL(compl_shown_match->cp_text[CPT_INFO])); set_vim_var_dict(VV_COMPLETED_ITEM, dict); - compl_curr_match = compl_shown_match; + if (!in_compl_func) { + compl_curr_match = compl_shown_match; + } } /* @@ -4014,9 +4017,10 @@ static void ins_compl_insert(void) static int ins_compl_next ( int allow_get_expansion, - int count, /* repeat completion this many times; should - be at least 1 */ - int insert_match /* Insert the newly selected match */ + int count, // Repeat completion this many times; should + // be at least 1 + int insert_match, // Insert the newly selected match + int in_compl_func // Called from complete_check() ) { int num_matches = -1; @@ -4146,7 +4150,7 @@ ins_compl_next ( compl_used_match = FALSE; } else if (insert_match) { if (!compl_get_longest || compl_used_match) { - ins_compl_insert(); + ins_compl_insert(in_compl_func); } else { ins_bytes(compl_leader + ins_compl_len()); } @@ -4196,14 +4200,14 @@ ins_compl_next ( return num_matches; } -/* - * Call this while finding completions, to check whether the user has hit a key - * that should change the currently displayed completion, or exit completion - * mode. Also, when compl_pending is not zero, show a completion as soon as - * possible. -- webb - * "frequency" specifies out of how many calls we actually check. - */ -void ins_compl_check_keys(int frequency) +// Call this while finding completions, to check whether the user has hit a key +// that should change the currently displayed completion, or exit completion +// mode. Also, when compl_pending is not zero, show a completion as soon as +// possible. -- webb +// "frequency" specifies out of how many calls we actually check. +// "in_compl_func" is TRUE when called from complete_check(), don't set +// compl_curr_match. +void ins_compl_check_keys(int frequency, int in_compl_func) { static int count = 0; @@ -4226,8 +4230,8 @@ void ins_compl_check_keys(int frequency) if (vim_is_ctrl_x_key(c) && c != Ctrl_X && c != Ctrl_R) { c = safe_vgetc(); /* Eat the character */ compl_shows_dir = ins_compl_key2dir(c); - (void)ins_compl_next(FALSE, ins_compl_key2count(c), - c != K_UP && c != K_DOWN); + (void)ins_compl_next(false, ins_compl_key2count(c), + c != K_UP && c != K_DOWN, in_compl_func); } else { /* Need to get the character to have KeyTyped set. We'll put it * back with vungetc() below. But skip K_IGNORE. */ @@ -4246,7 +4250,7 @@ void ins_compl_check_keys(int frequency) int todo = compl_pending > 0 ? compl_pending : -compl_pending; compl_pending = 0; - (void)ins_compl_next(FALSE, todo, TRUE); + (void)ins_compl_next(false, todo, true, in_compl_func); } } @@ -4673,7 +4677,7 @@ static int ins_complete(int c, bool enable_pum) * Find next match (and following matches). */ save_w_wrow = curwin->w_wrow; - n = ins_compl_next(true, ins_compl_key2count(c), insert_match); + n = ins_compl_next(true, ins_compl_key2count(c), insert_match, false); /* may undisplay the popup menu */ ins_compl_upd_pum(); diff --git a/src/nvim/eval.c b/src/nvim/eval.c index b8173c7570..39df4cd024 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -8010,7 +8010,7 @@ static void f_complete_check(typval_T *argvars, typval_T *rettv, FunPtr fptr) int saved = RedrawingDisabled; RedrawingDisabled = 0; - ins_compl_check_keys(0); + ins_compl_check_keys(0, true); rettv->vval.v_number = compl_interrupted; RedrawingDisabled = saved; } diff --git a/src/nvim/search.c b/src/nvim/search.c index 5f4df3be92..1029190db4 100644 --- a/src/nvim/search.c +++ b/src/nvim/search.c @@ -4549,7 +4549,7 @@ exit_matched: } line_breakcheck(); if (action == ACTION_EXPAND) - ins_compl_check_keys(30); + ins_compl_check_keys(30, false); if (got_int || compl_interrupted) break; diff --git a/src/nvim/spell.c b/src/nvim/spell.c index d9cdce8ca4..7119ac6dc1 100644 --- a/src/nvim/spell.c +++ b/src/nvim/spell.c @@ -13160,7 +13160,7 @@ spell_dump_compl ( // Done all bytes at this node, go up one level. --depth; line_breakcheck(); - ins_compl_check_keys(50); + ins_compl_check_keys(50, false); } else { // Do one more byte at this node. n = arridx[depth] + curi[depth]; diff --git a/src/nvim/tag.c b/src/nvim/tag.c index 81256b4f01..46fad688cc 100644 --- a/src/nvim/tag.c +++ b/src/nvim/tag.c @@ -1295,7 +1295,7 @@ find_tags ( for (;; ) { line_breakcheck(); /* check for CTRL-C typed */ if ((flags & TAG_INS_COMP)) /* Double brackets for gcc */ - ins_compl_check_keys(30); + ins_compl_check_keys(30, false); if (got_int || compl_interrupted) { stop_searching = TRUE; break; diff --git a/src/nvim/testdir/test_popup.vim b/src/nvim/testdir/test_popup.vim index 63be8bf609..8615e32cfd 100644 --- a/src/nvim/testdir/test_popup.vim +++ b/src/nvim/testdir/test_popup.vim @@ -63,3 +63,116 @@ func! Test_popup_completion_insertmode() bwipe! iunmap <F5> endfunc + +func DummyCompleteOne(findstart, base) + if a:findstart + return 0 + else + wincmd n + return ['onedef', 'oneDEF'] + endif +endfunc + +" Test that nothing happens if the 'completefunc' opens +" a new window (no completion, no crash) +func Test_completefunc_opens_new_window_one() + new + let winid = win_getid() + setlocal completefunc=DummyCompleteOne + call setline(1, 'one') + /^one + call assert_fails('call feedkeys("A\<C-X>\<C-U>\<C-N>\<Esc>", "x")', 'E839:') + call assert_notequal(winid, win_getid()) + q! + call assert_equal(winid, win_getid()) + call assert_equal('', getline(1)) + q! +endfunc + +" Test that nothing happens if the 'completefunc' opens +" a new window (no completion, no crash) +func DummyCompleteTwo(findstart, base) + if a:findstart + wincmd n + return 0 + else + return ['twodef', 'twoDEF'] + endif +endfunction + +" Test that nothing happens if the 'completefunc' opens +" a new window (no completion, no crash) +func Test_completefunc_opens_new_window_two() + new + let winid = win_getid() + setlocal completefunc=DummyCompleteTwo + call setline(1, 'two') + /^two + call assert_fails('call feedkeys("A\<C-X>\<C-U>\<C-N>\<Esc>", "x")', 'E764:') + call assert_notequal(winid, win_getid()) + q! + call assert_equal(winid, win_getid()) + call assert_equal('two', getline(1)) + q! +endfunc + +func DummyCompleteThree(findstart, base) + if a:findstart + return 0 + else + return ['threedef', 'threeDEF'] + endif +endfunc + +:"Test that 'completefunc' works when it's OK. +func Test_completefunc_works() + new + let winid = win_getid() + setlocal completefunc=DummyCompleteThree + call setline(1, 'three') + /^three + call feedkeys("A\<C-X>\<C-U>\<C-N>\<Esc>", "x") + call assert_equal(winid, win_getid()) + call assert_equal('threeDEF', getline(1)) + q! +endfunc + +func DummyCompleteFour(findstart, base) + if a:findstart + return 0 + else + call complete_add('four1') + call complete_add('four2') + call complete_check() + call complete_add('four3') + call complete_add('four4') + call complete_check() + call complete_add('four5') + call complete_add('four6') + return [] + endif +endfunc + +:"Test that 'completefunc' works when it's OK. +func Test_omnifunc_with_check() + new + setlocal omnifunc=DummyCompleteFour + call setline(1, 'four') + /^four + call feedkeys("A\<C-X>\<C-O>\<C-N>\<Esc>", "x") + call assert_equal('four2', getline(1)) + + call setline(1, 'four') + /^four + call feedkeys("A\<C-X>\<C-O>\<C-N>\<C-N>\<Esc>", "x") + call assert_equal('four3', getline(1)) + + call setline(1, 'four') + /^four + call feedkeys("A\<C-X>\<C-O>\<C-N>\<C-N>\<C-N>\<C-N>\<Esc>", "x") + call assert_equal('four5', getline(1)) + + q! +endfunc + +" vim: shiftwidth=2 sts=2 expandtab diff --git a/test/functional/legacy/076_completefunc_spec.lua b/test/functional/legacy/076_completefunc_spec.lua deleted file mode 100644 index bf3f56eb84..0000000000 --- a/test/functional/legacy/076_completefunc_spec.lua +++ /dev/null @@ -1,68 +0,0 @@ --- Tests for completefunc/omnifunc. - -local helpers = require('test.functional.helpers')(after_each) -local feed, insert, source = helpers.feed, helpers.insert, helpers.source -local clear, expect, execute = helpers.clear, helpers.expect, helpers.execute - -describe('completefunc', function() - setup(clear) - - it('is working', function() - insert([=[ - +++ - one - two - three]=]) - - -- Test that nothing happens if the 'completefunc' opens - -- a new window (no completion, no crash). - source([=[ - function! DummyCompleteOne(findstart, base) - if a:findstart - return 0 - else - wincmd n - return ['onedef', 'oneDEF'] - endif - endfunction - setlocal completefunc=DummyCompleteOne - /^one - ]=]) - feed('A<C-X><C-U><C-N><esc>') - execute('q!') - source([=[ - function! DummyCompleteTwo(findstart, base) - if a:findstart - wincmd n - return 0 - else - return ['twodef', 'twoDEF'] - endif - endfunction - setlocal completefunc=DummyCompleteTwo - /^two - ]=]) - feed('A<C-X><C-U><C-N><esc>') - execute('q!') - -- Test that 'completefunc' works when it's OK. - source([=[ - function! DummyCompleteThree(findstart, base) - if a:findstart - return 0 - else - return ['threedef', 'threeDEF'] - endif - endfunction - setlocal completefunc=DummyCompleteThree - /^three - ]=]) - feed('A<C-X><C-U><C-N><esc>') - - -- Assert buffer contents. - expect([=[ - +++ - - two - threeDEF]=]) - end) -end) |