Patch 8.1.1989
Problem:    The evalfunc.c file is still too big.
Solution:   Move f_pathshorten() to filepath.c.  Move f_cscope_connection() to
            if_cscope.c.  Move diff_ functions to diff.c.  Move timer_
            functions to ex_cmds2.c.  move callback functions to evalvars.c.
Files:      src/evalfunc.c, src/proto/evalfunc.pro, src/filepath.c,
            src/proto/filepath.pro, src/if_cscope.c, src/proto/if_cscope.pro,
            src/diff.c, src/proto/diff.pro, src/ex_cmds2.c,
            src/proto/ex_cmds2.pro, src/evalvars.c, src/proto/evalvars.pro


*** ../vim-8.1.1988/src/evalfunc.c      2019-09-04 22:28:53.061026888 +0200
--- src/evalfunc.c      2019-09-05 22:18:06.320368819 +0200
***************
*** 70,76 ****
  static void f_cos(typval_T *argvars, typval_T *rettv);
  static void f_cosh(typval_T *argvars, typval_T *rettv);
  #endif
- static void f_cscope_connection(typval_T *argvars, typval_T *rettv);
  static void f_cursor(typval_T *argsvars, typval_T *rettv);
  #ifdef MSWIN
  static void f_debugbreak(typval_T *argvars, typval_T *rettv);
--- 70,75 ----
***************
*** 78,85 ****
  static void f_deepcopy(typval_T *argvars, typval_T *rettv);
  static void f_deletebufline(typval_T *argvars, typval_T *rettv);
  static void f_did_filetype(typval_T *argvars, typval_T *rettv);
- static void f_diff_filler(typval_T *argvars, typval_T *rettv);
- static void f_diff_hlID(typval_T *argvars, typval_T *rettv);
  static void f_empty(typval_T *argvars, typval_T *rettv);
  static void f_environ(typval_T *argvars, typval_T *rettv);
  static void f_escape(typval_T *argvars, typval_T *rettv);
--- 77,82 ----
***************
*** 178,184 ****
  static void f_nextnonblank(typval_T *argvars, typval_T *rettv);
  static void f_nr2char(typval_T *argvars, typval_T *rettv);
  static void f_or(typval_T *argvars, typval_T *rettv);
- static void f_pathshorten(typval_T *argvars, typval_T *rettv);
  #ifdef FEAT_PERL
  static void f_perleval(typval_T *argvars, typval_T *rettv);
  #endif
--- 175,180 ----
***************
*** 291,303 ****
  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_pause(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);
