summaryrefslogtreecommitdiff
path: root/src/eval.c
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2016-03-15 23:10:59 +0100
committerBram Moolenaar <Bram@vim.org>2016-03-15 23:10:59 +0100
commit975b5271eed4fa0500c24a8f37be0b1797cb9db7 (patch)
treee2f73f9ae91f1fce55de8757dc1599fcc169c3fe /src/eval.c
parentab1fa3955f25dfdb7e329c3bd76e175c93c8cb5e (diff)
downloadvim-git-975b5271eed4fa0500c24a8f37be0b1797cb9db7.tar.gz
patch 7.4.1578v7.4.1578
Problem: There is no way to invoke a function later or periodically. Solution: Add timer support.
Diffstat (limited to 'src/eval.c')
-rw-r--r--src/eval.c87
1 files changed, 87 insertions, 0 deletions
diff --git a/src/eval.c b/src/eval.c
index 38c192ed1..506932403 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -794,6 +794,10 @@ static void f_test(typval_T *argvars, typval_T *rettv);
static void f_tan(typval_T *argvars, typval_T *rettv);
static void f_tanh(typval_T *argvars, typval_T *rettv);
#endif
+#ifdef FEAT_TIMERS
+static void f_timer_start(typval_T *argvars, typval_T *rettv);
+static void f_timer_stop(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);
static void f_tr(typval_T *argvars, typval_T *rettv);
@@ -8404,6 +8408,10 @@ static struct fst
#endif
{"tempname", 0, 0, f_tempname},
{"test", 1, 1, f_test},
+#ifdef FEAT_TIMERS
+ {"timer_start", 2, 3, f_timer_start},
+ {"timer_stop", 1, 1, f_timer_stop},
+#endif
{"tolower", 1, 1, f_tolower},
{"toupper", 1, 1, f_toupper},
{"tr", 3, 3, f_tr},
@@ -13648,6 +13656,9 @@ f_has(typval_T *argvars, typval_T *rettv)
#ifdef HAVE_TGETENT
"tgetent",
#endif
+#ifdef FEAT_TIMERS
+ "timers",
+#endif
#ifdef FEAT_TITLE
"title",
#endif
@@ -20077,6 +20088,82 @@ f_tanh(typval_T *argvars, typval_T *rettv)
}
#endif
+#if defined(FEAT_JOB_CHANNEL) || defined(FEAT_TIMERS) || defined(PROTO)
+/*
+ * Get a callback from "arg". It can be a Funcref or a function name.
+ * When "arg" is zero return an empty string.
+ * Return NULL for an invalid argument.
+ */
+ char_u *
+get_callback(typval_T *arg, partial_T **pp)
+{
+ if (arg->v_type == VAR_PARTIAL && arg->vval.v_partial != NULL)
+ {
+ *pp = arg->vval.v_partial;
+ return (*pp)->pt_name;
+ }
+ *pp = NULL;
+ if (arg->v_type == VAR_FUNC || arg->v_type == VAR_STRING)
+ return arg->vval.v_string;
+ if (arg->v_type == VAR_NUMBER && arg->vval.v_number == 0)
+ return (char_u *)"";
+ EMSG(_("E921: Invalid callback argument"));
+ return NULL;
+}
+#endif
+
+#ifdef FEAT_TIMERS
+/*
+ * "timer_start(time, callback [, options])" function
+ */
+ static void
+f_timer_start(typval_T *argvars, typval_T *rettv)
+{
+ long msec = get_tv_number(&argvars[0]);
+ timer_T *timer;
+ int repeat = 0;
+ char_u *callback;
+ dict_T *dict;
+
+ if (argvars[2].v_type != VAR_UNKNOWN)
+ {
+ if (argvars[2].v_type != VAR_DICT
+ || (dict = argvars[2].vval.v_dict) == NULL)
+ {
+ EMSG2(_(e_invarg2), get_tv_string(&argvars[2]));
+ return;
+ }
+ if (dict_find(dict, (char_u *)"repeat", -1) != NULL)
+ repeat = get_dict_number(dict, (char_u *)"repeat");
+ }
+
+ timer = create_timer(msec, repeat);
+ callback = get_callback(&argvars[1], &timer->tr_partial);
+ if (callback == NULL)
+ {
+ stop_timer(timer);
+ rettv->vval.v_number = -1;
+ }
+ else
+ {
+ timer->tr_callback = vim_strsave(callback);
+ rettv->vval.v_number = timer->tr_id;
+ }
+}
+
+/*
+ * "timer_stop(timer)" function
+ */
+ static void
+f_timer_stop(typval_T *argvars, typval_T *rettv UNUSED)
+{
+ timer_T *timer = find_timer(get_tv_number(&argvars[0]));
+
+ if (timer != NULL)
+ stop_timer(timer);
+}
+#endif
+
/*
* "tolower(string)" function
*/