]> granicus.if.org Git - vim/commitdiff
patch 8.2.3015: Vim9: Assigning to @# requires a string v8.2.3015
authorBram Moolenaar <Bram@vim.org>
Thu, 17 Jun 2021 19:03:07 +0000 (21:03 +0200)
committerBram Moolenaar <Bram@vim.org>
Thu, 17 Jun 2021 19:03:07 +0000 (21:03 +0200)
Problem:    Vim9: Assigning to @# requires a string. (Naohiro Ono)
Solution:   Accent a number or a string. (closes #8396)

src/globals.h
src/testdir/test_vim9_assign.vim
src/version.c
src/vim9compile.c
src/vim9execute.c

index 77ea16943405a37e77b1e6b4bd5b786fd2b4b908..07acc2602b8eb3936f2c1cc4a79a120ac1e69996 100644 (file)
@@ -418,6 +418,9 @@ EXTERN type_T t_blob INIT6(VAR_BLOB, 0, 0, TTFLAG_STATIC, NULL, NULL);
 EXTERN type_T t_job INIT6(VAR_JOB, 0, 0, TTFLAG_STATIC, NULL, NULL);
 EXTERN type_T t_channel INIT6(VAR_CHANNEL, 0, 0, TTFLAG_STATIC, NULL, NULL);
 
+// Special value used for @#.
+EXTERN type_T t_number_or_string INIT6(VAR_STRING, 0, 0, TTFLAG_STATIC, NULL, NULL);
+
 EXTERN type_T t_func_unknown INIT6(VAR_FUNC, -1, 0, TTFLAG_STATIC, &t_unknown, NULL);
 EXTERN type_T t_func_void INIT6(VAR_FUNC, -1, 0, TTFLAG_STATIC, &t_void, NULL);
 EXTERN type_T t_func_any INIT6(VAR_FUNC, -1, 0, TTFLAG_STATIC, &t_any, NULL);
index 7b7b62305be88cd9aceeee7f429b2eb64c98842d..1cbdcfb4661fffdb28ebb84da5602f66d60e1df2 100644 (file)
@@ -1820,6 +1820,19 @@ def Test_assign_command_modifier()
   CheckDefAndScriptSuccess(lines)
 enddef
 
+def Test_assign_alt_buf_register()
+  var lines =<< trim END
+      edit 'file_b1'
+      var b1 = bufnr()
+      edit 'file_b2'
+      var b2 = bufnr()
+      assert_equal(b1, bufnr('#'))
+      @# = b2
+      assert_equal(b2, bufnr('#'))
+  END
+  CheckDefAndScriptSuccess(lines)
+enddef
+
 def Test_script_funcref_case()
   var lines =<< trim END
       var Len = (s: string): number => len(s) + 1
index 99c086f5b587b5ab72b4463adecd630226e6f0a6..4f33d35d87932043ecf77d7ff610aed9ad175698 100644 (file)
@@ -750,6 +750,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    3015,
 /**/
     3014,
 /**/
index 404c819e7800c71ffcfdfdc9d348164b7f3f638c..e4656c99af5a018bb4a830dac2628285f013fbab 100644 (file)
@@ -5852,7 +5852,7 @@ get_var_dest(
            return FAIL;
        }
        *dest = dest_reg;
-       *type = &t_string;
+       *type = name[1] == '#' ? &t_number_or_string : &t_string;
     }
     else if (STRNCMP(name, "g:", 2) == 0)
     {
@@ -5927,7 +5927,8 @@ generate_store_var(
        case dest_env:
            return generate_STORE(cctx, ISN_STOREENV, 0, name + 1);
        case dest_reg:
-           return generate_STORE(cctx, ISN_STOREREG, name[1], NULL);
+           return generate_STORE(cctx, ISN_STOREREG,
+                                        name[1] == '@' ? '"' : name[1], NULL);
        case dest_vimvar:
            return generate_STORE(cctx, ISN_STOREV, vimvaridx, NULL);
        case dest_script:
@@ -6843,9 +6844,19 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
                            goto theend;
                    }
                }
-               else if (*p != '=' && need_type(rhs_type, lhs.lhs_member_type,
+               else
+               {
+                   type_T *lhs_type = lhs.lhs_member_type;
+
+                   // Special case: assigning to @# can use a number or a
+                   // string.
+                   if (lhs_type == &t_number_or_string
+                                           && rhs_type->tt_type == VAR_NUMBER)
+                       lhs_type = &t_number;
+                   if (*p != '=' && need_type(rhs_type, lhs_type,
                                            -1, 0, cctx, FALSE, FALSE) == FAIL)
                    goto theend;
+               }
            }
            else if (cmdidx == CMD_final)
            {
index fabce4dbe7c86bb2d29619f6daa731d8580a244e..2577e63e2761e79bed36dcb5dc28a90258529f66 100644 (file)
@@ -2182,8 +2182,7 @@ exec_instructions(ectx_T *ectx)
 
                    --ectx->ec_stack.ga_len;
                    tv = STACK_TV_BOT(0);
-                   write_reg_contents(reg == '@' ? '"' : reg,
-                                                tv_get_string(tv), -1, FALSE);
+                   write_reg_contents(reg, tv_get_string(tv), -1, FALSE);
                    clear_tv(tv);
                }
                break;