- static void f_timer_stopall(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);
--- 287,292 ----
***************
*** 2095,2127 ****
  #endif
  
  /*
-  * "cscope_connection([{num} , {dbpath} [, {prepend}]])" function
-  *
-  * Checks the existence of a cscope connection.
-  */
-     static void
- f_cscope_connection(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
- {
- #ifdef FEAT_CSCOPE
-     int               num = 0;
-     char_u    *dbpath = NULL;
-     char_u    *prepend = NULL;
-     char_u    buf[NUMBUFLEN];
- 
-     if (argvars[0].v_type != VAR_UNKNOWN
-           && argvars[1].v_type != VAR_UNKNOWN)
-     {
-       num = (int)tv_get_number(&argvars[0]);
-       dbpath = tv_get_string(&argvars[1]);
-       if (argvars[2].v_type != VAR_UNKNOWN)
-           prepend = tv_get_string_buf(&argvars[2], buf);
-     }
- 
-     rettv->vval.v_number = cs_connection(num, dbpath, prepend);
- #endif
- }
- 
- /*
   * "cursor(lnum, col)" function, or
   * "cursor(list)"
   *
--- 2084,2089 ----
***************
*** 2322,2396 ****
  }
  
  /*
-  * "diff_filler()" function
-  */
-     static void
- f_diff_filler(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
- {
- #ifdef FEAT_DIFF
-     rettv->vval.v_number = diff_check_fill(curwin, tv_get_lnum(argvars));
- #endif
- }
- 
- /*
-  * "diff_hlID()" function
-  */
-     static void
- f_diff_hlID(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
- {
- #ifdef FEAT_DIFF
-     linenr_T          lnum = tv_get_lnum(argvars);
-     static linenr_T   prev_lnum = 0;
-     static varnumber_T        changedtick = 0;
-     static int                fnum = 0;
-     static int                change_start = 0;
-     static int                change_end = 0;
-     static hlf_T      hlID = (hlf_T)0;
-     int                       filler_lines;
-     int                       col;
- 
-     if (lnum < 0)     /* ignore type error in {lnum} arg */
-       lnum = 0;
-     if (lnum != prev_lnum
-           || changedtick != CHANGEDTICK(curbuf)
-           || fnum != curbuf->b_fnum)
-     {
-       /* New line, buffer, change: need to get the values. */
-       filler_lines = diff_check(curwin, lnum);
-       if (filler_lines < 0)
-       {
-           if (filler_lines == -1)
-           {
-               change_start = MAXCOL;
-               change_end = -1;
-               if (diff_find_change(curwin, lnum, &change_start, &change_end))
-                   hlID = HLF_ADD;     /* added line */
-               else
-                   hlID = HLF_CHD;     /* changed line */
-           }
-           else
-               hlID = HLF_ADD; /* added line */
-       }
-       else
-           hlID = (hlf_T)0;
-       prev_lnum = lnum;
-       changedtick = CHANGEDTICK(curbuf);
-       fnum = curbuf->b_fnum;
-     }
- 
-     if (hlID == HLF_CHD || hlID == HLF_TXD)
-     {
-       col = tv_get_number(&argvars[1]) - 1; /* ignore type error in {col} */
-       if (col >= change_start && col <= change_end)
-           hlID = HLF_TXD;                     /* changed text */
-       else
-           hlID = HLF_CHD;                     /* changed line */
-     }
-     rettv->vval.v_number = hlID == (hlf_T)0 ? 0 : (int)hlID;
- #endif
- }
- 
- /*
   * "empty({expr})" function
   */
      static void
--- 2284,2289 ----
***************
*** 6358,6384 ****
                                        | tv_get_number_chk(&argvars[1], NULL);
  }
  
- /*
-  * "pathshorten()" function
-  */
-     static void
- f_pathshorten(typval_T *argvars, typval_T *rettv)
- {
-     char_u    *p;
- 
-     rettv->v_type = VAR_STRING;
-     p = tv_get_string_chk(&argvars[0]);
-     if (p == NULL)
-       rettv->vval.v_string = NULL;
-     else
-     {
-       p = vim_strsave(p);
-       rettv->vval.v_string = p;
-       if (p != NULL)
-           shorten_dir(p);
-     }
- }
- 
  #ifdef FEAT_PERL
  /*
   * "perleval()" function
--- 6251,6256 ----
***************
*** 9472,9694 ****
  }
  #endif
  
- /*
-  * Get a callback from "arg".  It can be a Funcref or a function name.
-  * When "arg" is zero return an empty string.
-  * "cb_name" is not allocated.
-  * "cb_name" is set to NULL for an invalid argument.
-  */
-     callback_T
- get_callback(typval_T *arg)
- {
-     callback_T res;
- 
-     res.cb_free_name = FALSE;
-     if (arg->v_type == VAR_PARTIAL && arg->vval.v_partial != NULL)
-     {
-       res.cb_partial = arg->vval.v_partial;
-       ++res.cb_partial->pt_refcount;
-       res.cb_name = partial_name(res.cb_partial);
-     }
-     else
-     {
-       res.cb_partial = NULL;
-       if (arg->v_type == VAR_FUNC || arg->v_type == VAR_STRING)
-       {
-           // Note that we don't make a copy of the string.
-           res.cb_name = arg->vval.v_string;
-           func_ref(res.cb_name);
-       }
-       else if (arg->v_type == VAR_NUMBER && arg->vval.v_number == 0)
-       {
-           res.cb_name = (char_u *)"";
-       }
-       else
-       {
-           emsg(_("E921: Invalid callback argument"));
-           res.cb_name = NULL;
-       }
-     }
-     return res;
- }
- 
- /*
-  * Copy a callback into a typval_T.
-  */
-     void
- put_callback(callback_T *cb, typval_T *tv)
- {
-     if (cb->cb_partial != NULL)
-     {
-       tv->v_type = VAR_PARTIAL;
-       tv->vval.v_partial = cb->cb_partial;
-       ++tv->vval.v_partial->pt_refcount;
-     }
-     else
-     {
-       tv->v_type = VAR_FUNC;
-       tv->vval.v_string = vim_strsave(cb->cb_name);
-       func_ref(cb->cb_name);
-     }
- }
- 
- /*
-  * Make a copy of "src" into "dest", allocating the function name if needed,
-  * without incrementing the refcount.
-  */
-     void
- set_callback(callback_T *dest, callback_T *src)
- {
-     if (src->cb_partial == NULL)
-     {
-       // just a function name, make a copy
-       dest->cb_name = vim_strsave(src->cb_name);
-       dest->cb_free_name = TRUE;
-     }
-     else
-     {
-       // cb_name is a pointer into cb_partial
-       dest->cb_name = src->cb_name;
-       dest->cb_free_name = FALSE;
-     }
-     dest->cb_partial = src->cb_partial;
- }
- 
- /*
-  * Unref/free "callback" returned by get_callback() or set_callback().
-  */
-     void
- free_callback(callback_T *callback)
- {
-     if (callback->cb_partial != NULL)
-     {
-       partial_unref(callback->cb_partial);
-       callback->cb_partial = NULL;
-     }
-     else if (callback->cb_name != NULL)
-       func_unref(callback->cb_name);
-     if (callback->cb_free_name)
-     {
-       vim_free(callback->cb_name);
-       callback->cb_free_name = FALSE;
-     }
-     callback->cb_name = NULL;
- }
- 
- #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)tv_get_number(&argvars[0]));
-           if (timer != NULL)
-               add_timer_info(rettv, timer);
-       }
-     }
-     else
-       add_timer_info_all(rettv);
- }
- 
- /*
-  * "timer_pause(timer, paused)" function
-  */
-     static void
- f_timer_pause(typval_T *argvars, typval_T *rettv UNUSED)
- {
-     timer_T   *timer = NULL;
-     int               paused = (int)tv_get_number(&argvars[1]);
- 
-     if (argvars[0].v_type != VAR_NUMBER)
-       emsg(_(e_number_exp));
-     else
-     {
-       timer = find_timer((int)tv_get_number(&argvars[0]));
-       if (timer != NULL)
-           timer->tr_paused = paused;
-     }
- }
- 
- /*
-  * "timer_start(time, callback [, options])" function
-  */
-     static void
- f_timer_start(typval_T *argvars, typval_T *rettv)
- {
-     long      msec = (long)tv_get_number(&argvars[0]);
-     timer_T   *timer;
-     int               repeat = 0;
-     callback_T        callback;
-     dict_T    *dict;
- 
-     rettv->vval.v_number = -1;
-     if (check_secure())
-       return;
-     if (argvars[2].v_type != VAR_UNKNOWN)
-     {
-       if (argvars[2].v_type != VAR_DICT
-                                  || (dict = argvars[2].vval.v_dict) == NULL)
-       {
-           semsg(_(e_invarg2), tv_get_string(&argvars[2]));
-           return;
-       }
-       if (dict_find(dict, (char_u *)"repeat", -1) != NULL)
-           repeat = dict_get_number(dict, (char_u *)"repeat");
-     }
- 
-     callback = get_callback(&argvars[1]);
-     if (callback.cb_name == NULL)
-       return;
- 
-     timer = create_timer(msec, repeat);
-     if (timer == NULL)
-       free_callback(&callback);
-     else
-     {
-       set_callback(&timer->tr_callback, &callback);
-       rettv->vval.v_number = (varnumber_T)timer->tr_id;
-     }
- }
- 
- /*
-  * "timer_stop(timer)" function
-  */
-     static void
- f_timer_stop(typval_T *argvars, typval_T *rettv UNUSED)
- {
-     timer_T *timer;
- 
-     if (argvars[0].v_type != VAR_NUMBER)
-     {
-       emsg(_(e_number_exp));
-       return;
-     }
-     timer = find_timer((int)tv_get_number(&argvars[0]));
-     if (timer != NULL)
-       stop_timer(timer);
- }
- 
- /*
-  * "timer_stopall()" function
-  */
-     static void
- f_timer_stopall(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
- {
-     stop_all_timers();
- }
- #endif
- 
  /*
   * "tolower(string)" function
   */
--- 9344,9349 ----
*** ../vim-8.1.1988/src/proto/evalfunc.pro      2019-08-03 21:58:17.753476626 
+0200
--- src/proto/evalfunc.pro      2019-09-05 22:18:47.576212519 +0200
***************
*** 14,21 ****
  float_T vim_round(float_T f);
  long do_searchpair(char_u *spat, char_u *mpat, char_u *epat, int dir, 
typval_T *skip, int flags, pos_T *match_pos, linenr_T lnum_stop, long 
time_limit);
  void f_string(typval_T *argvars, typval_T *rettv);
- callback_T get_callback(typval_T *arg);
- void put_callback(callback_T *cb, typval_T *tv);
- void set_callback(callback_T *dest, callback_T *src);
- void free_callback(callback_T *callback);
  /* vim: set ft=c : */
--- 14,17 ----
*** ../vim-8.1.1988/src/filepath.c      2019-09-04 20:59:10.487410001 +0200
--- src/filepath.c      2019-09-05 21:58:40.449130391 +0200
***************
*** 1311,1316 ****
--- 1311,1337 ----
  }
  
  /*
+  * "pathshorten()" function
+  */
+     void
+ f_pathshorten(typval_T *argvars, typval_T *rettv)
+ {
+     char_u    *p;
+ 
+     rettv->v_type = VAR_STRING;
+     p = tv_get_string_chk(&argvars[0]);
+     if (p == NULL)
+       rettv->vval.v_string = NULL;
+     else
+     {
+       p = vim_strsave(p);
+       rettv->vval.v_string = p;
+       if (p != NULL)
+           shorten_dir(p);
+     }
+ }
+ 
+ /*
   * "readdir()" function
   */
      void
