Patch 8.2.3866
Problem:    Vim9: type checking global variables is inconsistent.
Solution:   Use the "unknown" type in more places.
Files:      src/globals.h, src/vim9expr.c, src/vim9instr.c, src/vim9cmds.c,
            src/evalfunc.c, src/testdir/test_vim9_func.vim


*** ../vim-8.2.3865/src/globals.h       2021-12-17 20:15:30.448830724 +0000
--- src/globals.h       2021-12-21 10:24:45.896882818 +0000
***************
*** 404,412 ****
--- 404,419 ----
  
  
  // Commonly used types.
+ // "unknown" is used for when the type is really unknown, e.g. global
+ // variables.  Also for when a function may or may not return something.
  EXTERN type_T t_unknown INIT6(VAR_UNKNOWN, 0, 0, TTFLAG_STATIC, NULL, NULL);
+ 
+ // "any" is used for when the type is mixed.  Excludes "void".
  EXTERN type_T t_any INIT6(VAR_ANY, 0, 0, TTFLAG_STATIC, NULL, NULL);
+ 
+ // "void" is used for a function not returning anything.
  EXTERN type_T t_void INIT6(VAR_VOID, 0, 0, TTFLAG_STATIC, NULL, NULL);
+ 
  EXTERN type_T t_bool INIT6(VAR_BOOL, 0, 0, TTFLAG_STATIC, NULL, NULL);
  EXTERN type_T t_special INIT6(VAR_SPECIAL, 0, 0, TTFLAG_STATIC, NULL, NULL);
  EXTERN type_T t_number INIT6(VAR_NUMBER, 0, 0, TTFLAG_STATIC, NULL, NULL);
*** ../vim-8.2.3865/src/vim9expr.c      2021-12-20 15:03:23.247346527 +0000
--- src/vim9expr.c      2021-12-21 12:23:36.524687742 +0000
***************
*** 90,96 ****
      vartype = (*typep)->tt_type;
      idxtype = ((type_T **)stack->ga_data)[stack->ga_len - 1];
      // If the index is a string, the variable must be a Dict.
!     if (*typep == &t_any && idxtype == &t_string)
        vartype = VAR_DICT;
      if (vartype == VAR_STRING || vartype == VAR_LIST || vartype == VAR_BLOB)
      {
--- 90,96 ----
      vartype = (*typep)->tt_type;
      idxtype = ((type_T **)stack->ga_data)[stack->ga_len - 1];
      // If the index is a string, the variable must be a Dict.
!     if ((*typep == &t_any || *typep == &t_unknown) && idxtype == &t_string)
        vartype = VAR_DICT;
      if (vartype == VAR_STRING || vartype == VAR_LIST || vartype == VAR_BLOB)
      {
***************
*** 156,162 ****
                return FAIL;
        }
      }
!     else if (vartype == VAR_LIST || *typep == &t_any)
      {
        if (is_slice)
        {
--- 156,162 ----
                return FAIL;
        }
      }
!     else if (vartype == VAR_LIST || *typep == &t_any || *typep == &t_unknown)
      {
        if (is_slice)
        {
***************
*** 415,421 ****
                // Global, Buffer-local, Window-local and Tabpage-local
                // variables can be defined later, thus we don't check if it
                // exists, give an error at runtime.
!               res = generate_LOAD(cctx, isn_type, 0, name, &t_any);
            }
        }
      }
--- 415,421 ----
                // Global, Buffer-local, Window-local and Tabpage-local
                // variables can be defined later, thus we don't check if it
                // exists, give an error at runtime.
!               res = generate_LOAD(cctx, isn_type, 0, name, &t_unknown);
            }
        }
      }
***************
*** 1428,1434 ****
      if (type == &t_bool)
        return OK;
  
!     if (type == &t_any || type == &t_number || type == &t_number_bool)
        // Number 0 and 1 are OK to use as a bool.  "any" could also be a bool.
        // This requires a runtime type check.
        return generate_COND2BOOL(cctx);
--- 1428,1437 ----
      if (type == &t_bool)
        return OK;
  
!     if (type == &t_any
!           || type == &t_unknown
!           || type == &t_number
!           || type == &t_number_bool)
        // Number 0 and 1 are OK to use as a bool.  "any" could also be a bool.
        // This requires a runtime type check.
        return generate_COND2BOOL(cctx);
