aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJurica Bradaric <jurica.bradaric@avl.com>2017-03-05 16:25:40 +0100
committerJurica Bradaric <jbradaric@gmail.com>2017-03-20 21:15:56 +0100
commit5b8ce2feed6b528bae4bceba6f234be000949971 (patch)
tree2763d110839192b2130a72d7f78b0bddf6f6b519 /src
parent8924e75f3477b20f0ef4e3df64b56bf496b197ae (diff)
downloadrneovim-5b8ce2feed6b528bae4bceba6f234be000949971.tar.gz
rneovim-5b8ce2feed6b528bae4bceba6f234be000949971.tar.bz2
rneovim-5b8ce2feed6b528bae4bceba6f234be000949971.zip
vim-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(). https://github.com/vim/vim/commit/b73598e2f022a22fec512ea681c70d2775e8fd87
Diffstat (limited to 'src')
-rw-r--r--src/nvim/eval.c34
-rw-r--r--src/nvim/eval.lua2
-rw-r--r--src/nvim/testdir/shared.vim17
-rw-r--r--src/nvim/testdir/test_timers.vim86
-rw-r--r--src/nvim/version.c2
5 files changed, 120 insertions, 21 deletions
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 537e9e696f..062999e73b 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -446,6 +446,7 @@ typedef struct {
int refcount;
long timeout;
bool stopped;
+ bool paused;
Callback callback;
} timer_T;
@@ -17939,6 +17940,7 @@ static void add_timer_info(typval_T *rettv, timer_T *timer)
list_append_dict(list, dict);
dict_add_nr_str(dict, "id", (long)timer->timer_id, NULL);
dict_add_nr_str(dict, "time", timer->timeout, NULL);
+ dict_add_nr_str(dict, "paused", (long)timer->paused, NULL);
dict_add_nr_str(dict, "repeat",
(long)(timer->repeat_count < 0 ? -1 : timer->repeat_count),
@@ -17965,7 +17967,9 @@ static void add_timer_info_all(typval_T *rettv)
{
timer_T *timer;
map_foreach_value(timers, timer, {
- add_timer_info(rettv, timer);
+ if (!timer->stopped) {
+ add_timer_info(rettv, timer);
+ }
})
}
@@ -17978,7 +17982,7 @@ static void f_timer_info(typval_T *argvars, typval_T *rettv, FunPtr fptr)
EMSG(_(e_number_exp));
} else {
timer_T *timer = pmap_get(uint64_t)(timers, get_tv_number(&argvars[0]));
- if (timer != NULL) {
+ if (timer != NULL && !timer->stopped) {
add_timer_info(rettv, timer);
}
}
@@ -17987,6 +17991,20 @@ static void f_timer_info(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
+/// "timer_pause(timer, paused)" function
+static void f_timer_pause(typval_T *argvars, typval_T *unused, FunPtr fptr)
+{
+ if (argvars[0].v_type != VAR_NUMBER) {
+ EMSG(_(e_number_exp));
+ } else {
+ int paused = (bool)get_tv_number(&argvars[1]);
+ timer_T *timer = pmap_get(uint64_t)(timers, get_tv_number(&argvars[0]));
+ if (timer != NULL) {
+ timer->paused = paused;
+ }
+ }
+}
+
/// "timer_start(timeout, callback, opts)" function
static void f_timer_start(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
@@ -18019,6 +18037,7 @@ static void f_timer_start(typval_T *argvars, typval_T *rettv, FunPtr fptr)
timer = xmalloc(sizeof *timer);
timer->refcount = 1;
timer->stopped = false;
+ timer->paused = false;
timer->repeat_count = repeat;
timer->timeout = timeout;
timer->timer_id = last_timer_id++;
@@ -18028,8 +18047,7 @@ static void f_timer_start(typval_T *argvars, typval_T *rettv, FunPtr fptr)
timer->tw.events = multiqueue_new_child(main_loop.events);
// if main loop is blocked, don't queue up multiple events
timer->tw.blockable = true;
- time_watcher_start(&timer->tw, timer_due_cb, timeout,
- timeout * (repeat != 1));
+ time_watcher_start(&timer->tw, timer_due_cb, timeout, timeout);
pmap_put(uint64_t)(timers, timer->timer_id, timer);
rettv->vval.v_number = timer->timer_id;
@@ -18053,13 +18071,19 @@ static void f_timer_stop(typval_T *argvars, typval_T *rettv, FunPtr fptr)
timer_stop(timer);
}
+static void f_timer_stopall(typval_T *argvars, typval_T *unused, FunPtr fptr)
+{
+ timer_teardown();
+}
+
// invoked on the main loop
static void timer_due_cb(TimeWatcher *tw, void *data)
{
timer_T *timer = (timer_T *)data;
- if (timer->stopped) {
+ if (timer->stopped || timer->paused) {
return;
}
+
timer->refcount++;
// if repeat was negative repeat forever
if (timer->repeat_count >= 0 && --timer->repeat_count == 0) {
diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua
index e923fee316..d30d34135b 100644
--- a/src/nvim/eval.lua
+++ b/src/nvim/eval.lua
@@ -307,8 +307,10 @@ return {
termopen={args={1, 2}},
test_garbagecollect_now={},
timer_info={args={0,1}},
+ timer_pause={args=2},
timer_start={args={2,3}},
timer_stop={args=1},
+ timer_stopall={args=0},
tolower={args=1},
toupper={args=1},
tr={args=3},
diff --git a/src/nvim/testdir/shared.vim b/src/nvim/testdir/shared.vim
new file mode 100644
index 0000000000..9573f5a9c3
--- /dev/null
+++ b/src/nvim/testdir/shared.vim
@@ -0,0 +1,17 @@
+" Functions shared by several tests.
+
+" 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
diff --git a/src/nvim/testdir/test_timers.vim b/src/nvim/testdir/test_timers.vim
index 56f9feef66..b03295bd01 100644
--- a/src/nvim/testdir/test_timers.vim
+++ b/src/nvim/testdir/test_timers.vim
@@ -4,8 +4,10 @@ if !has('timers')
finish
endif
+source shared.vim
+
func MyHandler(timer)
- let s:val += 1
+ let g:val += 1
endfunc
func MyHandlerWithLists(lists, timer)
@@ -13,44 +15,98 @@ 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 garbagecollect()
+ 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_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 200m
+ 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: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/version.c b/src/nvim/version.c
index b283059c7a..4da970d43b 100644
--- a/src/nvim/version.c
+++ b/src/nvim/version.c
@@ -261,7 +261,7 @@ static int included_patches[] = {
2183,
// 2182 NA
// 2181,
- // 2180,
+ 2180,
// 2179,
// 2178,
// 2177,