*** ../vim-8.1.1988/src/proto/filepath.pro      2019-09-04 20:59:10.491409987 
+0200
--- src/proto/filepath.pro      2019-09-05 21:59:36.936933760 +0200
***************
*** 20,25 ****
--- 20,26 ----
  void f_globpath(typval_T *argvars, typval_T *rettv);
  void f_isdirectory(typval_T *argvars, typval_T *rettv);
  void f_mkdir(typval_T *argvars, typval_T *rettv);
+ void f_pathshorten(typval_T *argvars, typval_T *rettv);
  void f_readdir(typval_T *argvars, typval_T *rettv);
  void f_readfile(typval_T *argvars, typval_T *rettv);
  void f_resolve(typval_T *argvars, typval_T *rettv);
*** ../vim-8.1.1988/src/if_cscope.c     2019-09-04 15:54:23.916359692 +0200
--- src/if_cscope.c     2019-09-05 22:06:27.459142131 +0200
***************
*** 384,390 ****
   *            Note: All string comparisons are case sensitive!
   */
  #if defined(FEAT_EVAL) || defined(PROTO)
!     int
  cs_connection(int num, char_u *dbpath, char_u *ppath)
  {
      int i;
--- 384,390 ----
   *            Note: All string comparisons are case sensitive!
   */
  #if defined(FEAT_EVAL) || defined(PROTO)
!     static int
  cs_connection(int num, char_u *dbpath, char_u *ppath)
  {
      int i;
***************
*** 430,436 ****
      }
  
      return FALSE;
! } /* cs_connection */
  #endif
  
  
