summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/evalfunc.c32
-rw-r--r--src/ex_cmds2.c12
-rw-r--r--src/proto/ex_cmds2.pro1
-rw-r--r--src/structs.h1
-rw-r--r--src/testdir/shared.vim5
-rw-r--r--src/testdir/test_timers.vim92
-rw-r--r--src/version.c2
7 files changed, 128 insertions, 17 deletions
diff --git a/src/evalfunc.c b/src/evalfunc.c
index 50fa3bf72..8b5ad22fe 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -397,8 +397,10 @@ static void f_tanh(typval_T *argvars, typval_T *rettv);
#endif
#ifdef FEAT_TIMERS
static void f_timer_info(typval_T *argvars, typval_T *rettv);
+static void f_timer_pause(typval_T *argvars, typval_T *rettv);
static void f_timer_start(typval_T *argvars, typval_T *rettv);
static void f_timer_stop(typval_T *argvars, typval_T *rettv);
+static void f_timer_stopall(typval_T *argvars, typval_T *rettv);
#endif
static void f_tolower(typval_T *argvars, typval_T *rettv);
static void f_toupper(typval_T *argvars, typval_T *rettv);
@@ -817,8 +819,10 @@ static struct fst
{"test_settime", 1, 1, f_test_settime},
#ifdef FEAT_TIMERS
{"timer_info", 0, 1, f_timer_info},
+ {"timer_pause", 2, 2, f_timer_pause},
{"timer_start", 2, 3, f_timer_start},
{"timer_stop", 1, 1, f_timer_stop},
+ {"timer_stopall", 0, 0, f_timer_stopall},
#endif
{"tolower", 1, 1, f_tolower},
{"toupper", 1, 1, f_toupper},
@@ -11988,6 +11992,25 @@ f_timer_info(typval_T *argvars, typval_T *rettv)
}
/*
+ * "timer_pause(timer, paused)" function
+ */
+ static void
+f_timer_pause(typval_T *argvars, typval_T *rettv UNUSED)
+{
+ timer_T *timer = NULL;
+ int paused = (int)get_tv_number(&argvars[1]);
+
+ if (argvars[0].v_type != VAR_NUMBER)
+ EMSG(_(e_number_exp));
+ else
+ {
+ timer = find_timer((int)get_tv_number(&argvars[0]));
+ if (timer != NULL)
+ timer->tr_paused = paused;
+ }
+}
+
+/*
* "timer_start(time, callback [, options])" function
*/
static void
@@ -12048,6 +12071,15 @@ f_timer_stop(typval_T *argvars, typval_T *rettv UNUSED)
if (timer != NULL)
stop_timer(timer);
}
+
+/*
+ * "timer_stopall()" function
+ */
+ static void
+f_timer_stopall(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
+{
+ stop_all_timers();
+}
#endif
/*
diff --git a/src/ex_cmds2.c b/src/ex_cmds2.c
index 6cf26e993..73b3a522f 100644
--- a/src/ex_cmds2.c
+++ b/src/ex_cmds2.c
@@ -1189,6 +1189,8 @@ check_due_timer(void)
next_due = -1;
for (timer = first_timer; timer != NULL; timer = timer->tr_next)
{
+ if (timer->tr_paused)
+ continue;
# ifdef WIN3264
this_due = (long)(((double)(timer->tr_due.QuadPart - now.QuadPart)
/ (double)fr.QuadPart) * 1000);
@@ -1252,6 +1254,15 @@ stop_timer(timer_T *timer)
}
void
+stop_all_timers(void)
+{
+ timer_T *timer;
+
+ while (first_timer != NULL)
+ stop_timer(first_timer);
+}
+
+ void
add_timer_info(typval_T *rettv, timer_T *timer)
{
list_T *list = rettv->vval.v_list;
@@ -1283,6 +1294,7 @@ add_timer_info(typval_T *rettv, timer_T *timer)
dict_add_nr_str(dict, "repeat",
(long)(timer->tr_repeat < 0 ? -1 : timer->tr_repeat + 1), NULL);
+ dict_add_nr_str(dict, "paused", (long)(timer->tr_paused), NULL);
di = dictitem_alloc((char_u *)"callback");
if (di != NULL)
diff --git a/src/proto/ex_cmds2.pro b/src/proto/ex_cmds2.pro
index 977f5c0de..f241d377e 100644
--- a/src/proto/ex_cmds2.pro
+++ b/src/proto/ex_cmds2.pro
@@ -22,6 +22,7 @@ timer_T *create_timer(long msec, int repeat);
long check_due_timer(void);
timer_T *find_timer(int id);
void stop_timer(timer_T *timer);
+void stop_all_timers(void);
void add_timer_info(typval_T *rettv, timer_T *timer);
void add_timer_info_all(typval_T *rettv);
int set_ref_in_timer(int copyID);
diff --git a/src/structs.h b/src/structs.h
index 6cfbb3c25..b56282fc2 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -3159,6 +3159,7 @@ struct timer_S
timer_T *tr_next;
timer_T *tr_prev;
proftime_T tr_due; /* when the callback is to be invoked */
+ int tr_paused; /* when TRUE callback is not invoked */
int tr_repeat; /* number of times to repeat, -1 forever */
long tr_interval; /* msec */
char_u *tr_callback; /* allocated */
diff --git a/src/testdir/shared.vim b/src/testdir/shared.vim
index ad8afe1ff..aba428a46 100644
--- a/src/testdir/shared.vim
+++ b/src/testdir/shared.vim
@@ -109,14 +109,17 @@ func s:kill_server(cmd)
endfunc
" Wait for up to a second for "expr" to become true.
+" Return time slept in milliseconds.
func WaitFor(expr)
+ let slept = 0
for i in range(100)
try
if eval(a:expr)
- return
+ return slept
endif
catch
endtry
+ let slept += 10
sleep 10m
endfor
endfunc
diff --git a/src/testdir/test_timers.vim b/src/testdir/test_timers.vim
index 0969377c8..fb35f61ff 100644
--- a/src/testdir/test_timers.vim
+++ b/src/testdir/test_timers.vim
@@ -1,11 +1,13 @@
" Test for timers
+source shared.vim
+
if !has('timers')
finish
endif
func MyHandler(timer)
- let s:val += 1
+ let g:val += 1
endfunc
func MyHandlerWithLists(lists, timer)
@@ -13,43 +15,101 @@ func MyHandlerWithLists(lists, timer)
endfunc
func Test_oneshot()
- let s:val = 0
+ let g:val = 0
let timer = timer_start(50, 'MyHandler')
- sleep 200m
- call assert_equal(1, s:val)
+ let slept = WaitFor('g:val == 1')
+ call assert_equal(1, g:val)
+ call assert_inrange(30, 100, slept)
endfunc
func Test_repeat_three()
- let s:val = 0
+ let g:val = 0
let timer = timer_start(50, 'MyHandler', {'repeat': 3})
- sleep 500m
- call assert_equal(3, s:val)
+ let slept = WaitFor('g:val == 3')
+ call assert_equal(3, g:val)
+ call assert_inrange(100, 250, slept)
endfunc
func Test_repeat_many()
- let s:val = 0
+ let g:val = 0
let timer = timer_start(50, 'MyHandler', {'repeat': -1})
sleep 200m
call timer_stop(timer)
- call assert_true(s:val > 1)
- call assert_true(s:val < 5)
+ call assert_inrange(2, 4, g:val)
endfunc
func Test_with_partial_callback()
- let s:val = 0
+ let g:val = 0
let s:meow = {}
function s:meow.bite(...)
- let s:val += 1
+ let g:val += 1
endfunction
call timer_start(50, s:meow.bite)
- sleep 200m
- call assert_equal(1, s:val)
+ let slept = WaitFor('g:val == 1')
+ call assert_equal(1, g:val)
+ call assert_inrange(30, 100, slept)
endfunc
func Test_retain_partial()
- call timer_start(100, function('MyHandlerWithLists', [['a']]))
+ call timer_start(50, function('MyHandlerWithLists', [['a']]))
call test_garbagecollect_now()
- sleep 200m
+ sleep 100m
+endfunc
+
+func Test_info()
+ let id = timer_start(1000, 'MyHandler')
+ let info = timer_info(id)
+ call assert_equal(id, info[0]['id'])
+ call assert_equal(1000, info[0]['time'])
+ call assert_true(info[0]['remaining'] > 500)
+ call assert_true(info[0]['remaining'] <= 1000)
+ call assert_equal(1, info[0]['repeat'])
+ call assert_equal("function('MyHandler')", string(info[0]['callback']))
+
+ let found = 0
+ for info in timer_info()
+ if info['id'] == id
+ let found += 1
+ endif
+ endfor
+ call assert_equal(1, found)
+
+ call timer_stop(id)
+ call assert_equal([], timer_info(id))
+endfunc
+
+func Test_stopall()
+ let id1 = timer_start(1000, 'MyHandler')
+ let id2 = timer_start(2000, 'MyHandler')
+ let info = timer_info()
+ call assert_equal(2, len(info))
+
+ call timer_stopall()
+ let info = timer_info()
+ call assert_equal(0, len(info))
endfunc
+
+func Test_paused()
+ let g:val = 0
+
+ let id = timer_start(50, 'MyHandler')
+ let info = timer_info(id)
+ call assert_equal(0, info[0]['paused'])
+
+ call timer_pause(id, 1)
+ let info = timer_info(id)
+ call assert_equal(1, info[0]['paused'])
+ sleep 100m
+ call assert_equal(0, g:val)
+
+ call timer_pause(id, 0)
+ let info = timer_info(id)
+ call assert_equal(0, info[0]['paused'])
+
+ let slept = WaitFor('g:val == 1')
+ call assert_equal(1, g:val)
+ call assert_inrange(0, 10, slept)
+endfunc
+
" vim: ts=2 sw=0 et
diff --git a/src/version.c b/src/version.c
index c9197f44a..044546b3d 100644
--- a/src/version.c
+++ b/src/version.c
@@ -764,6 +764,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 2180,
+/**/
2179,
/**/
2178,