Patch 8.1.1943
Problem:    More code can be moved to evalvars.c.
Solution:   Move it, clean up comments.  Also move some window related
            functions to window.c. (Yegappan Lakshmanan, closes #4874)
Files:      src/eval.c, src/evalfunc.c, src/evalvars.c, src/proto/eval.pro,
            src/proto/evalvars.pro, src/proto/window.pro, src/window.c


*** ../vim-8.1.1942/src/eval.c  2019-08-29 22:48:20.921069540 +0200
--- src/eval.c  2019-08-30 14:13:18.816480045 +0200
***************
*** 6514,6622 ****
  }
  
  /*
-  * Find window specified by "vp" in tabpage "tp".
-  */
-     win_T *
- find_win_by_nr(
-     typval_T  *vp,
-     tabpage_T *tp)    /* NULL for current tab page */
- {
-     win_T     *wp;
-     int               nr = (int)tv_get_number_chk(vp, NULL);
- 
-     if (nr < 0)
-       return NULL;
-     if (nr == 0)
-       return curwin;
- 
-     FOR_ALL_WINDOWS_IN_TAB(tp, wp)
-     {
-       if (nr >= LOWEST_WIN_ID)
-       {
-           if (wp->w_id == nr)
-               return wp;
-       }
-       else if (--nr <= 0)
-           break;
-     }
-     if (nr >= LOWEST_WIN_ID)
-     {
- #ifdef FEAT_TEXT_PROP
-       // check tab-local popup windows
-       for (wp = tp->tp_first_popupwin; wp != NULL; wp = wp->w_next)
-           if (wp->w_id == nr)
-               return wp;
-       // check global popup windows
-       for (wp = first_popupwin; wp != NULL; wp = wp->w_next)
-           if (wp->w_id == nr)
-               return wp;
- #endif
-       return NULL;
-     }
-     return wp;
- }
- 
- /*
-  * Find a window: When using a Window ID in any tab page, when using a number
-  * in the current tab page.
-  */
-     win_T *
- find_win_by_nr_or_id(typval_T *vp)
- {
-     int       nr = (int)tv_get_number_chk(vp, NULL);
- 
-     if (nr >= LOWEST_WIN_ID)
-       return win_id2wp(tv_get_number(vp));
-     return find_win_by_nr(vp, NULL);
- }
- 
- /*
-  * Find window specified by "wvp" in tabpage "tvp".
-  * Returns the tab page in 'ptp'
-  */
-     win_T *
- find_tabwin(
-     typval_T  *wvp,   // VAR_UNKNOWN for current window
-     typval_T  *tvp,   // VAR_UNKNOWN for current tab page
-     tabpage_T **ptp)
- {
-     win_T     *wp = NULL;
-     tabpage_T *tp = NULL;
-     long      n;
- 
-     if (wvp->v_type != VAR_UNKNOWN)
-     {
-       if (tvp->v_type != VAR_UNKNOWN)
-       {
-           n = (long)tv_get_number(tvp);
-           if (n >= 0)
-               tp = find_tabpage(n);
-       }
-       else
-           tp = curtab;
- 
-       if (tp != NULL)
-       {
-           wp = find_win_by_nr(wvp, tp);
-           if (wp == NULL && wvp->v_type == VAR_NUMBER
-                                               && wvp->vval.v_number != -1)
-               // A window with the specified number is not found
-               tp = NULL;
-       }
-     }
-     else
-     {
-       wp = curwin;
-       tp = curtab;
-     }
- 
-     if (ptp != NULL)
-       *ptp = tp;
- 
-     return wp;
- }
- 
- /*
   * Skip over the name of an option: "&option", "&g:option" or "&l:option".
   * "arg" points to the "&" or '+' when called, to "option" when returning.
   * Returns NULL when no option name found.  Otherwise pointer to the char
--- 6514,6519 ----
*** ../vim-8.1.1942/src/evalfunc.c      2019-08-27 22:48:12.737480696 +0200
--- src/evalfunc.c      2019-08-30 14:10:09.617713145 +0200
***************
*** 21,27 ****
  #endif
  
  #ifdef MACOS_X
! # include <time.h>    /* for time_t */
  #endif
  
  static char *e_listblobarg = N_("E899: Argument of %s must be a List or 
Blob");
--- 21,27 ----
  #endif
  
  #ifdef MACOS_X
! # include <time.h>    // for time_t
  #endif
  
  static char *e_listblobarg = N_("E899: Argument of %s must be a List or 
Blob");
***************
*** 129,135 ****
  static void f_get(typval_T *argvars, typval_T *rettv);
  static void f_getbufinfo(typval_T *argvars, typval_T *rettv);
  static void f_getbufline(typval_T *argvars, typval_T *rettv);
- static void f_getbufvar(typval_T *argvars, typval_T *rettv);
  static void f_getchangelist(typval_T *argvars, typval_T *rettv);
  static void f_getchar(typval_T *argvars, typval_T *rettv);
  static void f_getcharmod(typval_T *argvars, typval_T *rettv);
--- 129,134 ----
***************
*** 280,286 ****
  static void f_server2client(typval_T *argvars, typval_T *rettv);
  static void f_serverlist(typval_T *argvars, typval_T *rettv);
  static void f_setbufline(typval_T *argvars, typval_T *rettv);
- static void f_setbufvar(typval_T *argvars, typval_T *rettv);
  static void f_setcharsearch(typval_T *argvars, typval_T *rettv);
  static void f_setcmdpos(typval_T *argvars, typval_T *rettv);
  static void f_setenv(typval_T *argvars, typval_T *rettv);
--- 279,284 ----
***************
*** 4394,4466 ****
  }
  
  /*
-  * "getbufvar()" function
-  */
-     static void
- f_getbufvar(typval_T *argvars, typval_T *rettv)
- {
-     buf_T     *buf;
-     buf_T     *save_curbuf;
-     char_u    *varname;
-     dictitem_T        *v;
-     int               done = FALSE;
- 
-     (void)tv_get_number(&argvars[0]);     /* issue errmsg if type error */
-     varname = tv_get_string_chk(&argvars[1]);
-     ++emsg_off;
-     buf = tv_get_buf(&argvars[0], FALSE);
- 
-     rettv->v_type = VAR_STRING;
-     rettv->vval.v_string = NULL;
- 
-     if (buf != NULL && varname != NULL)
-     {
-       /* set curbuf to be our buf, temporarily */
-       save_curbuf = curbuf;
-       curbuf = buf;
- 
-       if (*varname == '&')
-       {
-           if (varname[1] == NUL)
-           {
-               /* get all buffer-local options in a dict */
-               dict_T  *opts = get_winbuf_options(TRUE);
- 
-               if (opts != NULL)
-               {
-                   rettv_dict_set(rettv, opts);
-                   done = TRUE;
-               }
-           }
-           else if (get_option_tv(&varname, rettv, TRUE) == OK)
-               /* buffer-local-option */
-               done = TRUE;
-       }
-       else
-       {
-           /* Look up the variable. */
-           /* Let getbufvar({nr}, "") return the "b:" dictionary. */
-           v = find_var_in_ht(&curbuf->b_vars->dv_hashtab,
-                                                        'b', varname, FALSE);
-           if (v != NULL)
-           {
-               copy_tv(&v->di_tv, rettv);
-               done = TRUE;
-           }
-       }
- 
-       /* restore previous notion of curbuf */
-       curbuf = save_curbuf;
-     }
- 
-     if (!done && argvars[2].v_type != VAR_UNKNOWN)
-       /* use the default value */
-       copy_tv(&argvars[2], rettv);
- 
-     --emsg_off;
- }
- 
- /*
   * "getchangelist()" function
   */
      static void
--- 4392,4397 ----
***************
*** 9749,9811 ****
      }
  }
  
