Patch 8.2.0614

10 views
Skip to first unread message

Bram Moolenaar

unread,
Apr 21, 2020, 4:02:03 PM4/21/20
to vim...@googlegroups.com

Patch 8.2.0614
Problem: Get ml_get error when deleting a line in 'completefunc'. (Yegappan
Lakshmanan)
Solution: Lock the text while evaluating 'completefunc'.
Files: src/insexpand.c, src/globals.h, src/edit.c, src/ex_getln.c,
src/undo.c, src/testdir/test_edit.vim, src/testdir/test_excmd.vim,
src/testdir/test_gf.vim, src/testdir/test_popup.vim,
src/testdir/test_ex_mode.vim, runtime/doc/insert.txt


*** ../vim-8.2.0613/src/insexpand.c 2020-04-12 19:37:13.514297270 +0200
--- src/insexpand.c 2020-04-21 21:54:18.321792952 +0200
***************
*** 2217,2222 ****
--- 2217,2224 ----
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,2244 ****
--- 2241,2247 ----
break;
}
}
+ --textlock;

if (curwin_save != curwin || curbuf_save != curbuf)
{
***************
*** 2431,2436 ****
--- 2434,2440 ----
f_complete(typval_T *argvars, typval_T *rettv UNUSED)
{
int startcol;
+ int save_textlock = textlock;

if ((State & INSERT) == 0)
{
***************
*** 2438,2459 ****
return;
}

// 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;
}
!
! startcol = (int)tv_get_number_chk(&argvars[0], NULL);
! if (startcol <= 0)
! return;
!
! set_completion(startcol - 1, argvars[1].vval.v_list);
}