--- 430,464 ----
      }
  
      return FALSE;
! }
! 
! /*
!  * "cscope_connection([{num} , {dbpath} [, {prepend}]])" function
!  *
!  * Checks the existence of a cscope connection.
!  */
!     void
! f_cscope_connection(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
! {
! #ifdef FEAT_CSCOPE
!     int               num = 0;
!     char_u    *dbpath = NULL;
!     char_u    *prepend = NULL;
!     char_u    buf[NUMBUFLEN];
! 
!     if (argvars[0].v_type != VAR_UNKNOWN
!           && argvars[1].v_type != VAR_UNKNOWN)
!     {
!       num = (int)tv_get_number(&argvars[0]);
!       dbpath = tv_get_string(&argvars[1]);
!       if (argvars[2].v_type != VAR_UNKNOWN)
!           prepend = tv_get_string_buf(&argvars[2], buf);
!     }
! 
!     rettv->vval.v_number = cs_connection(num, dbpath, prepend);
! #endif
! }
! 
  #endif
  
  
*** ../vim-8.1.1988/src/proto/if_cscope.pro     2018-05-17 13:52:38.000000000 
+0200
--- src/proto/if_cscope.pro     2019-09-05 22:06:29.231134618 +0200
***************
*** 7,12 ****
  int cs_fgets(char_u *buf, int size);
  void cs_free_tags(void);
  void cs_print_tags(void);
! int cs_connection(int num, char_u *dbpath, char_u *ppath);
  void cs_end(void);
  /* vim: set ft=c : */
--- 7,12 ----
  int cs_fgets(char_u *buf, int size);
  void cs_free_tags(void);
  void cs_print_tags(void);
! void f_cscope_connection(typval_T *argvars, typval_T *rettv);
  void cs_end(void);
  /* vim: set ft=c : */
*** ../vim-8.1.1988/src/diff.c  2019-08-24 20:54:15.979845564 +0200
--- src/diff.c  2019-09-05 22:09:21.998417515 +0200
***************
*** 3215,3218 ****
      return 0;
  }
  
