Patch 7.4.2180
Problem: There is no easy way to stop all timers. There is no way to
temporary pause a timer.
Solution: Add timer_stopall() and timer_pause().
Files: src/evalfunc.c, src/ex_cmds2.c, src/proto/ex_cmds2.pro,
src/structs.h, src/testdir/test_timers.vim,
src/testdir/shared.vim, runtime/doc/eval.txt
*** ../vim-7.4.2179/src/evalfunc.c 2016-08-06 22:04:44.274311280 +0200
--- src/evalfunc.c 2016-08-07 18:15:25.349625170 +0200
***************
*** 397,404 ****
--- 397,406 ----
#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,824 ****
--- 819,828 ----
{"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,11993 ****
--- 11992,12016 ----
}
/*
+ * "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,12053 ****
--- 12071,12085 ----
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
/*
*** ../vim-7.4.2179/src/ex_cmds2.c 2016-08-06 22:27:24.799508423 +0200
--- src/ex_cmds2.c 2016-08-07 17:49:39.726424958 +0200
***************
*** 1189,1194 ****
--- 1189,1196 ----
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,1257 ****
--- 1254,1268 ----
}
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,1288 ****
--- 1294,1300 ----
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)
*** ../vim-7.4.2179/src/proto/ex_cmds2.pro 2016-08-06 22:04:44.278311247
+0200
--- src/proto/ex_cmds2.pro 2016-08-07 17:18:46.937920379 +0200
***************
*** 22,27 ****
--- 22,28 ----
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);
*** ../vim-7.4.2179/src/structs.h 2016-08-07 15:19:22.204295369 +0200
--- src/structs.h 2016-08-07 17:45:30.456510980 +0200
***************
*** 3159,3164 ****
--- 3159,3165 ----
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 */
*** ../vim-7.4.2179/src/testdir/test_timers.vim 2016-05-31 21:12:59.734705409
+0200
--- src/testdir/test_timers.vim 2016-08-07 18:13:19.222665327 +0200
***************
*** 1,11 ****
" Test for timers
if !has('timers')
finish
endif
func MyHandler(timer)
! let s:val += 1
endfunc
func MyHandlerWithLists(lists, timer)
--- 1,13 ----
" Test for timers
+ source shared.vim
+
if !has('timers')
finish
endif
func MyHandler(timer)
! let g:val += 1
endfunc
func MyHandlerWithLists(lists, timer)
***************
*** 13,55 ****
endfunc
func Test_oneshot()
! let s:val = 0
let timer = timer_start(50, 'MyHandler')
! sleep 200m
! call assert_equal(1, s:val)
endfunc
func Test_repeat_three()
! let s:val = 0
let timer = timer_start(50, 'MyHandler', {'repeat': 3})
! sleep 500m
! call assert_equal(3, s:val)
endfunc
func Test_repeat_many()
! let s: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)
endfunc
func Test_with_partial_callback()
! let s:val = 0
let s:meow = {}
function s:meow.bite(...)
! let s:val += 1
endfunction
call timer_start(50, s:meow.bite)
! sleep 200m
! call assert_equal(1, s:val)
endfunc
func Test_retain_partial()
! call timer_start(100, function('MyHandlerWithLists', [['a']]))
call test_garbagecollect_now()
! sleep 200m
endfunc
" vim: ts=2 sw=0 et
--- 15,115 ----
endfunc
func Test_oneshot()
! let g:val = 0
let timer = timer_start(50, 'MyHandler')
! let slept = WaitFor('g:val == 1')
! call assert_equal(1, g:val)
! call assert_inrange(30, 100, slept)
endfunc
func Test_repeat_three()
! let g:val = 0
let timer = timer_start(50, 'MyHandler', {'repeat': 3})
! let slept = WaitFor('g:val == 3')
! call assert_equal(3, g:val)
! call assert_inrange(100, 250, slept)
endfunc
func Test_repeat_many()
! let g:val = 0
let timer = timer_start(50, 'MyHandler', {'repeat': -1})
sleep 200m
call timer_stop(timer)
! call assert_inrange(2, 4, g:val)
endfunc
func Test_with_partial_callback()
! let g:val = 0
let s:meow = {}
function s:meow.bite(...)
! let g:val += 1
endfunction
call timer_start(50, s:meow.bite)
! 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(50, function('MyHandlerWithLists', [['a']]))
call test_garbagecollect_now()
! 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
*** ../vim-7.4.2179/src/testdir/shared.vim 2016-08-07 16:36:26.718630005
+0200
--- src/testdir/shared.vim 2016-08-07 17:24:09.703254829 +0200
***************
*** 109,122 ****
endfunc
" Wait for up to a second for "expr" to become true.
func WaitFor(expr)
for i in range(100)
try
if eval(a:expr)
! return
endif
catch
endtry
sleep 10m
endfor
endfunc
--- 109,125 ----
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 slept
endif
catch
endtry
+ let slept += 10
sleep 10m
endfor
endfunc
*** ../vim-7.4.2179/runtime/doc/eval.txt 2016-08-06 22:04:44.286311184
+0200
--- runtime/doc/eval.txt 2016-08-07 17:44:49.332855441 +0200
***************
*** 2318,2326 ****
--- 2340,2350 ----
test_null_string() String null value for testing
test_settime({expr}) none set current time for testing
timer_info([{id}]) List information about timers
+ timer_pause({id}, {pause}) none pause or unpause a timer
timer_start({time}, {callback} [, {options}])
Number create a timer
timer_stop({timer}) none stop a timer
+ timer_stopall() none stop all timers
tolower({expr}) String the String {expr} switched to
lowercase
toupper({expr}) String the String {expr} switched to
uppercase
tr({src}, {fromstr}, {tostr}) String translate chars of {src} in {fromstr}
***************
*** 7450,7457 ****
"time" time the timer was started with
"remaining" time until the timer fires
"repeat" number of times the timer will still fire;
! -1 means forever
"callback" the callback
*timer_start()*
timer_start({time}, {callback} [, {options}])
--- 7557,7582 ----
"time" time the timer was started with
"remaining" time until the timer fires
"repeat" number of times the timer will still fire;
! -1 means forever
"callback" the callback
+ "paused" 1 if the timer is paused, 0 otherwise
+
+ {only available when compiled with the |+timers| feature}
+
+ timer_pause({timer}, {paused}) *timer_pause()*
+ Pause or unpause a timer. A paused timer does not invoke its
+ callback, while the time it would is not changed. Unpausing a
+ timer may cause the callback to be invoked almost immediately
+ if enough time has passed.
+
+ Pausing a timer is useful to avoid the callback to be called
+ for a short time.
+
+ If {paused} evaluates to a non-zero Number or a non-empty
+ String, then the timer is paused, otherwise it is unpaused.
+ See |non-zero-arg|.
+
+ {only available when compiled with the |+timers| feature}
*timer_start()*
timer_start({time}, {callback} [, {options}])
***************
*** 7478,7483 ****
--- 7603,7609 ----
\ {'repeat': 3})
< This will invoke MyHandler() three times at 500 msec
intervals.
+
{only available when compiled with the |+timers| feature}
timer_stop({timer}) *timer_stop()*
***************
*** 7485,7490 ****
--- 7611,7625 ----
{timer} is an ID returned by timer_start(), thus it must be a
Number. If {timer} does not exist there is no error.
+ {only available when compiled with the |+timers| feature}
+
+ timer_stopall()
*timer_stopall()*
+ Stop all timers. The timer callbacks will no longer be
+ invoked. Useful if some timers is misbehaving. If there are
+ no timers there is no error.
+
+ {only available when compiled with the |+timers| feature}
+
tolower({expr}) *tolower()*
The result is a copy of the String given, with all uppercase
characters turned into lowercase (just like applying |gu| to
*** ../vim-7.4.2179/src/version.c 2016-08-07 16:50:07.751926334 +0200
--- src/version.c 2016-08-07 17:17:03.190762909 +0200
***************
*** 765,766 ****
--- 765,768 ----
{ /* Add new patch number below this line */
+ /**/
+ 2180,
/**/
--
"You're fired." (1980)
"You're laid off." (1985)
"You're downsized." (1990)
"You're rightsized." (1992)
(Scott Adams - The Dilbert principle)
/// Bram Moolenaar -- [email protected] -- 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 ///
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.