Skip to content

Commit 975b527

Browse files
committed
patch 7.4.1578
Problem: There is no way to invoke a function later or periodically. Solution: Add timer support.
1 parent ab1fa39 commit 975b527

14 files changed

Lines changed: 439 additions & 19 deletions

File tree

runtime/doc/eval.txt

Lines changed: 49 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
*eval.txt* For Vim version 7.4. Last change: 2016 Mar 14
1+
*eval.txt* For Vim version 7.4. Last change: 2016 Mar 15
22

33

44
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -350,10 +350,6 @@ This works like: >
350350
: let index = index + 1
351351
:endwhile
352352
353-
Note that all items in the list should be of the same type, otherwise this
354-
results in error |E706|. To avoid this |:unlet| the variable at the end of
355-
the loop.
356-
357353
If all you want to do is modify each item in the list then the |map()|
358354
function will be a simpler method than a for loop.
359355

@@ -2133,9 +2129,12 @@ tabpagewinnr( {tabarg}[, {arg}])
21332129
Number number of current window in tab page
21342130
taglist( {expr}) List list of tags matching {expr}
21352131
tagfiles() List tags files used
2136-
tempname() String name for a temporary file
21372132
tan( {expr}) Float tangent of {expr}
21382133
tanh( {expr}) Float hyperbolic tangent of {expr}
2134+
tempname() String name for a temporary file
2135+
timer_start( {time}, {callback} [, {options}])
2136+
Number create a timer
2137+
timer_stop( {timer}) none stop a timer
21392138
tolower( {expr}) String the String {expr} switched to lowercase
21402139
toupper( {expr}) String the String {expr} switched to uppercase
21412140
tr( {src}, {fromstr}, {tostr}) String translate chars of {src} in {fromstr}
@@ -3572,8 +3571,15 @@ foreground() Move the Vim window to the foreground. Useful when sent from
35723571
*function()* *E700* *E922* *E923*
35733572
function({name} [, {arglist}] [, {dict}])
35743573
Return a |Funcref| variable that refers to function {name}.
3575-
{name} can be a user defined function or an internal function.
3576-
3574+
{name} can be the name of a user defined function or an
3575+
internal function.
3576+
3577+
{name} can also be a Funcref, also a partial. When it is a
3578+
partial the dict stored in it will be used and the {dict}
3579+
argument is not allowed. E.g.: >
3580+
let FuncWithArg = function(dict.Func, [arg])
3581+
let Broken = function(dict.Func, [arg], dict)
3582+
<
35773583
When {arglist} or {dict} is present this creates a partial.
35783584
That mans the argument list and/or the dictionary is stored in
35793585
the Funcref and will be used when the Funcref is called.
@@ -3598,6 +3604,10 @@ function({name} [, {arglist}] [, {dict}])
35983604
let Func = function('Callback', context)
35993605
...
36003606
call Func() " will echo: called for example
3607+
< The use of function() is not needed when there are no extra
3608+
arguments, these two are equivalent: >
3609+
let Func = function('Callback', context)
3610+
let Func = context.Callback
36013611
36023612
< The argument list and the Dictionary can be combined: >
36033613
function Callback(arg1, count) dict
@@ -4523,13 +4533,13 @@ job_info({job}) *job_info()*
45234533
"status" what |job_status()| returns
45244534
"channel" what |job_getchannel()| returns
45254535
"exitval" only valid when "status" is "dead"
4526-
"exit-cb" function to be called on exit
4536+
"exit_cb" function to be called on exit
45274537
"stoponexit" |job-stoponexit|
45284538

45294539
job_setoptions({job}, {options}) *job_setoptions()*
45304540
Change options for {job}. Supported are:
45314541
"stoponexit" |job-stoponexit|
4532-
"exit-cb" |job-exit-cb|
4542+
"exit_cb" |job-exit_cb|
45334543

45344544
job_start({command} [, {options}]) *job_start()*
45354545
Start a job and return a Job object. Unlike |system()| and
@@ -6897,8 +6907,7 @@ systemlist({expr} [, {input}]) *systemlist()*
68976907
is the same as |readfile()| will output with {binary} argument
68986908
set to "b".
68996909

6900-
Returns an empty string on error, so be careful not to run
6901-
into |E706|.
6910+
Returns an empty string on error.
69026911

69036912

69046913
tabpagebuflist([{arg}]) *tabpagebuflist()*
@@ -7014,6 +7023,33 @@ tanh({expr}) *tanh()*
70147023
{only available when compiled with the |+float| feature}
70157024

70167025

