]> granicus.if.org Git - vim/commitdiff
patch 8.2.0605: Vim9: cannot unlet an environment variable v8.2.0605
authorBram Moolenaar <Bram@vim.org>
Sun, 19 Apr 2020 16:27:26 +0000 (18:27 +0200)
committerBram Moolenaar <Bram@vim.org>
Sun, 19 Apr 2020 16:27:26 +0000 (18:27 +0200)
Problem:    Vim9: cannot unlet an environment variable.
Solution:   Implement unlet for $VAR.

src/testdir/test_vim9_disassemble.vim
src/testdir/test_vim9_script.vim
src/version.c
src/vim9.h
src/vim9compile.c
src/vim9execute.c

index 7f6d86a56e0cd459245f1ac4a4e0e637bc313af5..78149527896035277da1f47010d187a3af330aca 100644 (file)
@@ -130,6 +130,7 @@ def s:ScriptFuncUnlet()
   g:somevar = "value"
   unlet g:somevar
   unlet! g:somevar
+  unlet $SOMEVAR
 enddef
 
 def Test_disassemble_unlet()
@@ -141,7 +142,9 @@ def Test_disassemble_unlet()
         'unlet g:somevar.*' ..
         '\d UNLET g:somevar.*' ..
         'unlet! g:somevar.*' ..
-        '\d UNLET! g:somevar.*',
+        '\d UNLET! g:somevar.*' ..
+        'unlet $SOMEVAR.*' ..
+        '\d UNLETENV $SOMEVAR.*',
         res)
 enddef
 
index 568338b27b35af0f4c81bfc7011297655cdb39d2..4b7339961f68f032d4fada28a6f1869665ae376e 100644 (file)
@@ -289,6 +289,11 @@ def Test_unlet()
         '  unlet s:svar',
         'enddef',
         ], 'E1081:')
+
+  $ENVVAR = 'foobar'
+  assert_equal('foobar', $ENVVAR)
+  unlet $ENVVAR
+  assert_equal('', $ENVVAR)
 enddef
 
 func Test_wrong_type()
index 89021265abb4fbac92daf2186b6119fec14b874c..7af2e50e5a1d74e79b71f6335c013c969ee541fa 100644 (file)
@@ -746,6 +746,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    605,
 /**/
     604,
 /**/
index 64749ce1b51fd8ffb1cfb98491d7356216fb6111..a75e1752cd7e1ef50b8242eab2ad14777b333a67 100644 (file)
@@ -45,6 +45,7 @@ typedef enum {
     ISN_STORENR,    // store number into local variable isn_arg.storenr.stnr_idx
 
     ISN_UNLET,         // unlet variable isn_arg.unlet.ul_name
+    ISN_UNLETENV,      // unlet environment variable isn_arg.unlet.ul_name
 
     // constants
     ISN_PUSHNR,                // push number isn_arg.number
index c4a5c08d89d58e3e1b72f8b91ea717bd72a3f524..daa1cbea41170017687bcdf336fba5d2c6bb0e0c 100644 (file)
@@ -990,12 +990,12 @@ generate_LOADV(
  * Generate an ISN_UNLET instruction.
  */
     static int
-generate_UNLET(cctx_T *cctx, char_u *name, int forceit)
+generate_UNLET(cctx_T *cctx, isntype_T isn_type, char_u *name, int forceit)
 {
     isn_T      *isn;
 
     RETURN_OK_IF_SKIP(cctx);
-    if ((isn = generate_instr(cctx, ISN_UNLET)) == NULL)
+    if ((isn = generate_instr(cctx, isn_type)) == NULL)
        return FAIL;
     isn->isn_arg.unlet.ul_name = vim_strsave(name);
     isn->isn_arg.unlet.ul_forceit = forceit;
@@ -4594,10 +4594,12 @@ compile_unlet(
 
        // Normal name.  Only supports g:, w:, t: and b: namespaces.
        *name_end = NUL;
-       if (check_vim9_unlet(p) == FAIL)
+       if (*p == '$')
+           ret = generate_UNLET(cctx, ISN_UNLETENV, p + 1, eap->forceit);
+       else if (check_vim9_unlet(p) == FAIL)
            ret = FAIL;
        else
-           ret = generate_UNLET(cctx, p, eap->forceit);
+           ret = generate_UNLET(cctx, ISN_UNLET, p, eap->forceit);
 
        *name_end = cc;
        return ret;
@@ -6363,6 +6365,7 @@ delete_instr(isn_T *isn)
            break;
 
        case ISN_UNLET:
+       case ISN_UNLETENV:
            vim_free(isn->isn_arg.unlet.ul_name);
            break;
 
index e6758698c4bedd88d6ca9a28d889cc97de5971cc..6c8b8c86eab13897c20d2a965282db0edab01411 100644 (file)
@@ -1073,6 +1073,9 @@ call_def_function(
                                       iptr->isn_arg.unlet.ul_forceit) == FAIL)
                    goto failed;
                break;
+           case ISN_UNLETENV:
+               vim_unsetenv(iptr->isn_arg.unlet.ul_name);
+               break;
 
            // create a list from items on the stack; uses a single allocation
            // for the list header and the items
@@ -2119,6 +2122,11 @@ ex_disassemble(exarg_T *eap)
                        iptr->isn_arg.unlet.ul_forceit ? "!" : "",
                        iptr->isn_arg.unlet.ul_name);
                break;
+           case ISN_UNLETENV:
+               smsg("%4d UNLETENV%s $%s", current,
+                       iptr->isn_arg.unlet.ul_forceit ? "!" : "",
+                       iptr->isn_arg.unlet.ul_name);
+               break;
            case ISN_NEWLIST:
                smsg("%4d NEWLIST size %lld", current,
                                            (long long)(iptr->isn_arg.number));