/*
--- 2442,2465 ----
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));
! else
! {
! startcol = (int)tv_get_number_chk(&argvars[0], NULL);
! if (startcol > 0)
! set_completion(startcol - 1, argvars[1].vval.v_list);
}
! textlock = save_textlock;
}

/*
*** ../vim-8.2.0613/src/globals.h 2020-04-19 17:24:48.665264342 +0200
--- src/globals.h 2020-04-21 20:41:50.964300235 +0200
***************
*** 1678,1686 ****
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"));
#endif
! EXTERN char e_secure[] INIT(= N_("E523: Not allowed 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"));
--- 1678,1687 ----
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"));
#endif
! 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"));
*** ../vim-8.2.0613/src/edit.c 2020-04-17 19:41:16.100078313 +0200
--- src/edit.c 2020-04-21 20:52:09.233681112 +0200
***************
*** 175,190 ****
#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())
{
! emsg(_(e_secure));
return FALSE;
}
ins_compl_clear(); // clear stuff for CTRL-X mode
--- 175,184 ----
#endif
// Don't allow changes in the buffer while editing the cmdline. The
// caller of getcmdline() may get confused.
// Don't allow recursive insert mode when busy with completion.
! if (textlock != 0 || ins_compl_active() || compl_busy || pum_visible())
{
! emsg(_(e_textlock));
return FALSE;
}
ins_compl_clear(); // clear stuff for CTRL-X mode
*** ../vim-8.2.0613/src/ex_getln.c 2020-04-14 20:15:45.284566193 +0200
--- src/ex_getln.c 2020-04-21 20:51:33.569810886 +0200
***************
*** 2576,2582 ****
if (cmdwin_type != 0)
return e_cmdwin;
#endif
! return e_secure;
}

/*
--- 2576,2582 ----
if (cmdwin_type != 0)
return e_cmdwin;
#endif
! return e_textlock;
}

/*
*** ../vim-8.2.0613/src/undo.c 2020-04-12 19:37:13.526297236 +0200
--- src/undo.c 2020-04-21 20:53:06.141477432 +0200
***************
*** 333,339 ****
// caller of getcmdline() may get confused.
if (textlock != 0)
{
! emsg(_(e_secure));
return FALSE;
}

--- 333,339 ----
// caller of getcmdline() may get confused.
if (textlock != 0)
{
! emsg(_(e_textlock));
return FALSE;
}

*** ../vim-8.2.0613/src/testdir/test_edit.vim 2020-03-30 19:30:07.129542925 +0200
--- src/testdir/test_edit.vim 2020-04-21 20:57:02.780666855 +0200
***************
*** 915,920 ****
--- 915,937 ----
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,1246 ****
try
call feedkeys("ix\<esc>", 'tnix')
call assert_fails(1, 'textlock')
! catch /^Vim\%((\a\+)\)\=:E523/ " catch E523: not allowed here
endtry
" TODO: Might be a bug: should x really be inserted here
call assert_equal(['xa'], getline(1, '$'))
--- 1257,1263 ----
try
call feedkeys("ix\<esc>", 'tnix')
call assert_fails(1, 'textlock')
! 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,1270 ****
try
call feedkeys("i\<c-x>\<c-u>\<esc>", 'tnix')
call assert_fails(1, 'change in complete function')
! catch /^Vim\%((\a\+)\)\=:E523/ " catch E523
endtry
delfu Complete
set completefunc=
--- 1281,1287 ----
try
call feedkeys("i\<c-x>\<c-u>\<esc>", 'tnix')
call assert_fails(1, 'change in complete function')
! catch /^Vim\%((\a\+)\)\=:E565/ " catch E565
endtry
delfu Complete
set completefunc=
*** ../vim-8.2.0613/src/testdir/test_excmd.vim 2020-03-30 19:30:07.129542925 +0200
--- src/testdir/test_excmd.vim 2020-04-21 21:37:41.425277149 +0200
***************
*** 354,368 ****
func Test_run_excmd_with_text_locked()
" :quit
let cmd = ":\<C-\>eexecute('quit')\<CR>\<C-C>"
! call assert_fails("call feedkeys(cmd, 'xt')", 'E523:')

" :qall
let cmd = ":\<C-\>eexecute('qall')\<CR>\<C-C>"
! call assert_fails("call feedkeys(cmd, 'xt')", 'E523:')

" :exit
let cmd = ":\<C-\>eexecute('exit')\<CR>\<C-C>"
! call assert_fails("call feedkeys(cmd, 'xt')", 'E523:')

" :close - should be ignored
new
--- 354,368 ----
func Test_run_excmd_with_text_locked()
" :quit
let cmd = ":\<C-\>eexecute('quit')\<CR>\<C-C>"
! call assert_fails("call feedkeys(cmd, 'xt')", 'E565:')

" :qall
let cmd = ":\<C-\>eexecute('qall')\<CR>\<C-C>"
! call assert_fails("call feedkeys(cmd, 'xt')", 'E565:')

" :exit
let cmd = ":\<C-\>eexecute('exit')\<CR>\<C-C>"
! call assert_fails("call feedkeys(cmd, 'xt')", 'E565:')

" :close - should be ignored
new
***************
*** 370,376 ****
call assert_equal(2, winnr('$'))
close

! call assert_fails("call feedkeys(\":\<C-R>=execute('bnext')\<CR>\", 'xt')", 'E523:')
endfunc

" Test for the :verbose command
--- 370,376 ----
call assert_equal(2, winnr('$'))
close

! call assert_fails("call feedkeys(\":\<C-R>=execute('bnext')\<CR>\", 'xt')", 'E565:')
endfunc

" Test for the :verbose command
*** ../vim-8.2.0613/src/testdir/test_gf.vim 2020-03-10 07:48:06.571619551 +0100
--- src/testdir/test_gf.vim 2020-04-21 21:38:25.129147979 +0200
***************
*** 134,146 ****

" gf is not allowed when text is locked
au InsertCharPre <buffer> normal! gF<CR>
! let caught_e523 = 0
try
call feedkeys("ix\<esc>", 'xt')
! catch /^Vim\%((\a\+)\)\=:E523/ " catch E523
! let caught_e523 = 1
endtry
! call assert_equal(1, caught_e523)
au! InsertCharPre

bwipe!
--- 134,146 ----

" gf is not allowed when text is locked
au InsertCharPre <buffer> normal! gF<CR>
! let caught_e565 = 0
try
call feedkeys("ix\<esc>", 'xt')
! catch /^Vim\%((\a\+)\)\=:E565/ " catch E565
! let caught_e565 = 1
endtry
! call assert_equal(1, caught_e565)
au! InsertCharPre

bwipe!
*** ../vim-8.2.0613/src/testdir/test_popup.vim 2020-04-08 21:50:18.876619651 +0200
--- src/testdir/test_popup.vim 2020-04-21 21:50:45.361744692 +0200
***************
*** 334,352 ****
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

--- 334,350 ----
endif
endfunc

! " 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")', 'E565:')
call assert_equal(winid, win_getid())
! call assert_equal('oneDEF', getline(1))
q!
endfunc

*** ../vim-8.2.0613/src/testdir/test_ex_mode.vim 2020-04-04 14:00:34.197098267 +0200
--- src/testdir/test_ex_mode.vim 2020-04-21 21:40:08.736841926 +0200
***************
*** 158,170 ****
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
try
call feedkeys("ix\<esc>", 'xt')
! catch /^Vim\%((\a\+)\)\=:E523/ " catch E523
! let caught_e523 = 1
endtry
! call assert_equal(1, caught_e523)
au! InsertCharPre
endfunc

--- 158,170 ----
func Test_ex_mode_errors()
" Not allowed to enter ex mode when text is locked
au InsertCharPre <buffer> normal! gQ<CR>
! let caught_e565 = 0
try
call feedkeys("ix\<esc>", 'xt')
! catch /^Vim\%((\a\+)\)\=:E565/ " catch E565
! let caught_e565 = 1
endtry
! call assert_equal(1, caught_e565)
au! InsertCharPre
endfunc

*** ../vim-8.2.0613/runtime/doc/insert.txt 2020-01-04 14:32:35.522717984 +0100
--- runtime/doc/insert.txt 2020-04-21 20:45:07.579358745 +0200
***************
*** 658,665 ****
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.

The following mappings are suggested to make typing the completion commands
a bit easier (although they will hide other commands): >
--- 666,675 ----
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.

! *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): >
*** ../vim-8.2.0613/src/version.c 2020-04-20 22:42:28.232964333 +0200
--- src/version.c 2020-04-21 21:58:20.605666005 +0200
***************
*** 748,749 ****
--- 748,751 ----
{ /* Add new patch number below this line */
+ /**/
+ 614,
/**/

--
No engineer can take a shower without wondering if some sort of Teflon coating
would make showering unnecessary.
(Scott Adams - The Dilbert principle)

/// Bram Moolenaar -- Br...@Moolenaar.net -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
Reply all
Reply to author
Forward
0 new messages