changeset 20099:058b41f85bcb v8.2.0605

patch 8.2.0605: Vim9: cannot unlet an environment variable Commit: https://github.com/vim/vim/commit/7bdaea6e0df849cf3dd7eaaf454eb88f637d1884 Author: Bram Moolenaar <Bram@vim.org> Date: Sun Apr 19 18:27:26 2020 +0200 patch 8.2.0605: Vim9: cannot unlet an environment variable Problem: Vim9: cannot unlet an environment variable. Solution: Implement unlet for $VAR.
author Bram Moolenaar <Bram@vim.org>
date Sun, 19 Apr 2020 18:30:04 +0200
parents a901238a18a2
children 6c52f2ebe4e7
files src/testdir/test_vim9_disassemble.vim src/testdir/test_vim9_script.vim src/version.c src/vim9.h src/vim9compile.c src/vim9execute.c
diffstat 6 files changed, 27 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/src/testdir/test_vim9_disassemble.vim
+++ b/src/testdir/test_vim9_disassemble.vim
@@ -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
 
--- a/src/testdir/test_vim9_script.vim
+++ b/src/testdir/test_vim9_script.vim
@@ -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()
--- a/src/version.c
+++ b/src/version.c
@@ -747,6 +747,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    605,
+/**/
     604,
 /**/
     603,
--- a/src/vim9.h
+++ b/src/vim9.h
@@ -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
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -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;
 
--- a/src/vim9execute.c
+++ b/src/vim9execute.c
@@ -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));