Skip to content

Commit 67a2deb

Browse files
committed
patch 8.1.2341: not so easy to interrupt a script programatically
Problem: Not so easy to interrupt a script programatically. Solution: Add the interrupt() function. (Yasuhiro Matsumoto, closes #2834)
1 parent a106e6c commit 67a2deb

File tree

6 files changed

+58
-1
lines changed

6 files changed

+58
-1
lines changed

runtime/doc/eval.txt

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
*eval.txt* For Vim version 8.1. Last change: 2019 Nov 21
1+
*eval.txt* For Vim version 8.1. Last change: 2019 Nov 24
22

33

44
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -2531,6 +2531,7 @@ inputrestore() Number restore typeahead
25312531
inputsave() Number save and clear typeahead
25322532
inputsecret({prompt} [, {text}]) String like input() but hiding the text
25332533
insert({object}, {item} [, {idx}]) List insert {item} in {object} [before {idx}]
2534+
interrupt() none interrupt script execution
25342535
invert({expr}) Number bitwise invert
25352536
isdirectory({directory}) Number |TRUE| if {directory} is a directory
25362537
isinf({expr}) Number determine if {expr} is infinity value
@@ -6181,6 +6182,19 @@ insert({object}, {item} [, {idx}]) *insert()*
61816182
Can also be used as a |method|: >
61826183
mylist->insert(item)
61836184
6185+
interrupt() *interrupt()*
6186+
Interrupt script execution. It works more or less like the
6187+
user typing CTRL-C, most commands won't execute and control
6188+
returns to the user. This is useful to abort execution
6189+
from lower down, e.g. in an autocommand. Example: >
6190+
:function s:check_typoname(file)
6191+
: if fnamemodify(a:file, ':t') == '['
6192+
: echomsg 'Maybe typo'
6193+
: call interrupt()
6194+
: endif
6195+
:endfunction
6196+
:au BufWritePre * call s:check_typoname(expand('<amatch>'))
6197+
61846198
invert({expr}) *invert()*
61856199
Bitwise invert. The argument is converted to a number. A
61866200
List, Dict or Float argument causes an error. Example: >

src/evalfunc.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ static void f_inputlist(typval_T *argvars, typval_T *rettv);
114114
static void f_inputrestore(typval_T *argvars, typval_T *rettv);
115115
static void f_inputsave(typval_T *argvars, typval_T *rettv);
116116
static void f_inputsecret(typval_T *argvars, typval_T *rettv);
117+
static void f_interrupt(typval_T *argvars, typval_T *rettv);
117118
static void f_invert(typval_T *argvars, typval_T *rettv);
118119
static void f_islocked(typval_T *argvars, typval_T *rettv);
119120
#if defined(FEAT_FLOAT) && defined(HAVE_MATH_H)
@@ -509,6 +510,7 @@ static funcentry_T global_functions[] =
509510
{"inputsave", 0, 0, 0, f_inputsave},
510511
{"inputsecret", 1, 2, FEARG_1, f_inputsecret},
511512
{"insert", 2, 3, FEARG_1, f_insert},
513+
{"interrupt", 0, 0, 0, f_interrupt},
512514
{"invert", 1, 1, FEARG_1, f_invert},
513515
{"isdirectory", 1, 1, FEARG_1, f_isdirectory},
514516
#if defined(FEAT_FLOAT) && defined(HAVE_MATH_H)
@@ -4151,6 +4153,15 @@ f_inputsecret(typval_T *argvars, typval_T *rettv)
41514153
--inputsecret_flag;
41524154
}
41534155

4156+
/*
4157+
* "interrupt()" function
4158+
*/
4159+
static void
4160+
f_interrupt(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
4161+
{
4162+
got_int = TRUE;
4163+
}
4164+
41544165
/*
41554166
* "invert(expr)" function
41564167
*/

src/ex_eval.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ static int cause_abort = FALSE;
8585
* until the throw point for error messages has been reached. That is, during
8686
* cancellation of an expression evaluation after an aborting function call or
8787
* due to a parsing error, aborting() always returns the same value.
88+
* "got_int" is also set by calling interrupt().
8889
*/
8990
int
9091
aborting(void)

src/testdir/Make_all.mak

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ NEW_TESTS = \
154154
test_increment \
155155
test_increment_dbcs \
156156
test_ins_complete \
157+
test_interrupt \
157158
test_job_fails \
158159
test_join \
159160
test_json \
@@ -361,6 +362,7 @@ NEW_TESTS_RES = \
361362
test_increment.res \
362363
test_increment_dbcs.res \
363364
test_ins_complete.res \
365+
test_interrupt.res \
364366
test_job_fails.res \
365367
test_json.res \
366368
test_jumplist.res \

src/testdir/test_interrupt.vim

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
" Test behavior of interrupt()
2+
3+
let s:bufwritepre_called = 0
4+
let s:bufwritepost_called = 0
5+
6+
func s:bufwritepre()
7+
let s:bufwritepre_called = 1
8+
call interrupt()
9+
endfunction
10+
11+
func s:bufwritepost()
12+
let s:bufwritepost_called = 1
13+
endfunction
14+
15+
func Test_interrupt()
16+
new Xfile
17+
let n = 0
18+
try
19+
au BufWritePre Xfile call s:bufwritepre()
20+
au BufWritePost Xfile call s:bufwritepost()
21+
w!
22+
catch /^Vim:Interrupt$/
23+
endtry
24+
call assert_equal(1, s:bufwritepre_called)
25+
call assert_equal(0, s:bufwritepost_called)
26+
call assert_equal(0, filereadable('Xfile'))
27+
endfunc

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -737,6 +737,8 @@ static char *(features[]) =
737737

738738
static int included_patches[] =
739739
{ /* Add new patch number below this line */
740+
/**/
741+
2341,
740742
/**/
741743
2340,
742744
/**/

0 commit comments

Comments
 (0)