***************
*** 2155,2163 ****
  
        generate_ppconst(cctx, ppconst);
        actual = ((type_T **)stack->ga_data)[stack->ga_len - 1];
!       if (check_type(want_type, actual, FALSE, where) == FAIL)
        {
!           if (need_type(actual, want_type, -1, 0, cctx, FALSE, FALSE) == FAIL)
                return FAIL;
        }
      }
--- 2158,2167 ----
  
        generate_ppconst(cctx, ppconst);
        actual = ((type_T **)stack->ga_data)[stack->ga_len - 1];
!       if (check_type_maybe(want_type, actual, FALSE, where) != OK)
        {
!           if (need_type(actual, want_type, -1, 0, cctx, FALSE, FALSE)
!                                                                      == FAIL)
                return FAIL;
        }
      }
*** ../vim-8.2.3865/src/vim9instr.c     2021-12-21 09:42:05.626265159 +0000
--- src/vim9instr.c     2021-12-21 11:17:05.112606053 +0000
***************
*** 168,176 ****
      static int
  check_number_or_float(vartype_T type1, vartype_T type2, char_u *op)
  {
!     if (!((type1 == VAR_NUMBER || type1 == VAR_FLOAT || type1 == VAR_ANY)
            && (type2 == VAR_NUMBER || type2 == VAR_FLOAT
!                                                        || type2 == VAR_ANY)))
      {
        if (*op == '+')
            emsg(_(e_wrong_argument_type_for_plus));
--- 168,177 ----
      static int
  check_number_or_float(vartype_T type1, vartype_T type2, char_u *op)
  {
!     if (!((type1 == VAR_NUMBER || type1 == VAR_FLOAT
!                                  || type1 == VAR_ANY || type1 == VAR_UNKNOWN)
            && (type2 == VAR_NUMBER || type2 == VAR_FLOAT
!                                || type2 == VAR_ANY || type2 == VAR_UNKNOWN)))
      {
        if (*op == '+')
            emsg(_(e_wrong_argument_type_for_plus));
***************
*** 204,210 ****
--- 205,213 ----
  
      if (vartype != VAR_LIST && vartype != VAR_BLOB
            && type1->tt_type != VAR_ANY
+           && type1->tt_type != VAR_UNKNOWN
            && type2->tt_type != VAR_ANY
+           && type2->tt_type != VAR_UNKNOWN
            && check_number_or_float(
                        type1->tt_type, type2->tt_type, (char_u *)"+") == FAIL)
        return FAIL;
***************
*** 293,300 ****
--- 296,305 ----
                  break;
  
        case '%': if ((type1->tt_type != VAR_ANY
+                             && type1->tt_type != VAR_UNKNOWN
                                               && type1->tt_type != VAR_NUMBER)
                          || (type2->tt_type != VAR_ANY
+                             && type2->tt_type != VAR_UNKNOWN
                                              && type2->tt_type != VAR_NUMBER))
                  {
                      emsg(_(e_percent_requires_number_arguments));
***************
*** 1528,1534 ****
  
      RETURN_OK_IF_SKIP(cctx);
  
!     if (type->tt_type == VAR_ANY)
        ret_type = &t_any;
      else if (type->tt_type == VAR_FUNC || type->tt_type == VAR_PARTIAL)
      {
--- 1533,1539 ----
  
      RETURN_OK_IF_SKIP(cctx);
  
!     if (type->tt_type == VAR_ANY || type->tt_type == VAR_UNKNOWN)
        ret_type = &t_any;
      else if (type->tt_type == VAR_FUNC || type->tt_type == VAR_PARTIAL)
      {
***************
*** 1620,1626 ****
  
      // check for dict type
      type = ((type_T **)stack->ga_data)[stack->ga_len - 1];
!     if (type->tt_type != VAR_DICT && type != &t_any)
      {
        char *tofree;
  
--- 1625,1631 ----
  
      // check for dict type
      type = ((type_T **)stack->ga_data)[stack->ga_len - 1];
!     if (type->tt_type != VAR_DICT && type != &t_any && type != &t_unknown)
      {
        char *tofree;
  
*** ../vim-8.2.3865/src/vim9cmds.c      2021-12-21 09:42:05.626265159 +0000
--- src/vim9cmds.c      2021-12-21 11:20:32.837049712 +0000
***************
*** 843,850 ****
        // If we know the type of "var" and it is a not a supported type we can
        // give an error now.
        vartype = ((type_T **)stack->ga_data)[stack->ga_len - 1];
!       if (vartype->tt_type != VAR_LIST && vartype->tt_type != VAR_STRING
!               && vartype->tt_type != VAR_BLOB && vartype->tt_type != VAR_ANY)
        {
            semsg(_(e_for_loop_on_str_not_supported),
                                               vartype_name(vartype->tt_type));
--- 843,853 ----
        // If we know the type of "var" and it is a not a supported type we can
        // give an error now.
        vartype = ((type_T **)stack->ga_data)[stack->ga_len - 1];
!       if (vartype->tt_type != VAR_LIST
!               && vartype->tt_type != VAR_STRING
!               && vartype->tt_type != VAR_BLOB
!               && vartype->tt_type != VAR_ANY
!               && vartype->tt_type != VAR_UNKNOWN)
        {
            semsg(_(e_for_loop_on_str_not_supported),
                                               vartype_name(vartype->tt_type));
*** ../vim-8.2.3865/src/evalfunc.c      2021-12-20 09:36:20.101548272 +0000
--- src/evalfunc.c      2021-12-21 10:46:29.346624953 +0000
***************
*** 228,234 ****
  arg_float_or_nr(type_T *type, argcontext_T *context)
  {
      if (type->tt_type == VAR_ANY
!                 || type->tt_type == VAR_FLOAT || type->tt_type == VAR_NUMBER)
        return OK;
      arg_type_mismatch(&t_number, type, context->arg_idx + 1);
      return FAIL;
--- 228,236 ----
  arg_float_or_nr(type_T *type, argcontext_T *context)
  {
      if (type->tt_type == VAR_ANY
!           || type->tt_type == VAR_UNKNOWN
!           || type->tt_type == VAR_FLOAT
!           || type->tt_type == VAR_NUMBER)
        return OK;
      arg_type_mismatch(&t_number, type, context->arg_idx + 1);
      return FAIL;
***************
*** 313,319 ****
  arg_list_or_blob(type_T *type, argcontext_T *context)
  {
      if (type->tt_type == VAR_ANY
!                    || type->tt_type == VAR_LIST || type->tt_type == VAR_BLOB)
        return OK;
      arg_type_mismatch(&t_list_any, type, context->arg_idx + 1);
      return FAIL;
--- 315,323 ----
  arg_list_or_blob(type_T *type, argcontext_T *context)
  {
      if (type->tt_type == VAR_ANY
!           || type->tt_type == VAR_UNKNOWN
!           || type->tt_type == VAR_LIST
!           || type->tt_type == VAR_BLOB)
        return OK;
      arg_type_mismatch(&t_list_any, type, context->arg_idx + 1);
      return FAIL;
***************
*** 326,332 ****
  arg_string_or_nr(type_T *type, argcontext_T *context)
  {
      if (type->tt_type == VAR_ANY
!           || type->tt_type == VAR_STRING || type->tt_type == VAR_NUMBER)
        return OK;
      arg_type_mismatch(&t_string, type, context->arg_idx + 1);
      return FAIL;
--- 330,338 ----
  arg_string_or_nr(type_T *type, argcontext_T *context)
  {
      if (type->tt_type == VAR_ANY
!           || type->tt_type == VAR_UNKNOWN
!           || type->tt_type == VAR_STRING
!           || type->tt_type == VAR_NUMBER)
        return OK;
      arg_type_mismatch(&t_string, type, context->arg_idx + 1);
      return FAIL;
***************
*** 339,345 ****
  arg_buffer(type_T *type, argcontext_T *context)
  {
      if (type->tt_type == VAR_ANY
!           || type->tt_type == VAR_STRING || type->tt_type == VAR_NUMBER)
        return OK;
      arg_type_mismatch(&t_string, type, context->arg_idx + 1);
      return FAIL;
--- 345,353 ----
  arg_buffer(type_T *type, argcontext_T *context)
  {
      if (type->tt_type == VAR_ANY
!           || type->tt_type == VAR_UNKNOWN
!           || type->tt_type == VAR_STRING
!           || type->tt_type == VAR_NUMBER)
        return OK;
      arg_type_mismatch(&t_string, type, context->arg_idx + 1);
      return FAIL;
***************
*** 352,357 ****
--- 360,366 ----
  arg_buffer_or_dict_any(type_T *type, argcontext_T *context)
  {
      if (type->tt_type == VAR_ANY
+           || type->tt_type == VAR_UNKNOWN
            || type->tt_type == VAR_STRING
            || type->tt_type == VAR_NUMBER
            || type->tt_type == VAR_DICT)
***************
*** 367,373 ****
  arg_lnum(type_T *type, argcontext_T *context)
  {
      if (type->tt_type == VAR_ANY
!           || type->tt_type == VAR_STRING || type->tt_type == VAR_NUMBER)
        return OK;
      arg_type_mismatch(&t_string, type, context->arg_idx + 1);
      return FAIL;
--- 376,384 ----
  arg_lnum(type_T *type, argcontext_T *context)
  {
      if (type->tt_type == VAR_ANY
!           || type->tt_type == VAR_UNKNOWN
!           || type->tt_type == VAR_STRING
!           || type->tt_type == VAR_NUMBER)
        return OK;
      arg_type_mismatch(&t_string, type, context->arg_idx + 1);
      return FAIL;
***************
*** 379,385 ****
      static int
  arg_string_or_list_string(type_T *type, argcontext_T *context)
  {
!     if (type->tt_type == VAR_ANY || type->tt_type == VAR_STRING)
        return OK;
      if (type->tt_type != VAR_LIST)
      {
--- 390,398 ----
      static int
  arg_string_or_list_string(type_T *type, argcontext_T *context)
  {
!     if (type->tt_type == VAR_ANY
!           || type->tt_type == VAR_UNKNOWN
!           || type->tt_type == VAR_STRING)
        return OK;
      if (type->tt_type != VAR_LIST)
      {
***************
*** 401,407 ****
  arg_string_or_list_any(type_T *type, argcontext_T *context)
  {
      if (type->tt_type == VAR_ANY
!           || type->tt_type == VAR_STRING || type->tt_type == VAR_LIST)
        return OK;
      arg_type_mismatch(&t_string, type, context->arg_idx + 1);
      return FAIL;
--- 414,422 ----
  arg_string_or_list_any(type_T *type, argcontext_T *context)
  {
      if (type->tt_type == VAR_ANY
!           || type->tt_type == VAR_UNKNOWN
!           || type->tt_type == VAR_STRING
!           || type->tt_type == VAR_LIST)
        return OK;
      arg_type_mismatch(&t_string, type, context->arg_idx + 1);
      return FAIL;
***************
*** 414,420 ****
  arg_string_or_blob(type_T *type, argcontext_T *context)
  {
      if (type->tt_type == VAR_ANY
!           || type->tt_type == VAR_STRING || type->tt_type == VAR_BLOB)
        return OK;
      arg_type_mismatch(&t_string, type, context->arg_idx + 1);
      return FAIL;
--- 429,437 ----
  arg_string_or_blob(type_T *type, argcontext_T *context)
  {
      if (type->tt_type == VAR_ANY
!           || type->tt_type == VAR_UNKNOWN
!           || type->tt_type == VAR_STRING
!           || type->tt_type == VAR_BLOB)
        return OK;
      arg_type_mismatch(&t_string, type, context->arg_idx + 1);
      return FAIL;
***************
*** 427,433 ****
  arg_list_or_dict(type_T *type, argcontext_T *context)
  {
      if (type->tt_type == VAR_ANY
!                    || type->tt_type == VAR_LIST || type->tt_type == VAR_DICT)
        return OK;
      arg_type_mismatch(&t_list_any, type, context->arg_idx + 1);
      return FAIL;
--- 444,452 ----
  arg_list_or_dict(type_T *type, argcontext_T *context)
  {
      if (type->tt_type == VAR_ANY
!           || type->tt_type == VAR_UNKNOWN
!           || type->tt_type == VAR_LIST
!           || type->tt_type == VAR_DICT)
        return OK;
      arg_type_mismatch(&t_list_any, type, context->arg_idx + 1);
      return FAIL;
***************
*** 440,448 ****
  arg_list_or_dict_or_blob(type_T *type, argcontext_T *context)
  {
      if (type->tt_type == VAR_ANY
!                    || type->tt_type == VAR_LIST
!                    || type->tt_type == VAR_DICT
!                    || type->tt_type == VAR_BLOB)
        return OK;
      arg_type_mismatch(&t_list_any, type, context->arg_idx + 1);
      return FAIL;
--- 459,468 ----
  arg_list_or_dict_or_blob(type_T *type, argcontext_T *context)
  {
      if (type->tt_type == VAR_ANY
!           || type->tt_type == VAR_UNKNOWN
!           || type->tt_type == VAR_LIST
!           || type->tt_type == VAR_DICT
!           || type->tt_type == VAR_BLOB)
        return OK;
      arg_type_mismatch(&t_list_any, type, context->arg_idx + 1);
      return FAIL;
***************
*** 455,464 ****
  arg_list_or_dict_or_blob_or_string(type_T *type, argcontext_T *context)
  {
      if (type->tt_type == VAR_ANY
!                    || type->tt_type == VAR_LIST
!                    || type->tt_type == VAR_DICT
!                    || type->tt_type == VAR_BLOB
!                    || type->tt_type == VAR_STRING)
        return OK;
      arg_type_mismatch(&t_list_any, type, context->arg_idx + 1);
      return FAIL;
--- 475,485 ----
  arg_list_or_dict_or_blob_or_string(type_T *type, argcontext_T *context)
  {
      if (type->tt_type == VAR_ANY
!           || type->tt_type == VAR_UNKNOWN
!           || type->tt_type == VAR_LIST
!           || type->tt_type == VAR_DICT
!           || type->tt_type == VAR_BLOB
!           || type->tt_type == VAR_STRING)
        return OK;
      arg_type_mismatch(&t_list_any, type, context->arg_idx + 1);
      return FAIL;
***************
*** 471,479 ****
  arg_string_list_or_blob(type_T *type, argcontext_T *context)
  {
      if (type->tt_type == VAR_ANY
!                    || type->tt_type == VAR_LIST
!                    || type->tt_type == VAR_BLOB
!                    || type->tt_type == VAR_STRING)
        return OK;
      arg_type_mismatch(&t_list_any, type, context->arg_idx + 1);
      return FAIL;
--- 492,501 ----
  arg_string_list_or_blob(type_T *type, argcontext_T *context)
  {
      if (type->tt_type == VAR_ANY
!           || type->tt_type == VAR_UNKNOWN
!           || type->tt_type == VAR_LIST
!           || type->tt_type == VAR_BLOB
!           || type->tt_type == VAR_STRING)
        return OK;
      arg_type_mismatch(&t_list_any, type, context->arg_idx + 1);
      return FAIL;
***************
*** 495,500 ****
--- 517,523 ----
  arg_chan_or_job(type_T *type, argcontext_T *context)
  {
      if (type->tt_type == VAR_ANY
+           || type->tt_type == VAR_UNKNOWN
            || type->tt_type == VAR_CHANNEL
            || type->tt_type == VAR_JOB)
        return OK;
***************
*** 557,565 ****
  arg_str_or_nr_or_list(type_T *type, argcontext_T *context)
  {
      if (type->tt_type == VAR_ANY
!               || type->tt_type == VAR_STRING
!               || type->tt_type == VAR_NUMBER
!               || type->tt_type == VAR_LIST)
        return OK;
      arg_type_mismatch(&t_string, type, context->arg_idx + 1);
      return FAIL;
--- 580,589 ----
  arg_str_or_nr_or_list(type_T *type, argcontext_T *context)
  {
      if (type->tt_type == VAR_ANY
!           || type->tt_type == VAR_UNKNOWN
!           || type->tt_type == VAR_STRING
!           || type->tt_type == VAR_NUMBER
!           || type->tt_type == VAR_LIST)
        return OK;
      arg_type_mismatch(&t_string, type, context->arg_idx + 1);
      return FAIL;
***************
*** 572,579 ****
  arg_dict_any_or_string(type_T *type, argcontext_T *context)
  {
      if (type->tt_type == VAR_ANY
!               || type->tt_type == VAR_DICT
!               || type->tt_type == VAR_STRING)
        return OK;
      arg_type_mismatch(&t_string, type, context->arg_idx + 1);
      return FAIL;
--- 596,604 ----
  arg_dict_any_or_string(type_T *type, argcontext_T *context)
  {
      if (type->tt_type == VAR_ANY
!           || type->tt_type == VAR_UNKNOWN
!           || type->tt_type == VAR_DICT
!           || type->tt_type == VAR_STRING)
        return OK;
      arg_type_mismatch(&t_string, type, context->arg_idx + 1);
      return FAIL;
***************
*** 603,608 ****
--- 628,634 ----
  arg_get1(type_T *type, argcontext_T *context)
  {
      if (type->tt_type == VAR_ANY
+           || type->tt_type == VAR_UNKNOWN
            || type->tt_type == VAR_BLOB
            || type->tt_type == VAR_LIST
            || type->tt_type == VAR_DICT
***************
*** 622,627 ****
--- 648,654 ----
  arg_len1(type_T *type, argcontext_T *context)
  {
      if (type->tt_type == VAR_ANY
+           || type->tt_type == VAR_UNKNOWN
            || type->tt_type == VAR_STRING
            || type->tt_type == VAR_NUMBER
            || type->tt_type == VAR_BLOB
***************
*** 657,662 ****
--- 684,690 ----
  arg_repeat1(type_T *type, argcontext_T *context)
  {
      if (type->tt_type == VAR_ANY
+           || type->tt_type == VAR_UNKNOWN
            || type->tt_type == VAR_STRING
            || type->tt_type == VAR_NUMBER
            || type->tt_type == VAR_LIST)
***************
*** 674,679 ****
--- 702,708 ----
  arg_slice1(type_T *type, argcontext_T *context)
  {
      if (type->tt_type == VAR_ANY
+           || type->tt_type == VAR_UNKNOWN
            || type->tt_type == VAR_LIST
            || type->tt_type == VAR_BLOB
            || type->tt_type == VAR_STRING)
***************
*** 691,696 ****
--- 720,726 ----
  arg_count1(type_T *type, argcontext_T *context)
  {
      if (type->tt_type == VAR_ANY
+           || type->tt_type == VAR_UNKNOWN
            || type->tt_type == VAR_STRING
            || type->tt_type == VAR_LIST
            || type->tt_type == VAR_DICT)
***************
*** 708,713 ****
--- 738,744 ----
  arg_cursor1(type_T *type, argcontext_T *context)
  {
      if (type->tt_type == VAR_ANY
+           || type->tt_type == VAR_UNKNOWN
            || type->tt_type == VAR_NUMBER
            || type->tt_type == VAR_STRING
            || type->tt_type == VAR_LIST)
*** ../vim-8.2.3865/src/testdir/test_vim9_func.vim      2021-12-19 
18:33:17.325954806 +0000
--- src/testdir/test_vim9_func.vim      2021-12-21 11:29:00.517302071 +0000
***************
*** 547,552 ****
--- 547,585 ----
        defcompile
    END
    CheckScriptFailure(lines, 'E1001: Variable not found: b')
+ 
+   # using script variable requires matching type or type cast
+   lines =<< trim END
+       vim9script
+       var a: any
+       def Func(arg: string = a)
+         echo arg
+       enddef
+       defcompile
+   END
+   CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected 
string but got any')
+ 
+   lines =<< trim END
+       vim9script
+       var a: any
+       def Func(arg: string = <string>a)
+         echo arg
+       enddef
+       a = 'works'
+       Func()
+   END
+   CheckScriptSuccess(lines)
+ 
+   # using global variable does not require type cast
+   lines =<< trim END
+       vim9script
+       def Func(arg: string = g:str)
+         echo arg
+       enddef
+       g:str = 'works'
+       Func()
+   END
+   CheckScriptSuccess(lines)
  enddef
  
  def FuncWithComment(  # comment
*** ../vim-8.2.3865/src/version.c       2021-12-21 09:42:05.626265159 +0000
--- src/version.c       2021-12-21 10:28:53.488316227 +0000
***************
*** 751,752 ****
--- 751,754 ----
  {   /* Add new patch number below this line */
+ /**/
+     3866,
  /**/

-- 
>From "know your smileys":
 :-O>-o   Smiley American tourist (note big mouth and camera)

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///                                                                      \\\
\\\        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
 \\\            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/20211221123252.A38661C0DCA%40moolenaar.net.

Raspunde prin e-mail lui