patch 7.4.2170
Problem:    Cannot get information about timers.
Solution:   Add timer_info().
diff --git a/src/evalfunc.c b/src/evalfunc.c
index 3754534..50fa3bf 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -396,6 +396,7 @@
 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 @@
     {"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
@@ -11961,6 +11963,31 @@
 
 #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
  */
     static void
diff --git a/src/ex_cmds2.c b/src/ex_cmds2.c
index 0e332dd..f6c054b 100644
--- a/src/ex_cmds2.c
+++ b/src/ex_cmds2.c
@@ -1139,10 +1139,8 @@
     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 @@
     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.
  */
diff --git a/src/proto/ex_cmds2.pro b/src/proto/ex_cmds2.pro
index c7a860b..977f5c0 100644
--- a/src/proto/ex_cmds2.pro
+++ b/src/proto/ex_cmds2.pro
@@ -22,6 +22,8 @@
 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);
diff --git a/src/version.c b/src/version.c
index e57e0fc..b1be507 100644
--- a/src/version.c
+++ b/src/version.c
@@ -764,6 +764,8 @@
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    2170,
+/**/
     2169,
 /**/
     2168,