Patch 8.1.2341
Problem: Not so easy to interrupt a script programatically.
Solution: Add the interrupt() function. (Yasuhiro Matsumoto, closes #2834)
Files: runtime/doc/eval.txt, src/evalfunc.c, src/ex_eval.c,
src/testdir/Make_all.mak, src/testdir/test_interrupt.vim
*** ../vim-8.1.2340/runtime/doc/eval.txt 2019-11-21 15:36:00.241478816 +0100
--- runtime/doc/eval.txt 2019-11-24 23:59:27.809525813 +0100
***************
*** 2531,2536 ****
--- 2531,2537 ----
inputsave() Number save and clear typeahead
inputsecret({prompt} [, {text}]) String like input() but hiding the text
insert({object}, {item} [, {idx}]) List insert {item} in {object} [before {idx}]
+ interrupt() none interrupt script execution
invert({expr}) Number bitwise invert
isdirectory({directory}) Number |TRUE| if {directory} is a directory
isinf({expr}) Number determine if {expr} is infinity value
***************
*** 6175,6180 ****
--- 6182,6200 ----
Can also be used as a |method|: >
mylist->insert(item)
+ interrupt() *interrupt()*
+ Interrupt script execution. It works more or less like the
+ user typing CTRL-C, most commands won't execute and control
+ returns to the user. This is useful to abort execution
+ from lower down, e.g. in an autocommand. Example: >
+ :function s:check_typoname(file)
+ : if fnamemodify(a:file, ':t') == '['
+ : echomsg 'Maybe typo'
+ : call interrupt()
+ : endif
+ :endfunction
+ :au BufWritePre * call s:check_typoname(expand('<amatch>'))
+
invert({expr}) *invert()*
Bitwise invert. The argument is converted to a number. A
List, Dict or Float argument causes an error. Example: >
*** ../vim-8.1.2340/src/evalfunc.c 2019-11-22 19:29:42.521805447 +0100
--- src/evalfunc.c 2019-11-25 00:01:36.069579874 +0100
***************
*** 114,119 ****
--- 114,120 ----
static void f_inputrestore(typval_T *argvars, typval_T *rettv);
static void f_inputsave(typval_T *argvars, typval_T *rettv);
static void f_inputsecret(typval_T *argvars, typval_T *rettv);
+ static void f_interrupt(typval_T *argvars, typval_T *rettv);
static void f_invert(typval_T *argvars, typval_T *rettv);
static void f_islocked(typval_T *argvars, typval_T *rettv);
#if defined(FEAT_FLOAT) && defined(HAVE_MATH_H)
***************
*** 509,514 ****
--- 510,516 ----
{"inputsave", 0, 0, 0, f_inputsave},
{"inputsecret", 1, 2, FEARG_1, f_inputsecret},
{"insert", 2, 3, FEARG_1, f_insert},
+ {"interrupt", 0, 0, 0, f_interrupt},
{"invert", 1, 1, FEARG_1, f_invert},
{"isdirectory", 1, 1, FEARG_1, f_isdirectory},
#if defined(FEAT_FLOAT) && defined(HAVE_MATH_H)
***************
*** 4152,4157 ****
--- 4154,4168 ----
}
/*
+ * "interrupt()" function
+ */
+ static void
+ f_interrupt(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
+ {
+ got_int = TRUE;
+ }
+
+ /*
* "invert(expr)" function
*/
static void
*** ../vim-8.1.2340/src/ex_eval.c 2019-08-20 20:13:40.322821973 +0200
--- src/ex_eval.c 2019-11-25 00:00:19.277324874 +0100
***************
*** 85,90 ****
--- 85,91 ----
* until the throw point for error messages has been reached. That is, during
* cancellation of an expression evaluation after an aborting function call or
* due to a parsing error, aborting() always returns the same value.
+ * "got_int" is also set by calling interrupt().
*/
int
aborting(void)
*** ../vim-8.1.2340/src/testdir/Make_all.mak 2019-11-06 15:21:56.720396416 +0100
--- src/testdir/Make_all.mak 2019-11-25 00:00:44.573226022 +0100
***************
*** 154,159 ****
--- 154,160 ----
test_increment \
test_increment_dbcs \
test_ins_complete \
+ test_interrupt \
test_job_fails \
test_join \
test_json \
***************
*** 361,366 ****
--- 362,368 ----
test_increment.res \
test_increment_dbcs.res \
test_ins_complete.res \
+ test_interrupt.res \
test_job_fails.res \
test_json.res \
test_jumplist.res \
*** ../vim-8.1.2340/src/testdir/test_interrupt.vim 2019-11-25 00:03:37.670787768 +0100
--- src/testdir/test_interrupt.vim 2019-11-24 23:55:26.274464765 +0100
***************
*** 0 ****
--- 1,27 ----
+ " Test behavior of interrupt()
+
+ let s:bufwritepre_called = 0
+ let s:bufwritepost_called = 0
+
+ func s:bufwritepre()
+ let s:bufwritepre_called = 1
+ call interrupt()
+ endfunction
+
+ func s:bufwritepost()
+ let s:bufwritepost_called = 1
+ endfunction
+
+ func Test_interrupt()
+ new Xfile
+ let n = 0
+ try
+ au BufWritePre Xfile call s:bufwritepre()
+ au BufWritePost Xfile call s:bufwritepost()
+ w!
+ catch /^Vim:Interrupt$/
+ endtry
+ call assert_equal(1, s:bufwritepre_called)
+ call assert_equal(0, s:bufwritepost_called)
+ call assert_equal(0, filereadable('Xfile'))
+ endfunc
*** ../vim-8.1.2340/src/version.c 2019-11-24 22:13:53.902251675 +0100
--- src/version.c 2019-11-24 23:54:45.054624172 +0100
***************
*** 739,740 ****
--- 739,742 ----
{ /* Add new patch number below this line */
+ /**/
+ 2341,
/**/
--
Support your right to bare arms! Wear short sleeves!
/// 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 ///