# HG changeset patch # User Christian Brabandt # Date 1476544505 -7200 # Node ID 154d5a2e7395c08ca4cea9b71e38ed5ca0476386 # Parent ac8a45a5cb0c2bc1526654db5479b1fae33b38d0 commit https://github.com/vim/vim/commit/472e85970ee3a80abd824bef510df12e9cfe9e96 Author: Bram Moolenaar Date: Sat Oct 15 17:06:47 2016 +0200 patch 8.0.0035 Problem: Order of matches for 'omnifunc' is messed up. (Danny Su) Solution: Do not set compl_curr_match when called from complete_check(). (closes https://github.com/vim/vim/issues/1168) diff --git a/src/Makefile b/src/Makefile --- a/src/Makefile +++ b/src/Makefile @@ -2047,7 +2047,7 @@ test1 \ test40 test41 test42 test43 test44 test45 test48 test49 \ test50 test51 test52 test53 test54 test55 test56 test57 test58 test59 \ test60 test64 test65 test66 test67 test68 test69 \ - test70 test72 test73 test74 test75 test76 test77 test78 test79 \ + test70 test72 test73 test74 test75 test77 test78 test79 \ test80 test82 test83 test84 test85 test86 test87 test88 test89 \ test90 test91 test92 test93 test94 test95 test97 test98 test99 \ test100 test101 test103 test104 test107 test108: diff --git a/src/edit.c b/src/edit.c --- a/src/edit.c +++ b/src/edit.c @@ -179,8 +179,8 @@ static void ins_compl_add_dict(dict_T *d #endif static int ins_compl_get_exp(pos_T *ini); static void ins_compl_delete(void); -static void ins_compl_insert(void); -static int ins_compl_next(int allow_get_expansion, int count, int insert_match); +static void ins_compl_insert(int in_compl_func); +static int ins_compl_next(int allow_get_expansion, int count, int insert_match, int in_compl_func); static int ins_compl_key2dir(int c); static int ins_compl_pum_key(int c); static int ins_compl_key2count(int c); @@ -861,7 +861,7 @@ edit( && (c == CAR || c == K_KENTER || c == NL))) { ins_compl_delete(); - ins_compl_insert(); + ins_compl_insert(FALSE); } } } @@ -3297,7 +3297,7 @@ ins_compl_files( break; } line_breakcheck(); - ins_compl_check_keys(50); + ins_compl_check_keys(50, FALSE); } fclose(fp); } @@ -4036,8 +4036,6 @@ ins_compl_next_buf(buf_T *buf, int flag) } #ifdef FEAT_COMPL_FUNC -static void expand_by_function(int type, char_u *base); - /* * Execute user defined complete function 'completefunc' or 'omnifunc', and * get matches in "matches". @@ -4596,7 +4594,7 @@ 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 ((ctrl_x_mode != 0 && !CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode)) || compl_interrupted) @@ -4653,9 +4651,12 @@ ins_compl_delete(void) set_vim_var_dict(VV_COMPLETED_ITEM, dict_alloc()); } -/* Insert the new text being completed. */ +/* + * Insert the new text being completed. + * "in_compl_func" is TRUE when called from complete_check(). + */ static void -ins_compl_insert(void) +ins_compl_insert(int in_compl_func) { dict_T *dict; @@ -4682,7 +4683,8 @@ ins_compl_insert(void) 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; } /* @@ -4706,7 +4708,8 @@ 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 insert_match, /* Insert the newly selected match */ + int in_compl_func) /* called from complete_check() */ { int num_matches = -1; int i; @@ -4856,7 +4859,7 @@ ins_compl_next( 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()); } @@ -4921,9 +4924,11 @@ ins_compl_next( * 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) +ins_compl_check_keys(int frequency, int in_compl_func) { static int count = 0; @@ -4949,7 +4954,7 @@ ins_compl_check_keys(int frequency) 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); + c != K_UP && c != K_DOWN, in_compl_func); } else { @@ -4972,7 +4977,7 @@ 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); } } @@ -5490,7 +5495,8 @@ ins_complete(int c, int enable_pum) * Find next match (and following matches). */ save_w_wrow = curwin->w_wrow; - n = ins_compl_next(TRUE, ins_compl_key2count(c), ins_compl_use_match(c)); + n = ins_compl_next(TRUE, ins_compl_key2count(c), + ins_compl_use_match(c), FALSE); /* may undisplay the popup menu */ ins_compl_upd_pum(); diff --git a/src/evalfunc.c b/src/evalfunc.c --- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -2175,7 +2175,7 @@ f_complete_check(typval_T *argvars UNUSE 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/proto/edit.pro b/src/proto/edit.pro --- a/src/proto/edit.pro +++ b/src/proto/edit.pro @@ -15,7 +15,7 @@ char_u *find_word_start(char_u *ptr); char_u *find_word_end(char_u *ptr); int ins_compl_active(void); int ins_compl_add_tv(typval_T *tv, int dir); -void ins_compl_check_keys(int frequency); +void ins_compl_check_keys(int frequency, int in_compl_func); int get_literal(void); void insertchar(int c, int flags, int second_indent); void auto_format(int trailblank, int prev_line); diff --git a/src/search.c b/src/search.c --- a/src/search.c +++ b/src/search.c @@ -5429,7 +5429,7 @@ exit_matched: line_breakcheck(); #ifdef FEAT_INS_EXPAND if (action == ACTION_EXPAND) - ins_compl_check_keys(30); + ins_compl_check_keys(30, FALSE); if (got_int || compl_interrupted) #else if (got_int) diff --git a/src/spell.c b/src/spell.c --- a/src/spell.c +++ b/src/spell.c @@ -8694,7 +8694,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 { diff --git a/src/tag.c b/src/tag.c --- a/src/tag.c +++ b/src/tag.c @@ -1587,7 +1587,7 @@ find_tags( fast_breakcheck(); #ifdef FEAT_INS_EXPAND 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) #else if (got_int) diff --git a/src/testdir/Make_all.mak b/src/testdir/Make_all.mak --- a/src/testdir/Make_all.mak +++ b/src/testdir/Make_all.mak @@ -55,7 +55,6 @@ SCRIPTS_ALL = \ test70.out \ test73.out \ test75.out \ - test76.out \ test77.out \ test79.out \ test80.out \ diff --git a/src/testdir/test76.in b/src/testdir/test76.in deleted file mode 100644 --- a/src/testdir/test76.in +++ /dev/null @@ -1,46 +0,0 @@ -Tests for completefunc/omnifunc. vim: set ft=vim : - -STARTTEST -:"Test that nothing happens if the 'completefunc' opens -:"a new window (no completion, no crash) -:so small.vim -:function! DummyCompleteOne(findstart, base) -: if a:findstart -: return 0 -: else -: wincmd n -: return ['onedef', 'oneDEF'] -: endif -:endfunction -:setlocal completefunc=DummyCompleteOne -/^one -A:q! -:function! DummyCompleteTwo(findstart, base) -: if a:findstart -: wincmd n -: return 0 -: else -: return ['twodef', 'twoDEF'] -: endif -:endfunction -:setlocal completefunc=DummyCompleteTwo -/^two -A:q! -:"Test that 'completefunc' works when it's OK. -:function! DummyCompleteThree(findstart, base) -: if a:findstart -: return 0 -: else -: return ['threedef', 'threeDEF'] -: endif -:endfunction -:setlocal completefunc=DummyCompleteThree -/^three -A:/^+++/,/^three/w! test.out -:qa! -ENDTEST - -+++ -one -two -three diff --git a/src/testdir/test76.ok b/src/testdir/test76.ok deleted file mode 100644 --- a/src/testdir/test76.ok +++ /dev/null @@ -1,4 +0,0 @@ -+++ - -two -threeDEF diff --git a/src/testdir/test_popup.vim b/src/testdir/test_popup.vim --- a/src/testdir/test_popup.vim +++ b/src/testdir/test_popup.vim @@ -289,4 +289,115 @@ func Test_compl_vim_cmds_after_register_ bwipe! 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\\\\", "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\\\\", "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\\\\", "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\\\\", "x") + call assert_equal('four2', getline(1)) + + call setline(1, 'four') + /^four + call feedkeys("A\\\\\", "x") + call assert_equal('four3', getline(1)) + + call setline(1, 'four') + /^four + call feedkeys("A\\\\\\\", "x") + call assert_equal('four5', getline(1)) + + q! +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -765,6 +765,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 35, +/**/ 34, /**/ 33,