7026+
*timer_start()*
7027+
timer_start({time}, {callback} [, {options}])
7028+
Create a timer and return the timer ID.
7029+
7030+
{time} is the waiting time in milliseconds. This is the
7031+
minimum time before invoking the callback. When the system is
7032+
busy or Vim is not waiting for input the time will be longer.
7033+
7034+
{callback} is the function to call. It can be the name of a
7035+
function or a Funcref. It is called with one argument, which
7036+
is the timer ID. The callback is only invoked when Vim is
7037+
waiting for input.
7038+
7039+
{options} is a dictionary. Supported entries:
7040+
"repeat" Number of times to repeat calling the
7041+
callback. -1 means forever.
7042+
7043+
Example: >
7044+
func MyHandler(timer)
7045+
echo 'Handler called'
7046+
endfunc
7047+
let timer = timer_start(500, 'MyHandler',
7048+
\ {'repeat': 3})
7049+
< This will invoke MyHandler() three times at 500 msec
7050+
intervals.
7051+
{only available when compiled with the |+timers| feature}
7052+
70177053
tolower({expr}) *tolower()*
70187054
The result is a copy of the String given, with all uppercase
70197055
characters turned into lowercase (just like applying |gu| to
@@ -7570,6 +7606,7 @@ termresponse Compiled with support for |t_RV| and |v:termresponse|.
75707606
textobjects Compiled with support for |text-objects|.
75717607
tgetent Compiled with tgetent support, able to use a termcap
75727608
or terminfo file.
7609+
timers Compiled with |timer_start()| support.
75737610
title Compiled with window title support |'title'|.
75747611
toolbar Compiled with support for |gui-toolbar|.
75757612
unix Unix version of Vim.

src/eval.c

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -794,6 +794,10 @@ static void f_test(typval_T *argvars, typval_T *rettv);
794794
static void f_tan(typval_T *argvars, typval_T *rettv);
795795
static void f_tanh(typval_T *argvars, typval_T *rettv);
796796
#endif
797+
#ifdef FEAT_TIMERS
798+
static void f_timer_start(typval_T *argvars, typval_T *rettv);
799+
static void f_timer_stop(typval_T *argvars, typval_T *rettv);
800+
#endif
797801
static void f_tolower(typval_T *argvars, typval_T *rettv);
798802
static void f_toupper(typval_T *argvars, typval_T *rettv);
799803
static void f_tr(typval_T *argvars, typval_T *rettv);
@@ -8404,6 +8408,10 @@ static struct fst
84048408
#endif
84058409
{"tempname", 0, 0, f_tempname},
84068410
{"test", 1, 1, f_test},
8411+
#ifdef FEAT_TIMERS
8412+
{"timer_start", 2, 3, f_timer_start},
8413+
{"timer_stop", 1, 1, f_timer_stop},
8414+
#endif
84078415
{"tolower", 1, 1, f_tolower},
84088416
{"toupper", 1, 1, f_toupper},
84098417
{"tr", 3, 3, f_tr},
@@ -13648,6 +13656,9 @@ f_has(typval_T *argvars, typval_T *rettv)
1364813656
#ifdef HAVE_TGETENT
1364913657
"tgetent",
1365013658
#endif
13659+
#ifdef FEAT_TIMERS
13660+
"timers",
13661+
#endif
1365113662
#ifdef FEAT_TITLE
1365213663
"title",
1365313664
#endif
@@ -20077,6 +20088,82 @@ f_tanh(typval_T *argvars, typval_T *rettv)
2007720088
}
2007820089
#endif
2007920090

20091+
#if defined(FEAT_JOB_CHANNEL) || defined(FEAT_TIMERS) || defined(PROTO)
20092+
/*
20093+
* Get a callback from "arg". It can be a Funcref or a function name.
20094+
* When "arg" is zero return an empty string.
20095+
* Return NULL for an invalid argument.
20096+
*/
20097+
char_u *
20098+
get_callback(typval_T *arg, partial_T **pp)
20099+
{
20100+
if (arg->v_type == VAR_PARTIAL && arg->vval.v_partial != NULL)
20101+
{
20102+
*pp = arg->vval.v_partial;
20103+
return (*pp)->pt_name;
20104+
}
20105+
*pp = NULL;
20106+
if (arg->v_type == VAR_FUNC || arg->v_type == VAR_STRING)
20107+
return arg->vval.v_string;
20108+
if (arg->v_type == VAR_NUMBER && arg->vval.v_number == 0)
20109+
return (char_u *)"";
20110+
EMSG(_("E921: Invalid callback argument"));
20111+
return NULL;
20112+
}
20113+
#endif
20114+
20115+
#ifdef FEAT_TIMERS
20116+
/*
20117+
* "timer_start(time, callback [, options])" function
20118+
*/
20119+
static void
20120+
f_timer_start(typval_T *argvars, typval_T *rettv)
20121+
{
20122+
long msec = get_tv_number(&argvars[0]);
20123+
timer_T *timer;
20124+
int repeat = 0;
20125+
char_u *callback;
20126+
dict_T *dict;
20127+
20128+
if (argvars[2].v_type != VAR_UNKNOWN)
20129+
{
20130+
if (argvars[2].v_type != VAR_DICT
20131+
|| (dict = argvars[2].vval.v_dict) == NULL)
20132+
{
20133+
EMSG2(_(e_invarg2), get_tv_string(&argvars[2]));
20134+
return;
20135+
}
20136+
if (dict_find(dict, (char_u *)"repeat", -1) != NULL)
20137+
repeat = get_dict_number(dict, (char_u *)"repeat");
20138+
}
20139+
20140+
timer = create_timer(msec, repeat);
20141+
callback = get_callback(&argvars[1], &timer->tr_partial);
20142+
if (callback == NULL)
20143+
{
20144+
stop_timer(timer);
20145+
rettv->vval.v_number = -1;
20146+
}
20147+
else
20148+
{
20149+
timer->tr_callback = vim_strsave(callback);
20150+
rettv->vval.v_number = timer->tr_id;
20151+
}
20152+
}
20153+
20154+
/*
20155+
* "timer_stop(timer)" function
20156+
*/
20157+
static void
20158+
f_timer_stop(typval_T *argvars, typval_T *rettv UNUSED)
20159+
{
20160+
timer_T *timer = find_timer(get_tv_number(&argvars[0]));
20161+
20162+
if (timer != NULL)
20163+
stop_timer(timer);
20164+
}
20165+
#endif
20166+
2008020167
/*
2008120168
* "tolower(string)" function
2008220169
*/

0 commit comments

Comments
 (0)