# HG changeset patch # User Christian Brabandt # Date 1526220007 -7200 # Node ID e4d5726e1678d7f56a738730c94b656416a91d6c # Parent 1a30d378b70bfbc605d9f94245fce44e4cda5159 patch 8.0.1832: cannot use :unlet for an environment variable commit https://github.com/vim/vim/commit/137374fd6538cf9dee0cb22907728d8fdecb5832 Author: Bram Moolenaar Date: Sun May 13 15:59:50 2018 +0200 patch 8.0.1832: cannot use :unlet for an environment variable Problem: Cannot use :unlet for an environment variable. Solution: Make it work. Use unsetenv() if available. (Ken Takata, closes #2855) diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -9939,6 +9939,14 @@ 7. Commands *expression-commands* variables are automatically deleted when the function ends. +:unl[et] ${env-name} ... *:unlet-environment* *:unlet-$* + Remove environment variable {env-name}. + Can mix {name} and ${env-name} in one :unlet command. + No error message is given for a non-existing + variable, also without !. + If the system does not support deleting an environment + variable, it is made emtpy. + :lockv[ar][!] [depth] {name} ... *:lockvar* *:lockv* Lock the internal variable {name}. Locking means that it can no longer be changed (until it is unlocked). diff --git a/src/auto/configure b/src/auto/configure --- a/src/auto/configure +++ b/src/auto/configure @@ -12609,7 +12609,7 @@ for ac_func in fchdir fchown fchmod fsyn getpgid setpgid setsid sigaltstack sigstack sigset sigsetjmp sigaction \ sigprocmask sigvec strcasecmp strerror strftime stricmp strncasecmp \ strnicmp strpbrk strtol tgetent towlower towupper iswupper \ - usleep utime utimes mblen ftruncate + usleep utime utimes mblen ftruncate unsetenv do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" diff --git a/src/config.h.in b/src/config.h.in --- a/src/config.h.in +++ b/src/config.h.in @@ -211,6 +211,7 @@ #undef HAVE_TOWLOWER #undef HAVE_TOWUPPER #undef HAVE_ISWUPPER +#undef HAVE_UNSETENV #undef HAVE_USLEEP #undef HAVE_UTIME #undef HAVE_BIND_TEXTDOMAIN_CODESET diff --git a/src/configure.ac b/src/configure.ac --- a/src/configure.ac +++ b/src/configure.ac @@ -3709,7 +3709,7 @@ AC_CHECK_FUNCS(fchdir fchown fchmod fsyn getpgid setpgid setsid sigaltstack sigstack sigset sigsetjmp sigaction \ sigprocmask sigvec strcasecmp strerror strftime stricmp strncasecmp \ strnicmp strpbrk strtol tgetent towlower towupper iswupper \ - usleep utime utimes mblen ftruncate) + usleep utime utimes mblen ftruncate unsetenv) AC_FUNC_FSEEKO dnl define _LARGE_FILES, _FILE_OFFSET_BITS and _LARGEFILE_SOURCE when diff --git a/src/eval.c b/src/eval.c --- a/src/eval.c +++ b/src/eval.c @@ -2758,6 +2758,20 @@ ex_unletlock( do { + if (*arg == '$') + { + char_u *name = ++arg; + + if (get_env_len(&arg) == 0) + { + EMSG2(_(e_invarg2), name - 1); + return; + } + vim_unsetenv(name); + arg = skipwhite(arg); + continue; + } + /* Parse the name and find the end. */ name_end = get_lval(arg, NULL, &lv, TRUE, eap->skip || error, 0, FNE_CHECK_START); diff --git a/src/misc1.c b/src/misc1.c --- a/src/misc1.c +++ b/src/misc1.c @@ -4479,6 +4479,17 @@ remove_tail(char_u *p, char_u *pend, cha return pend; } + void +vim_unsetenv(char_u *var) +{ +#ifdef HAVE_UNSETENV + unsetenv((char *)var); +#else + mch_setenv((char *)var, "", 0); +#endif +} + + /* * Our portable version of setenv. */ diff --git a/src/proto/misc1.pro b/src/proto/misc1.pro --- a/src/proto/misc1.pro +++ b/src/proto/misc1.pro @@ -60,6 +60,7 @@ void expand_env(char_u *src, char_u *dst void expand_env_esc(char_u *srcp, char_u *dst, int dstlen, int esc, int one, char_u *startstr); char_u *vim_getenv(char_u *name, int *mustfree); void vim_setenv(char_u *name, char_u *val); +void vim_unsetenv(char_u *name); char_u *get_env_name(expand_T *xp, int idx); char_u *get_users(expand_T *xp, int idx); int match_user(char_u *name); diff --git a/src/testdir/test_unlet.vim b/src/testdir/test_unlet.vim --- a/src/testdir/test_unlet.vim +++ b/src/testdir/test_unlet.vim @@ -21,3 +21,27 @@ endfunc func Test_unlet_fails() call assert_fails('unlet v:["count"]', 'E46:') endfunc + +func Test_unlet_env() + let envcmd = has('win32') ? 'set' : 'env' + + let $FOOBAR = 'test' + let found = 0 + for kv in split(system(envcmd), "\r*\n") + if kv == 'FOOBAR=test' + let found = 1 + endif + endfor + call assert_equal(1, found) + + unlet $FOOBAR + let found = 0 + for kv in split(system(envcmd), "\r*\n") + if kv == 'FOOBAR=test' + let found = 1 + endif + endfor + call assert_equal(0, found) + + unlet $MUST_NOT_BE_AN_ERROR +endfunc diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -762,6 +762,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1832, +/**/ 1831, /**/ 1830,