]> granicus.if.org Git - vim/commitdiff
patch 7.4.2170 v7.4.2170
authorBram Moolenaar <Bram@vim.org>
Sat, 6 Aug 2016 20:05:07 +0000 (22:05 +0200)
committerBram Moolenaar <Bram@vim.org>
Sat, 6 Aug 2016 20:05:07 +0000 (22:05 +0200)
Problem:    Cannot get information about timers.
Solution:   Add timer_info().

runtime/doc/eval.txt
src/evalfunc.c
src/ex_cmds2.c
src/proto/ex_cmds2.pro
src/version.c

index 04edbd367427b915b6d884a96c54c81b1fd964a8..d6269d5a3d80e763625bfa739c827b0156af11d6 100644 (file)
@@ -1,4 +1,4 @@
-*eval.txt*     For Vim version 7.4.  Last change: 2016 Aug 02
+*eval.txt*     For Vim version 7.4.  Last change: 2016 Aug 06
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -2339,6 +2339,7 @@ test_null_list()          List    null value for testing
 test_null_partial()            Funcref null value for testing
 test_null_string()             String  null value for testing
 test_settime({expr})           none    set current time for testing
+timer_info([{id}])             List    information about timers
 timer_start({time}, {callback} [, {options}])
                                Number  create a timer
 timer_stop({timer})            none    stop a timer
@@ -3392,9 +3393,13 @@ exepath({expr})                                          *exepath()*
                an empty string is returned.
 
                                                        *exists()*
-exists({expr}) The result is a Number, which is |TRUE| if {expr} is
-               defined, zero otherwise.  The {expr} argument is a string,
-               which contains one of these:
+exists({expr}) The result is a Number, which is |TRUE| if {expr} is defined,
+               zero otherwise.
+
+               For checking for a supported feature use |has()|.
+               For checking if a file exists use |filereadable()|.
+
+               The {expr} argument is a string, which contains one of these:
                        &option-name    Vim option (only checks if it exists,
                                        not if it really works)
                        +option-name    Vim option that works.
@@ -3442,7 +3447,6 @@ exists({expr})    The result is a Number, which is |TRUE| if {expr} is
                                        event and pattern.
                        ##event         autocommand for this event is
                                        supported.
-               For checking for a supported feature use |has()|.
 
                Examples: >
                        exists("&shortname")
@@ -5476,7 +5480,8 @@ matchadd({group}, {pattern}[, {priority}[, {id}[, {dict}]]])
                available from |getmatches()|.  All matches can be deleted in
                one operation by |clearmatches()|.
 
-matchaddpos({group}, {pos}[, {priority}[, {id}[, {dict}]]])            *matchaddpos()*
+                                                       *matchaddpos()*
+matchaddpos({group}, {pos}[, {priority}[, {id}[, {dict}]]])
                Same as |matchadd()|, but requires a list of positions {pos}
                instead of a pattern. This command is faster than |matchadd()|
                because it does not require to handle regular expressions and
@@ -7536,6 +7541,23 @@ test_settime({expr})                                     *test_settime()*
                {expr} must evaluate to a number.  When the value is zero the
                normal behavior is restored.
 
+                                                       *timer_info()*
+timer_info([{id}])
+               Return a list with information about timers.
+               When {id} is given only information about this timer is
+               returned.  When timer {id} does not exist an empty list is
+               returned.
+               When {id} is omitted information about all timers is returned.
+
+               For each timer the information is stored in a Dictionary with
+               these items:
+                   "id"            the timer ID
+                   "time"          time the timer was started with
+                   "remaining"     time until the timer fires
+                   "repeat"        number of times the timer will still fire;
+                                   -1 means forever
+                   "callback"      the callback
+
                                                        *timer_start()*
 timer_start({time}, {callback} [, {options}])
                Create a timer and return the timer ID.
@@ -7566,7 +7588,7 @@ timer_start({time}, {callback} [, {options}])
 timer_stop({timer})                                    *timer_stop()*
                Stop a timer.  The timer callback will no longer be invoked.
                {timer} is an ID returned by timer_start(), thus it must be a
-               Number.
+               Number.  If {timer} does not exist there is no error.
 
 tolower({expr})                                                *tolower()*
                The result is a copy of the String given, with all uppercase
index 37545344606595d1ba32f7b2b9f2990f6cb54b54..50fa3bf7200dbcaf28462202a321e9782e94bb04 100644 (file)
@@ -396,6 +396,7 @@ 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_info(typval_T *argvars, typval_T *rettv);
 static void f_timer_start(typval_T *argvars, typval_T *rettv);
 static void f_timer_stop(typval_T *argvars, typval_T *rettv);
 #endif
@@ -815,6 +816,7 @@ static struct fst
     {"test_null_string", 0, 0, f_test_null_string},
     {"test_settime",   1, 1, f_test_settime},
 #ifdef FEAT_TIMERS
