0
0
mirror of https://github.com/vim/vim.git synced 2025-09-26 04:04:07 -04:00

patch 7.4.1578

Problem:    There is no way to invoke a function later or periodically.
Solution:   Add timer support.
This commit is contained in:
Bram Moolenaar
2016-03-15 23:10:59 +01:00
parent ab1fa3955f
commit 975b5271ee
14 changed files with 438 additions and 18 deletions

View File

@@ -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
*/