- /*
-  * "setbufvar()" function
-  */
-     static void
- f_setbufvar(typval_T *argvars, typval_T *rettv UNUSED)
- {
-     buf_T     *buf;
-     char_u    *varname, *bufvarname;
-     typval_T  *varp;
-     char_u    nbuf[NUMBUFLEN];
- 
-     if (check_secure())
-       return;
-     (void)tv_get_number(&argvars[0]);     /* issue errmsg if type error */
-     varname = tv_get_string_chk(&argvars[1]);
-     buf = tv_get_buf(&argvars[0], FALSE);
-     varp = &argvars[2];
- 
-     if (buf != NULL && varname != NULL && varp != NULL)
-     {
-       if (*varname == '&')
-       {
-           long        numval;
-           char_u      *strval;
-           int         error = FALSE;
-           aco_save_T  aco;
- 
-           /* set curbuf to be our buf, temporarily */
-           aucmd_prepbuf(&aco, buf);
- 
-           ++varname;
-           numval = (long)tv_get_number_chk(varp, &error);
-           strval = tv_get_string_buf_chk(varp, nbuf);
-           if (!error && strval != NULL)
-               set_option_value(varname, numval, strval, OPT_LOCAL);
- 
-           /* reset notion of buffer */
-           aucmd_restbuf(&aco);
-       }
-       else
-       {
-           buf_T *save_curbuf = curbuf;
- 
-           bufvarname = alloc(STRLEN(varname) + 3);
-           if (bufvarname != NULL)
-           {
-               curbuf = buf;
-               STRCPY(bufvarname, "b:");
-               STRCPY(bufvarname + 2, varname);
-               set_var(bufvarname, varp, TRUE);
-               vim_free(bufvarname);
-               curbuf = save_curbuf;
-           }
-       }
-     }
- }
- 
      static void
  f_setcharsearch(typval_T *argvars, typval_T *rettv UNUSED)
  {
--- 9680,9685 ----
*** ../vim-8.1.1942/src/evalvars.c      2019-08-29 22:48:20.921069540 +0200
--- src/evalvars.c      2019-08-30 14:14:24.676057198 +0200
***************
*** 46,55 ****
      char      vv_flags;       // VV_COMPAT, VV_RO, VV_RO_SBX
  } vimvars[VV_LEN] =
  {
!     /*
!      * The order here must match the VV_ defines in vim.h!
!      * Initializing a union does not work, leave tv.vval empty to get zero's.
!      */
      {VV_NAME("count",          VAR_NUMBER), VV_COMPAT+VV_RO},
      {VV_NAME("count1",                 VAR_NUMBER), VV_RO},
      {VV_NAME("prevcount",      VAR_NUMBER), VV_RO},
--- 46,53 ----
      char      vv_flags;       // VV_COMPAT, VV_RO, VV_RO_SBX
  } vimvars[VV_LEN] =
  {
!     // The order here must match the VV_ defines in vim.h!
!     // Initializing a union does not work, leave tv.vval empty to get zero's.
      {VV_NAME("count",          VAR_NUMBER), VV_COMPAT+VV_RO},
      {VV_NAME("count1",                 VAR_NUMBER), VV_RO},
      {VV_NAME("prevcount",      VAR_NUMBER), VV_RO},
***************
*** 1592,1598 ****
      if (len > varnamebuflen)
      {
        vim_free(varnamebuf);
!       len += 10;                      /* some additional space */
        varnamebuf = alloc(len);
        if (varnamebuf == NULL)
        {
--- 1590,1596 ----
      if (len > varnamebuflen)
      {
        vim_free(varnamebuf);
!       len += 10;                      // some additional space
        varnamebuf = alloc(len);
        if (varnamebuf == NULL)
        {
***************
*** 1701,1706 ****
--- 1699,1705 ----
  
  /*
   * Set number v: variable to "val".
+  * Note that this does not set the type, use set_vim_var_type() for that.
   */
      void
  set_vim_var_nr(int idx, varnumber_T val)
***************
*** 2078,2084 ****
      if (ret != NULL)
        return ret;
  
!     /* Search in parent scope for lambda */
      return find_var_in_scoped_ht(name, no_autoload || htp != NULL);
  }
  
--- 2077,2083 ----
      if (ret != NULL)
        return ret;
  
!     // Search in parent scope for lambda
      return find_var_in_scoped_ht(name, no_autoload || htp != NULL);
  }
  
***************
*** 2222,2230 ****
  
      if (ga_grow(&ga_scripts, (int)(id - ga_scripts.ga_len)) == OK)
      {
!       /* Re-allocating ga_data means that an ht_array pointing to
!        * ht_smallarray becomes invalid.  We can recognize this: ht_mask is
!        * at its init value.  Also reset "v_dict", it's always the same. */
        for (i = 1; i <= ga_scripts.ga_len; ++i)
        {
            ht = &SCRIPT_VARS(i);
--- 2221,2229 ----
  
      if (ga_grow(&ga_scripts, (int)(id - ga_scripts.ga_len)) == OK)
      {
!       // Re-allocating ga_data means that an ht_array pointing to
!       // ht_smallarray becomes invalid.  We can recognize this: ht_mask is
!       // at its init value.  Also reset "v_dict", it's always the same.
        for (i = 1; i <= ga_scripts.ga_len; ++i)
        {
            ht = &SCRIPT_VARS(i);
***************
*** 2269,2276 ****
      void
  unref_var_dict(dict_T *dict)
  {
!     /* Now the dict needs to be freed if no one else is using it, go back to
!      * normal reference counting. */
      dict->dv_refcount -= DO_NOT_FREE_CNT - 1;
      dict_unref(dict);
  }
--- 2268,2275 ----
      void
  unref_var_dict(dict_T *dict)
  {
!     // Now the dict needs to be freed if no one else is using it, go back to
!     // normal reference counting.
      dict->dv_refcount -= DO_NOT_FREE_CNT - 1;
      dict_unref(dict);
  }
***************
*** 2817,2823 ****
      struct vimvar   *vp = &vimvars[VV_ERRORS];
  
      if (vp->vv_type != VAR_LIST || vimvars[VV_ERRORS].vv_list == NULL)
!       /* Make sure v:errors is a list. */
        set_vim_var_list(VV_ERRORS, list_alloc());
      list_append_string(vimvars[VV_ERRORS].vv_list, gap->ga_data, gap->ga_len);
  }
--- 2816,2822 ----
      struct vimvar   *vp = &vimvars[VV_ERRORS];
  
      if (vp->vv_type != VAR_LIST || vimvars[VV_ERRORS].vv_list == NULL)
!       // Make sure v:errors is a list.
        set_vim_var_list(VV_ERRORS, list_alloc());
      list_append_string(vimvars[VV_ERRORS].vv_list, gap->ga_data, gap->ga_len);
  }
***************
*** 2916,2921 ****
--- 2915,2987 ----
  }
  
  /*
+  * "getbufvar()" function
+  */
+     void
+ f_getbufvar(typval_T *argvars, typval_T *rettv)
+ {
+     buf_T     *buf;
+     buf_T     *save_curbuf;
+     char_u    *varname;
+     dictitem_T        *v;
+     int               done = FALSE;
+ 
+     (void)tv_get_number(&argvars[0]);     // issue errmsg if type error
+     varname = tv_get_string_chk(&argvars[1]);
+     ++emsg_off;
+     buf = tv_get_buf(&argvars[0], FALSE);
+ 
+     rettv->v_type = VAR_STRING;
+     rettv->vval.v_string = NULL;
+ 
+     if (buf != NULL && varname != NULL)
+     {
+       // set curbuf to be our buf, temporarily
+       save_curbuf = curbuf;
+       curbuf = buf;
+ 
+       if (*varname == '&')
+       {
+           if (varname[1] == NUL)
+           {
+               // get all buffer-local options in a dict
+               dict_T  *opts = get_winbuf_options(TRUE);
+ 
+               if (opts != NULL)
+               {
+                   rettv_dict_set(rettv, opts);
+                   done = TRUE;
+               }
+           }
+           else if (get_option_tv(&varname, rettv, TRUE) == OK)
+               // buffer-local-option
+               done = TRUE;
+       }
+       else
+       {
+           // Look up the variable.
+           // Let getbufvar({nr}, "") return the "b:" dictionary.
+           v = find_var_in_ht(&curbuf->b_vars->dv_hashtab,
+                                                        'b', varname, FALSE);
+           if (v != NULL)
+           {
+               copy_tv(&v->di_tv, rettv);
+               done = TRUE;
+           }
+       }
+ 
+       // restore previous notion of curbuf
+       curbuf = save_curbuf;
+     }
+ 
+     if (!done && argvars[2].v_type != VAR_UNKNOWN)
+       // use the default value
+       copy_tv(&argvars[2], rettv);
+ 
+     --emsg_off;
+ }
+ 
+ /*
   * "settabvar()" function
   */
      void
***************
*** 2973,2976 ****
--- 3039,3099 ----
      setwinvar(argvars, rettv, 0);
  }
  
+ /*
+  * "setbufvar()" function
+  */
+     void
+ f_setbufvar(typval_T *argvars, typval_T *rettv UNUSED)
+ {
+     buf_T     *buf;
+     char_u    *varname, *bufvarname;
+     typval_T  *varp;
+     char_u    nbuf[NUMBUFLEN];
+ 
+     if (check_secure())
+       return;
+     (void)tv_get_number(&argvars[0]);     // issue errmsg if type error
+     varname = tv_get_string_chk(&argvars[1]);
+     buf = tv_get_buf(&argvars[0], FALSE);
+     varp = &argvars[2];
+ 
+     if (buf != NULL && varname != NULL && varp != NULL)
+     {
+       if (*varname == '&')
+       {
+           long        numval;
+           char_u      *strval;
+           int         error = FALSE;
+           aco_save_T  aco;
+ 
+           // set curbuf to be our buf, temporarily
+           aucmd_prepbuf(&aco, buf);
+ 
+           ++varname;
+           numval = (long)tv_get_number_chk(varp, &error);
+           strval = tv_get_string_buf_chk(varp, nbuf);
+           if (!error && strval != NULL)
+               set_option_value(varname, numval, strval, OPT_LOCAL);
+ 
+           // reset notion of buffer
+           aucmd_restbuf(&aco);
+       }
+       else
+       {
+           buf_T *save_curbuf = curbuf;
+ 
+           bufvarname = alloc(STRLEN(varname) + 3);
+           if (bufvarname != NULL)
+           {
+               curbuf = buf;
+               STRCPY(bufvarname, "b:");
+               STRCPY(bufvarname + 2, varname);
+               set_var(bufvarname, varp, TRUE);
+               vim_free(bufvarname);
+               curbuf = save_curbuf;
+           }
+       }
+     }
+ }
+ 
  #endif // FEAT_EVAL
*** ../vim-8.1.1942/src/proto/eval.pro  2019-08-29 22:09:42.608429189 +0200
--- src/proto/eval.pro  2019-08-30 14:10:09.617713145 +0200
***************
*** 80,88 ****
  void ex_echo(exarg_T *eap);
  void ex_echohl(exarg_T *eap);
  void ex_execute(exarg_T *eap);
- win_T *find_win_by_nr(typval_T *vp, tabpage_T *tp);
- win_T *find_win_by_nr_or_id(typval_T *vp);
- win_T *find_tabwin(typval_T *wvp, typval_T *tvp, tabpage_T **ptp);
  char_u *find_option_end(char_u **arg, int *opt_flags);
  char_u *autoload_name(char_u *name);
  int script_autoload(char_u *name, int reload);
--- 80,85 ----
*** ../vim-8.1.1942/src/proto/evalvars.pro      2019-08-29 22:48:20.921069540 
+0200
--- src/proto/evalvars.pro      2019-08-30 14:10:09.617713145 +0200
***************
*** 58,64 ****
--- 58,66 ----
  void f_gettabvar(typval_T *argvars, typval_T *rettv);
  void f_gettabwinvar(typval_T *argvars, typval_T *rettv);
  void f_getwinvar(typval_T *argvars, typval_T *rettv);
+ void f_getbufvar(typval_T *argvars, typval_T *rettv);
  void f_settabvar(typval_T *argvars, typval_T *rettv);
  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);
  /* vim: set ft=c : */
*** ../vim-8.1.1942/src/proto/window.pro        2019-08-20 20:13:40.334821916 
+0200
--- src/proto/window.pro        2019-08-30 14:12:11.252916994 +0200
***************
*** 89,93 ****
--- 89,96 ----
  win_T *win_id2wp_tp(int id, tabpage_T **tpp);
  int win_id2win(typval_T *argvars);
  void win_findbuf(typval_T *argvars, list_T *list);
+ win_T *find_win_by_nr(typval_T *vp, tabpage_T *tp);
+ win_T *find_win_by_nr_or_id(typval_T *vp);
+ win_T *find_tabwin(typval_T *wvp, typval_T *tvp, tabpage_T **ptp);
  void get_framelayout(frame_T *fr, list_T *l, int outer);
  /* vim: set ft=c : */
*** ../vim-8.1.1942/src/window.c        2019-08-25 22:24:58.871357010 +0200
--- src/window.c        2019-08-30 14:12:07.824939257 +0200
***************
*** 6970,6975 ****
--- 6970,7078 ----
  }
  
  /*
+  * Find window specified by "vp" in tabpage "tp".
+  */
+     win_T *
+ find_win_by_nr(
+     typval_T  *vp,
+     tabpage_T *tp)    // NULL for current tab page
+ {
+     win_T     *wp;
+     int               nr = (int)tv_get_number_chk(vp, NULL);
+ 
+     if (nr < 0)
+       return NULL;
+     if (nr == 0)
+       return curwin;
+ 
+     FOR_ALL_WINDOWS_IN_TAB(tp, wp)
+     {
+       if (nr >= LOWEST_WIN_ID)
+       {
+           if (wp->w_id == nr)
+               return wp;
+       }
+       else if (--nr <= 0)
+           break;
+     }
+     if (nr >= LOWEST_WIN_ID)
+     {
+ #ifdef FEAT_TEXT_PROP
+       // check tab-local popup windows
+       for (wp = tp->tp_first_popupwin; wp != NULL; wp = wp->w_next)
+           if (wp->w_id == nr)
+               return wp;
+       // check global popup windows
+       for (wp = first_popupwin; wp != NULL; wp = wp->w_next)
+           if (wp->w_id == nr)
+               return wp;
+ #endif
+       return NULL;
+     }
+     return wp;
+ }
+ 
+ /*
+  * Find a window: When using a Window ID in any tab page, when using a number
+  * in the current tab page.
+  */
+     win_T *
+ find_win_by_nr_or_id(typval_T *vp)
+ {
+     int       nr = (int)tv_get_number_chk(vp, NULL);
+ 
+     if (nr >= LOWEST_WIN_ID)
+       return win_id2wp(tv_get_number(vp));
+     return find_win_by_nr(vp, NULL);
+ }
+ 
+ /*
+  * Find window specified by "wvp" in tabpage "tvp".
+  * Returns the tab page in 'ptp'
+  */
+     win_T *
+ find_tabwin(
+     typval_T  *wvp,   // VAR_UNKNOWN for current window
+     typval_T  *tvp,   // VAR_UNKNOWN for current tab page
+     tabpage_T **ptp)
+ {
+     win_T     *wp = NULL;
+     tabpage_T *tp = NULL;
+     long      n;
+ 
+     if (wvp->v_type != VAR_UNKNOWN)
+     {
+       if (tvp->v_type != VAR_UNKNOWN)
+       {
+           n = (long)tv_get_number(tvp);
+           if (n >= 0)
+               tp = find_tabpage(n);
+       }
+       else
+           tp = curtab;
+ 
+       if (tp != NULL)
+       {
+           wp = find_win_by_nr(wvp, tp);
+           if (wp == NULL && wvp->v_type == VAR_NUMBER
+                                               && wvp->vval.v_number != -1)
+               // A window with the specified number is not found
+               tp = NULL;
+       }
+     }
+     else
+     {
+       wp = curwin;
+       tp = curtab;
+     }
+ 
+     if (ptp != NULL)
+       *ptp = tp;
+ 
+     return wp;
+ }
+ 
+ /*
   * Get the layout of the given tab page for winlayout().
   */
      void
*** ../vim-8.1.1942/src/version.c       2019-08-30 13:59:26.446291285 +0200
--- src/version.c       2019-08-30 14:11:41.809108535 +0200
***************
*** 763,764 ****
--- 763,766 ----
  {   /* Add new patch number below this line */
+ /**/
+     1943,
  /**/

-- 
Amazing but true: If all the salmon caught in Canada in one year were laid
end to end across the Sahara Desert, the smell would be absolutely awful.

 /// 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/201908301347.x7UDl3A6004954%40masaka.moolenaar.net.

Raspunde prin e-mail lui