summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/doc/insert.txt6
-rw-r--r--src/edit.c10
-rw-r--r--src/ex_getln.c2
-rw-r--r--src/globals.h5
-rw-r--r--src/insexpand.c22
-rw-r--r--src/testdir/test_edit.vim21
-rw-r--r--src/testdir/test_ex_mode.vim8
-rw-r--r--src/testdir/test_excmd.vim8
-rw-r--r--src/testdir/test_gf.vim8
-rw-r--r--src/testdir/test_popup.vim10
-rw-r--r--src/undo.c2
-rw-r--r--src/version.c2
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,