+    {"timer_info",     0, 1, f_timer_info},
     {"timer_start",    2, 3, f_timer_start},
     {"timer_stop",     1, 1, f_timer_stop},
 #endif
@@ -11960,6 +11962,31 @@ free_callback(char_u *callback, partial_T *partial)
 #endif
 
 #ifdef FEAT_TIMERS
+/*
+ * "timer_info([timer])" function
+ */
+    static void
+f_timer_info(typval_T *argvars, typval_T *rettv)
+{
+    timer_T *timer = NULL;
+
+    if (rettv_list_alloc(rettv) != OK)
+       return;
+    if (argvars[0].v_type != VAR_UNKNOWN)
+    {
+       if (argvars[0].v_type != VAR_NUMBER)
+           EMSG(_(e_number_exp));
+       else
+       {
+           timer = find_timer((int)get_tv_number(&argvars[0]));
+           if (timer != NULL)
+               add_timer_info(rettv, timer);
+       }
+    }
+    else
+       add_timer_info_all(rettv);
+}
+
 /*
  * "timer_start(time, callback [, options])" function
  */
index 0e332dd421e833cc608289d57162cfa98fa00cc6..f6c054b8d29dea8228a02c40814cc7aa3a978f96 100644 (file)
@@ -1139,10 +1139,8 @@ create_timer(long msec, int repeat)
     timer->tr_id = ++last_timer_id;
     insert_timer(timer);
     if (repeat != 0)
-    {
        timer->tr_repeat = repeat - 1;
-       timer->tr_interval = msec;
-    }
+    timer->tr_interval = msec;
 
     profile_setlimit(msec, &timer->tr_due);
     return timer;
@@ -1253,6 +1251,64 @@ stop_timer(timer_T *timer)
     free_timer(timer);
 }
 
+    void
+add_timer_info(typval_T *rettv, timer_T *timer)
+{
+    list_T     *list = rettv->vval.v_list;
+    dict_T     *dict = dict_alloc();
+    dictitem_T *di;
+    long       remaining;
+    proftime_T now;
+
+    if (dict == NULL)
+       return;
+    list_append_dict(list, dict);
+
+    dict_add_nr_str(dict, "id", (long)timer->tr_id, NULL);
+    dict_add_nr_str(dict, "time", (long)timer->tr_interval, NULL);
+
+    profile_start(&now);
+# ifdef WIN3264
+    remaining = (long)(((double)(timer->tr_due.QuadPart - now.QuadPart)
+                                              / (double)fr.QuadPart) * 1000);
+# else
+    remaining = (timer->tr_due.tv_sec - now.tv_sec) * 1000
+                              + (timer->tr_due.tv_usec - now.tv_usec) / 1000;
+# endif
+    dict_add_nr_str(dict, "remaining", (long)remaining, NULL);
+
+    dict_add_nr_str(dict, "repeat",
+              (long)(timer->tr_repeat < 0 ? -1 : timer->tr_repeat + 1), NULL);
+
+    di = dictitem_alloc((char_u *)"callback");
+    if (di != NULL)
+    {
+       if (dict_add(dict, di) == FAIL)
+           vim_free(di);
+       else if (timer->tr_partial != NULL)
+       {
+           di->di_tv.v_type = VAR_PARTIAL;
+           di->di_tv.vval.v_partial = timer->tr_partial;
+           ++timer->tr_partial->pt_refcount;
+       }
+       else
+       {
+           di->di_tv.v_type = VAR_FUNC;
+           di->di_tv.vval.v_string = vim_strsave(timer->tr_callback);
+       }
+       di->di_tv.v_lock = 0;
+    }
+}
+
+    void
+add_timer_info_all(typval_T *rettv)
+{
+    timer_T *timer;
+
+    for (timer = first_timer; timer != NULL; timer = timer->tr_next)
+       add_timer_info(rettv, timer);
+}
+
 /*
  * Mark references in partials of timers.
  */
index c7a860b9f0a5660c9d0aa971cbc5aa918675ec55..977f5c0de183577e4f6d30e4b866f731cc9f613a 100644 (file)
@@ -22,6 +22,8 @@ timer_T *create_timer(long msec, int repeat);
 long check_due_timer(void);
 timer_T *find_timer(int id);
 void stop_timer(timer_T *timer);
+void add_timer_info(typval_T *rettv, timer_T *timer);
+void add_timer_info_all(typval_T *rettv);
 int set_ref_in_timer(int copyID);
 void timer_free_all(void);
 void profile_divide(proftime_T *tm, int count, proftime_T *tm2);
index e57e0fc93155d6f496f6dae6e6eb7edf7d63d94a..b1be507afd9a9761640bebdf6cb429bab4f902b7 100644 (file)
@@ -763,6 +763,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    2170,
 /**/
     2169,
 /**/