! #endif        /* FEAT_DIFF */
--- 3215,3291 ----
      return 0;
  }
  
! #endif        // FEAT_DIFF
! 
! #if defined(FEAT_EVAL) || defined(PROTO)
! 
! /*
!  * "diff_filler()" function
!  */
!     void
! f_diff_filler(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
! {
! #ifdef FEAT_DIFF
!     rettv->vval.v_number = diff_check_fill(curwin, tv_get_lnum(argvars));
! #endif
! }
! 
! /*
!  * "diff_hlID()" function
!  */
!     void
! f_diff_hlID(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
! {
! #ifdef FEAT_DIFF
!     linenr_T          lnum = tv_get_lnum(argvars);
!     static linenr_T   prev_lnum = 0;
!     static varnumber_T        changedtick = 0;
!     static int                fnum = 0;
!     static int                change_start = 0;
!     static int                change_end = 0;
!     static hlf_T      hlID = (hlf_T)0;
!     int                       filler_lines;
!     int                       col;
! 
!     if (lnum < 0)     /* ignore type error in {lnum} arg */
!       lnum = 0;
!     if (lnum != prev_lnum
!           || changedtick != CHANGEDTICK(curbuf)
!           || fnum != curbuf->b_fnum)
!     {
!       /* New line, buffer, change: need to get the values. */
!       filler_lines = diff_check(curwin, lnum);
!       if (filler_lines < 0)
!       {
!           if (filler_lines == -1)
!           {
!               change_start = MAXCOL;
!               change_end = -1;
!               if (diff_find_change(curwin, lnum, &change_start, &change_end))
!                   hlID = HLF_ADD;     /* added line */
!               else
!                   hlID = HLF_CHD;     /* changed line */
!           }
!           else
!               hlID = HLF_ADD; /* added line */
!       }
!       else
!           hlID = (hlf_T)0;
!       prev_lnum = lnum;
!       changedtick = CHANGEDTICK(curbuf);
!       fnum = curbuf->b_fnum;
!     }
! 
!     if (hlID == HLF_CHD || hlID == HLF_TXD)
!     {
!       col = tv_get_number(&argvars[1]) - 1; /* ignore type error in {col} */
!       if (col >= change_start && col <= change_end)
!           hlID = HLF_TXD;                     /* changed text */
!       else
!           hlID = HLF_CHD;                     /* changed line */
!     }
!     rettv->vval.v_number = hlID == (hlf_T)0 ? 0 : (int)hlID;
! #endif
! }
! 
! #endif
*** ../vim-8.1.1988/src/proto/diff.pro  2019-08-24 20:54:15.979845564 +0200
--- src/proto/diff.pro  2019-09-05 22:09:26.050401044 +0200
***************
*** 27,30 ****
--- 27,32 ----
  int diff_move_to(int dir, long count);
  linenr_T diff_get_corresponding_line(buf_T *buf1, linenr_T lnum1);
  linenr_T diff_lnum_win(linenr_T lnum, win_T *wp);
+ void f_diff_filler(typval_T *argvars, typval_T *rettv);
+ void f_diff_hlID(typval_T *argvars, typval_T *rettv);
  /* vim: set ft=c : */
*** ../vim-8.1.1988/src/ex_cmds2.c      2019-08-25 15:40:39.662739502 +0200
--- src/ex_cmds2.c      2019-09-05 22:14:37.377168986 +0200
***************
*** 375,381 ****
      return abort;
  }
  
! #  if defined(EXITFREE) || defined(PROTO)
      void
  timer_free_all()
  {
--- 375,381 ----
      return abort;
  }
  
! # if defined(EXITFREE) || defined(PROTO)
      void
  timer_free_all()
  {
***************
*** 388,397 ****
        free_timer(timer);
      }
  }
