To: vim_dev@googlegroups.com Subject: Patch 8.1.2341 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ 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('')) + 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 -- Bram@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 ///