diff options
author | Bram Moolenaar <Bram@vim.org> | 2019-11-25 00:05:32 +0100 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2019-11-25 00:05:32 +0100 |
commit | 67a2deb9cb4ac2224cb1e4d240a5d0659f036264 (patch) | |
tree | 024c2f55f38fb92a7da3c6887dbd0c510c7ae6cb | |
parent | a106e6cde682bda4ad10ed745acb51975fcb02e0 (diff) | |
download | vim-git-67a2deb9cb4ac2224cb1e4d240a5d0659f036264.tar.gz |
patch 8.1.2341: not so easy to interrupt a script programaticallyv8.1.2341
Problem: Not so easy to interrupt a script programatically.
Solution: Add the interrupt() function. (Yasuhiro Matsumoto, closes #2834)
-rw-r--r-- | runtime/doc/eval.txt | 16 | ||||
-rw-r--r-- | src/evalfunc.c | 11 | ||||
-rw-r--r-- | src/ex_eval.c | 1 | ||||
-rw-r--r-- | src/testdir/Make_all.mak | 2 | ||||
-rw-r--r-- | src/testdir/test_interrupt.vim | 27 | ||||
-rw-r--r-- | src/version.c | 2 |
6 files changed, 58 insertions, 1 deletions
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index 7c8c8d30f..a6f56eb91 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -1,4 +1,4 @@ -*eval.txt* For Vim version 8.1. Last change: 2019 Nov 21 +*eval.txt* For Vim version 8.1. Last change: 2019 Nov 24 VIM REFERENCE MANUAL by Bram Moolenaar @@ -2531,6 +2531,7 @@ inputrestore() Number restore typeahead 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 @@ -6181,6 +6182,19 @@ insert({object}, {item} [, {idx}]) *insert()* 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: > diff --git a/src/evalfunc.c b/src/evalfunc.c index 6a9f9d637..075ef1bf1 100644 --- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -114,6 +114,7 @@ static void f_inputlist(typval_T *argvars, typval_T *rettv); 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,6 +510,7 @@ static funcentry_T global_functions[] = {"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,6 +4154,15 @@ f_inputsecret(typval_T *argvars, typval_T *rettv) } /* + * "interrupt()" function + */ + static void +f_interrupt(typval_T *argvars UNUSED, typval_T *rettv UNUSED) +{ + got_int = TRUE; +} + +/* * "invert(expr)" function */ static void diff --git a/src/ex_eval.c b/src/ex_eval.c index f1a8b97fc..097280a67 100644 --- a/src/ex_eval.c +++ b/src/ex_eval.c @@ -85,6 +85,7 @@ static int cause_abort = FALSE; * 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) diff --git a/src/testdir/Make_all.mak b/src/testdir/Make_all.mak index 6b86b37ec..ac254202a 100644 --- a/src/testdir/Make_all.mak +++ b/src/testdir/Make_all.mak @@ -154,6 +154,7 @@ NEW_TESTS = \ test_increment \ test_increment_dbcs \ test_ins_complete \ + test_interrupt \ test_job_fails \ test_join \ test_json \ @@ -361,6 +362,7 @@ NEW_TESTS_RES = \ test_increment.res \ test_increment_dbcs.res \ test_ins_complete.res \ + test_interrupt.res \ test_job_fails.res \ test_json.res \ test_jumplist.res \ diff --git a/src/testdir/test_interrupt.vim b/src/testdir/test_interrupt.vim new file mode 100644 index 000000000..111752d16 --- /dev/null +++ b/src/testdir/test_interrupt.vim @@ -0,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 diff --git a/src/version.c b/src/version.c index bebf22003..bbc71be6e 100644 --- a/src/version.c +++ b/src/version.c @@ -738,6 +738,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 2341, +/**/ 2340, /**/ 2339, |