- #  endif
  # endif
  
! #endif
  
  /*
   * If 'autowrite' option set, try to write the file.
--- 388,510 ----
        free_timer(timer);
      }
  }
  # endif
  
! /*
!  * "timer_info([timer])" function
!  */
!     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)tv_get_number(&argvars[0]));
!           if (timer != NULL)
!               add_timer_info(rettv, timer);
!       }
!     }
!     else
!       add_timer_info_all(rettv);
! }
! 
! /*
!  * "timer_pause(timer, paused)" function
!  */
!     void
! f_timer_pause(typval_T *argvars, typval_T *rettv UNUSED)
! {
!     timer_T   *timer = NULL;
!     int               paused = (int)tv_get_number(&argvars[1]);
! 
!     if (argvars[0].v_type != VAR_NUMBER)
!       emsg(_(e_number_exp));
!     else
!     {
!       timer = find_timer((int)tv_get_number(&argvars[0]));
!       if (timer != NULL)
!           timer->tr_paused = paused;
!     }
! }
! 
! /*
!  * "timer_start(time, callback [, options])" function
!  */
!     void
! f_timer_start(typval_T *argvars, typval_T *rettv)
! {
!     long      msec = (long)tv_get_number(&argvars[0]);
!     timer_T   *timer;
!     int               repeat = 0;
!     callback_T        callback;
!     dict_T    *dict;
! 
!     rettv->vval.v_number = -1;
!     if (check_secure())
!       return;
!     if (argvars[2].v_type != VAR_UNKNOWN)
!     {
!       if (argvars[2].v_type != VAR_DICT
!                                  || (dict = argvars[2].vval.v_dict) == NULL)
!       {
!           semsg(_(e_invarg2), tv_get_string(&argvars[2]));
!           return;
!       }
!       if (dict_find(dict, (char_u *)"repeat", -1) != NULL)
!           repeat = dict_get_number(dict, (char_u *)"repeat");
!     }
! 
!     callback = get_callback(&argvars[1]);
!     if (callback.cb_name == NULL)
!       return;
! 
!     timer = create_timer(msec, repeat);
!     if (timer == NULL)
!       free_callback(&callback);
!     else
!     {
!       set_callback(&timer->tr_callback, &callback);
!       rettv->vval.v_number = (varnumber_T)timer->tr_id;
!     }
! }
! 
! /*
!  * "timer_stop(timer)" function
!  */
!     void
! f_timer_stop(typval_T *argvars, typval_T *rettv UNUSED)
! {
!     timer_T *timer;
! 
!     if (argvars[0].v_type != VAR_NUMBER)
!     {
!       emsg(_(e_number_exp));
!       return;
!     }
!     timer = find_timer((int)tv_get_number(&argvars[0]));
!     if (timer != NULL)
!       stop_timer(timer);
! }
! 
! /*
!  * "timer_stopall()" function
!  */
!     void
! f_timer_stopall(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
! {
!     stop_all_timers();
! }
! 
! # endif // FEAT_TIMERS
! 
! #endif // FEAT_EVAL
  
  /*
   * If 'autowrite' option set, try to write the file.
*** ../vim-8.1.1988/src/proto/ex_cmds2.pro      2019-08-25 15:40:39.662739502 
+0200
--- src/proto/ex_cmds2.pro      2019-09-05 22:15:08.777047668 +0200
***************
*** 9,14 ****
--- 9,19 ----
  void add_timer_info_all(typval_T *rettv);
  int set_ref_in_timer(int copyID);
  void timer_free_all(void);
+ void f_timer_info(typval_T *argvars, typval_T *rettv);
+ void f_timer_pause(typval_T *argvars, typval_T *rettv);
+ void f_timer_start(typval_T *argvars, typval_T *rettv);
+ void f_timer_stop(typval_T *argvars, typval_T *rettv);
+ void f_timer_stopall(typval_T *argvars, typval_T *rettv);
  int autowrite(buf_T *buf, int forceit);
  void autowrite_all(void);
  int check_changed(buf_T *buf, int flags);
*** ../vim-8.1.1988/src/evalvars.c      2019-09-03 17:13:32.040528491 +0200
--- src/evalvars.c      2019-09-05 22:18:11.476349258 +0200
***************
*** 3467,3470 ****
--- 3467,3573 ----
      }
  }
  
+ /*
+  * Get a callback from "arg".  It can be a Funcref or a function name.
+  * When "arg" is zero return an empty string.
+  * "cb_name" is not allocated.
+  * "cb_name" is set to NULL for an invalid argument.
+  */
+     callback_T
+ get_callback(typval_T *arg)
+ {
+     callback_T res;
+ 
+     res.cb_free_name = FALSE;
+     if (arg->v_type == VAR_PARTIAL && arg->vval.v_partial != NULL)
+     {
+       res.cb_partial = arg->vval.v_partial;
+       ++res.cb_partial->pt_refcount;
+       res.cb_name = partial_name(res.cb_partial);
+     }
+     else
+     {
+       res.cb_partial = NULL;
+       if (arg->v_type == VAR_FUNC || arg->v_type == VAR_STRING)
+       {
+           // Note that we don't make a copy of the string.
+           res.cb_name = arg->vval.v_string;
+           func_ref(res.cb_name);
+       }
+       else if (arg->v_type == VAR_NUMBER && arg->vval.v_number == 0)
+       {
+           res.cb_name = (char_u *)"";
+       }
+       else
+       {
+           emsg(_("E921: Invalid callback argument"));
+           res.cb_name = NULL;
+       }
+     }
+     return res;
+ }
+ 
+ /*
+  * Copy a callback into a typval_T.
+  */
+     void
+ put_callback(callback_T *cb, typval_T *tv)
+ {
+     if (cb->cb_partial != NULL)
+     {
+       tv->v_type = VAR_PARTIAL;
+       tv->vval.v_partial = cb->cb_partial;
+       ++tv->vval.v_partial->pt_refcount;
+     }
+     else
+     {
+       tv->v_type = VAR_FUNC;
+       tv->vval.v_string = vim_strsave(cb->cb_name);
+       func_ref(cb->cb_name);
+     }
+ }
+ 
+ /*
+  * Make a copy of "src" into "dest", allocating the function name if needed,
+  * without incrementing the refcount.
+  */
+     void
+ set_callback(callback_T *dest, callback_T *src)
+ {
+     if (src->cb_partial == NULL)
+     {
+       // just a function name, make a copy
+       dest->cb_name = vim_strsave(src->cb_name);
+       dest->cb_free_name = TRUE;
+     }
+     else
+     {
+       // cb_name is a pointer into cb_partial
+       dest->cb_name = src->cb_name;
+       dest->cb_free_name = FALSE;
+     }
+     dest->cb_partial = src->cb_partial;
+ }
+ 
+ /*
+  * Unref/free "callback" returned by get_callback() or set_callback().
+  */
+     void
+ free_callback(callback_T *callback)
+ {
+     if (callback->cb_partial != NULL)
+     {
+       partial_unref(callback->cb_partial);
+       callback->cb_partial = NULL;
+     }
+     else if (callback->cb_name != NULL)
+       func_unref(callback->cb_name);
+     if (callback->cb_free_name)
+     {
+       vim_free(callback->cb_name);
+       callback->cb_free_name = FALSE;
+     }
+     callback->cb_name = NULL;
+ }
+ 
  #endif // FEAT_EVAL
*** ../vim-8.1.1988/src/proto/evalvars.pro      2019-09-04 15:54:23.916359692 
+0200
--- src/proto/evalvars.pro      2019-09-05 22:18:39.884241622 +0200
***************
*** 77,80 ****
--- 77,84 ----
  void f_settabwinvar(typval_T *argvars, typval_T *rettv);
  void f_setwinvar(typval_T *argvars, typval_T *rettv);
  void f_setbufvar(typval_T *argvars, typval_T *rettv);
+ callback_T get_callback(typval_T *arg);
+ void put_callback(callback_T *cb, typval_T *tv);
+ void set_callback(callback_T *dest, callback_T *src);
+ void free_callback(callback_T *callback);
  /* vim: set ft=c : */
*** ../vim-8.1.1988/src/version.c       2019-09-05 21:28:58.495157310 +0200
--- src/version.c       2019-09-05 22:33:04.925030754 +0200
***************
*** 759,760 ****
--- 759,762 ----
  {   /* Add new patch number below this line */
+ /**/
+     1989,
  /**/

-- 
hundred-and-one symptoms of being an internet addict:
194. Your business cards contain your e-mail and home page address.

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/201909052034.x85KYg6H027806%40masaka.moolenaar.net.

Raspunde prin e-mail lui