diff options
-rw-r--r-- | runtime/doc/insert.txt | 6 | ||||
-rw-r--r-- | src/edit.c | 10 | ||||
-rw-r--r-- | src/ex_getln.c | 2 | ||||
-rw-r--r-- | src/globals.h | 5 | ||||
-rw-r--r-- | src/insexpand.c | 22 | ||||
-rw-r--r-- | src/testdir/test_edit.vim | 21 | ||||
-rw-r--r-- | src/testdir/test_ex_mode.vim | 8 | ||||
-rw-r--r-- | src/testdir/test_excmd.vim | 8 | ||||
-rw-r--r-- | src/testdir/test_gf.vim | 8 | ||||
-rw-r--r-- | src/testdir/test_popup.vim | 10 | ||||
-rw-r--r-- | src/undo.c | 2 | ||||
-rw-r--r-- | src/version.c | 2 |
12 files changed, 62 insertions, 42 deletions
diff --git a/runtime/doc/insert.txt b/runtime/doc/insert.txt index 99c2d40e7..ff74d625f 100644 --- a/runtime/doc/insert.txt +++ b/runtime/doc/insert.txt @@ -666,8 +666,10 @@ Note: The keys that are valid in CTRL-X mode are not mapped. This allows for ends CTRL-X mode (any key that is not a valid CTRL-X mode command) is mapped. Also, when doing completion with 'complete' mappings apply as usual. -Note: While completion is active Insert mode can't be used recursively. -Mappings that somehow invoke ":normal i.." will generate an E523 error. + *E565* +Note: While completion is active Insert mode can't be used recursively and +buffer text cannot be changed. Mappings that somehow invoke ":normal i.." +will generate an E565 error. The following mappings are suggested to make typing the completion commands a bit easier (although they will hide other commands): > diff --git a/src/edit.c b/src/edit.c index 3f0803f68..05518ceab 100644 --- a/src/edit.c +++ b/src/edit.c @@ -175,16 +175,10 @@ edit( #endif // Don't allow changes in the buffer while editing the cmdline. The // caller of getcmdline() may get confused. - if (textlock != 0) - { - emsg(_(e_secure)); - return FALSE; - } - // Don't allow recursive insert mode when busy with completion. - if (ins_compl_active() || compl_busy || pum_visible()) + if (textlock != 0 || ins_compl_active() || compl_busy || pum_visible()) { - emsg(_(e_secure)); + emsg(_(e_textlock)); return FALSE; } ins_compl_clear(); // clear stuff for CTRL-X mode diff --git a/src/ex_getln.c b/src/ex_getln.c index 9b959fbad..18da92656 100644 --- a/src/ex_getln.c +++ b/src/ex_getln.c @@ -2576,7 +2576,7 @@ get_text_locked_msg(void) if (cmdwin_type != 0) return e_cmdwin; #endif - return e_secure; + return e_textlock; } /* diff --git a/src/globals.h b/src/globals.h index 4822bf373..f6c9d60e2 100644 --- a/src/globals.h +++ b/src/globals.h @@ -1678,9 +1678,10 @@ EXTERN char e_letunexp[] INIT(= N_("E18: Unexpected characters in :let")); EXTERN char e_readerrf[] INIT(= N_("E47: Error while reading errorfile")); #endif #ifdef HAVE_SANDBOX -EXTERN char e_sandbox[] INIT(= N_("E48: Not allowed in sandbox")); +EXTERN char e_sandbox[] INIT(= N_("E48: Not allowed in sandbox")); #endif -EXTERN char e_secure[] INIT(= N_("E523: Not allowed here")); +EXTERN char e_secure[] INIT(= N_("E523: Not allowed here")); +EXTERN char e_textlock[] INIT(= N_("E565: Not allowed to change text here")); #if defined(AMIGA) || defined(MACOS_X) || defined(MSWIN) \ || defined(UNIX) || defined(VMS) EXTERN char e_screenmode[] INIT(= N_("E359: Screen mode setting not supported")); diff --git a/src/insexpand.c b/src/insexpand.c index 027852268..48ab260a7 100644 --- a/src/insexpand.c +++ b/src/insexpand.c @@ -2217,6 +2217,8 @@ expand_by_function( pos = curwin->w_cursor; curwin_save = curwin; curbuf_save = curbuf; + // Lock the text to avoid weird things from happening. + ++textlock; // Call a function, which returns a list or dict. if (call_vim_function(funcname, 2, args, &rettv) == OK) @@ -2239,6 +2241,7 @@ expand_by_function( break; } } + --textlock; if (curwin_save != curwin || curbuf_save != curbuf) { @@ -2431,6 +2434,7 @@ set_completion(colnr_T startcol, list_T *list) f_complete(typval_T *argvars, typval_T *rettv UNUSED) { int startcol; + int save_textlock = textlock; if ((State & INSERT) == 0) { @@ -2438,22 +2442,24 @@ f_complete(typval_T *argvars, typval_T *rettv UNUSED) return; } + // "textlock" is set when evaluating 'completefunc' but we can change text + // here. + textlock = 0; + // Check for undo allowed here, because if something was already inserted // the line was already saved for undo and this check isn't done. if (!undo_allowed()) return; if (argvars[1].v_type != VAR_LIST || argvars[1].vval.v_list == NULL) - { emsg(_(e_invarg)); - return; + else + { + startcol = (int)tv_get_number_chk(&argvars[0], NULL); + if (startcol > 0) + set_completion(startcol - 1, argvars[1].vval.v_list); } - - startcol = (int)tv_get_number_chk(&argvars[0], NULL); - if (startcol <= 0) - return; - - set_completion(startcol - 1, argvars[1].vval.v_list); + textlock = save_textlock; } /* diff --git a/src/testdir/test_edit.vim b/src/testdir/test_edit.vim index 9096fcdeb..ce55f6be0 100644 --- a/src/testdir/test_edit.vim +++ b/src/testdir/test_edit.vim @@ -915,6 +915,23 @@ func Test_edit_CTRL_U() bw! endfunc +func Test_edit_completefunc_delete() + func CompleteFunc(findstart, base) + if a:findstart == 1 + return col('.') - 1 + endif + normal dd + return ['a', 'b'] + endfunc + new + set completefunc=CompleteFunc + call setline(1, ['', 'abcd', '']) + 2d + call assert_fails("normal 2G$a\<C-X>\<C-U>", 'E565:') + bwipe! +endfunc + + func Test_edit_CTRL_Z() " Ctrl-Z when insertmode is not set inserts it literally new @@ -1240,7 +1257,7 @@ func Test_edit_forbidden() try call feedkeys("ix\<esc>", 'tnix') call assert_fails(1, 'textlock') - catch /^Vim\%((\a\+)\)\=:E523/ " catch E523: not allowed here + catch /^Vim\%((\a\+)\)\=:E565/ " catch E565: not allowed here endtry " TODO: Might be a bug: should x really be inserted here call assert_equal(['xa'], getline(1, '$')) @@ -1264,7 +1281,7 @@ func Test_edit_forbidden() try call feedkeys("i\<c-x>\<c-u>\<esc>", 'tnix') call assert_fails(1, 'change in complete function') - catch /^Vim\%((\a\+)\)\=:E523/ " catch E523 + catch /^Vim\%((\a\+)\)\=:E565/ " catch E565 endtry delfu Complete set completefunc= diff --git a/src/testdir/test_ex_mode.vim b/src/testdir/test_ex_mode.vim index 9f66e3f01..d23e0ad93 100644 --- a/src/testdir/test_ex_mode.vim +++ b/src/testdir/test_ex_mode.vim @@ -158,13 +158,13 @@ endfunc func Test_ex_mode_errors() " Not allowed to enter ex mode when text is locked au InsertCharPre <buffer> normal! gQ<CR> - let caught_e523 = 0 + let caught_e565 = 0 try call feedkeys("ix\<esc>", 'xt') - catch /^Vim\%((\a\+)\)\=:E523/ " catch E523 - let caught_e523 = 1 + catch /^Vim\%((\a\+)\)\=:E565/ " catch E565 + let caught_e565 = 1 endtry - call assert_equal(1, caught_e523) + call assert_equal(1, caught_e565) au! InsertCharPre endfunc diff --git a/src/testdir/test_excmd.vim b/src/testdir/test_excmd.vim index 9369c1b90..868ac6fc4 100644 --- a/src/testdir/test_excmd.vim +++ b/src/testdir/test_excmd.vim @@ -354,15 +354,15 @@ endfunc func Test_run_excmd_with_text_locked() " :quit let cmd = ":\<C-\>eexecute('quit')\<CR>\<C-C>" - call assert_fails("call feedkeys(cmd, 'xt')", 'E523:') + call assert_fails("call feedkeys(cmd, 'xt')", 'E565:') " :qall let cmd = ":\<C-\>eexecute('qall')\<CR>\<C-C>" - call assert_fails("call feedkeys(cmd, 'xt')", 'E523:') + call assert_fails("call feedkeys(cmd, 'xt')", 'E565:') " :exit let cmd = ":\<C-\>eexecute('exit')\<CR>\<C-C>" - call assert_fails("call feedkeys(cmd, 'xt')", 'E523:') + call assert_fails("call feedkeys(cmd, 'xt')", 'E565:') " :close - should be ignored new @@ -370,7 +370,7 @@ func Test_run_excmd_with_text_locked() call assert_equal(2, winnr('$')) close - call assert_fails("call feedkeys(\":\<C-R>=execute('bnext')\<CR>\", 'xt')", 'E523:') + call assert_fails("call feedkeys(\":\<C-R>=execute('bnext')\<CR>\", 'xt')", 'E565:') endfunc " Test for the :verbose command diff --git a/src/testdir/test_gf.vim b/src/testdir/test_gf.vim index 829b7c299..736a31579 100644 --- a/src/testdir/test_gf.vim +++ b/src/testdir/test_gf.vim @@ -134,13 +134,13 @@ func Test_gf_error() " gf is not allowed when text is locked au InsertCharPre <buffer> normal! gF<CR> - let caught_e523 = 0 + let caught_e565 = 0 try call feedkeys("ix\<esc>", 'xt') - catch /^Vim\%((\a\+)\)\=:E523/ " catch E523 - let caught_e523 = 1 + catch /^Vim\%((\a\+)\)\=:E565/ " catch E565 + let caught_e565 = 1 endtry - call assert_equal(1, caught_e523) + call assert_equal(1, caught_e565) au! InsertCharPre bwipe! diff --git a/src/testdir/test_popup.vim b/src/testdir/test_popup.vim index e96d5fda5..9890377ea 100644 --- a/src/testdir/test_popup.vim +++ b/src/testdir/test_popup.vim @@ -334,19 +334,17 @@ func DummyCompleteOne(findstart, base) endif endfunc -" Test that nothing happens if the 'completefunc' opens -" a new window (no completion, no crash) +" Test that nothing happens if the 'completefunc' tries to open +" a new window (fails to open window, continues) 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_fails('call feedkeys("A\<C-X>\<C-U>\<C-N>\<Esc>", "x")', 'E565:') call assert_equal(winid, win_getid()) - call assert_equal('', getline(1)) + call assert_equal('oneDEF', getline(1)) q! endfunc diff --git a/src/undo.c b/src/undo.c index c5ce306ca..c11b048a2 100644 --- a/src/undo.c +++ b/src/undo.c @@ -333,7 +333,7 @@ undo_allowed(void) // caller of getcmdline() may get confused. if (textlock != 0) { - emsg(_(e_secure)); + emsg(_(e_textlock)); return FALSE; } diff --git a/src/version.c b/src/version.c index 9b00c49d9..cb846f08d 100644 --- a/src/version.c +++ b/src/version.c @@ -747,6 +747,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 614, +/**/ 613, /**/ 612, |