From 8924e75f3477b20f0ef4e3df64b56bf496b197ae Mon Sep 17 00:00:00 2001 From: Jurica Bradaric Date: Thu, 2 Mar 2017 23:04:57 +0100 Subject: vim-patch:7.4.2170 Problem: Cannot get information about timers. Solution: Add timer_info(). https://github.com/vim/vim/commit/8e97bd74b5377753597e3d98e7123d8985c7fffd --- src/nvim/eval.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) (limited to 'src/nvim/eval.c') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index d4daffb469..537e9e696f 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -17931,6 +17931,61 @@ static bool set_ref_in_callback(Callback *callback, int copyID, return false; } +static void add_timer_info(typval_T *rettv, timer_T *timer) +{ + list_T *list = rettv->vval.v_list; + dict_T *dict = dict_alloc(); + + 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, "repeat", + (long)(timer->repeat_count < 0 ? -1 : timer->repeat_count), + NULL); + + dictitem_T *di = dictitem_alloc((char_u *)"callback"); + if (dict_add(dict, di) == FAIL) { + xfree(di); + return; + } + + if (timer->callback.type == kCallbackPartial) { + di->di_tv.v_type = VAR_PARTIAL; + di->di_tv.vval.v_partial = timer->callback.data.partial; + timer->callback.data.partial->pt_refcount++; + } else if (timer->callback.type == kCallbackFuncref) { + di->di_tv.v_type = VAR_FUNC; + di->di_tv.vval.v_string = vim_strsave(timer->callback.data.funcref); + } + di->di_tv.v_lock = 0; +} + +static void add_timer_info_all(typval_T *rettv) +{ + timer_T *timer; + map_foreach_value(timers, timer, { + add_timer_info(rettv, timer); + }) +} + +/// "timer_info([timer])" function +static void f_timer_info(typval_T *argvars, typval_T *rettv, FunPtr fptr) +{ + rettv_list_alloc(rettv); + if (argvars[0].v_type != VAR_UNKNOWN) { + if (argvars[0].v_type != VAR_NUMBER) { + EMSG(_(e_number_exp)); + } else { + timer_T *timer = pmap_get(uint64_t)(timers, get_tv_number(&argvars[0])); + if (timer != NULL) { + add_timer_info(rettv, timer); + } + } + } else { + add_timer_info_all(rettv); + } +} /// "timer_start(timeout, callback, opts)" function static void f_timer_start(typval_T *argvars, typval_T *rettv, FunPtr fptr) -- cgit From 5b8ce2feed6b528bae4bceba6f234be000949971 Mon Sep 17 00:00:00 2001 From: Jurica Bradaric Date: Sun, 5 Mar 2017 16:25:40 +0100 Subject: 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 --- src/nvim/eval.c | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) (limited to 'src/nvim/eval.c') 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) { -- cgit From ec0fabd4d5129c7293c8b8fcf0d0946ae5bd5fd4 Mon Sep 17 00:00:00 2001 From: Jurica Bradaric Date: Sat, 15 Apr 2017 18:45:47 +0200 Subject: eval.c: Code style fixes --- src/nvim/eval.c | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) (limited to 'src/nvim/eval.c') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 6a18baf2e2..33a553436f 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -16696,11 +16696,11 @@ static void f_timer_info(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (argvars[0].v_type != VAR_UNKNOWN) { if (argvars[0].v_type != VAR_NUMBER) { EMSG(_(e_number_exp)); - } else { - timer_T *timer = pmap_get(uint64_t)(timers, tv_get_number(&argvars[0])); - if (timer != NULL && !timer->stopped) { - add_timer_info(rettv, timer); - } + return; + } + timer_T *timer = pmap_get(uint64_t)(timers, tv_get_number(&argvars[0])); + if (timer != NULL && !timer->stopped) { + add_timer_info(rettv, timer); } } else { add_timer_info_all(rettv); @@ -16712,12 +16712,12 @@ 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)tv_get_number(&argvars[1]); - timer_T *timer = pmap_get(uint64_t)(timers, tv_get_number(&argvars[0])); - if (timer != NULL) { - timer->paused = paused; - } + return; + } + int paused = (bool)tv_get_number(&argvars[1]); + timer_T *timer = pmap_get(uint64_t)(timers, tv_get_number(&argvars[0])); + if (timer != NULL) { + timer->paused = paused; } } @@ -16790,7 +16790,7 @@ static void f_timer_stop(typval_T *argvars, typval_T *rettv, FunPtr fptr) static void f_timer_stopall(typval_T *argvars, typval_T *unused, FunPtr fptr) { - timer_teardown(); + timer_stop_all(); } // invoked on the main loop @@ -16853,7 +16853,7 @@ static void timer_decref(timer_T *timer) } } -void timer_teardown(void) +static void timer_stop_all(void) { timer_T *timer; map_foreach_value(timers, timer, { @@ -16861,6 +16861,11 @@ void timer_teardown(void) }) } +void timer_teardown(void) +{ + timer_stop_all(); +} + /* * "tolower(string)" function */ -- cgit