diff options
| -rw-r--r-- | runtime/doc/eval.txt | 8 | ||||
| -rw-r--r-- | src/nvim/eval.c | 12 | ||||
| -rw-r--r-- | src/nvim/ex_docmd.c | 13 | ||||
| -rw-r--r-- | src/nvim/testdir/test_unlet.vim | 34 | 
4 files changed, 65 insertions, 2 deletions
| diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index 064c08c190..2e1d89c524 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -9136,6 +9136,14 @@ This does NOT work: >  			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/nvim/eval.c b/src/nvim/eval.c index 41a9eeeb40..2aab2d72a7 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -2818,6 +2818,18 @@ static void ex_unletlock(exarg_T *eap, char_u *argstart, int deep)    lval_T lv;    do { +    if (*arg == '$') { +      const char *name = (char *)++arg; + +      if (get_env_len((const char_u **)&arg) == 0) { +        EMSG2(_(e_invarg2), name - 1); +        return; +      } +      os_unsetenv(name); +      arg = skipwhite(arg); +      continue; +    } +      // Parse the name and find the end.      char_u *const name_end = (char_u *)get_lval(arg, NULL, &lv, true,                                                  eap->skip || error, diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index f8d4e7d980..2a733f5831 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -3260,8 +3260,15 @@ const char * set_one_cmd_context(      while ((xp->xp_pattern = (char_u *)strchr(arg, ' ')) != NULL) {        arg = (const char *)xp->xp_pattern + 1;      } +      xp->xp_context = EXPAND_USER_VARS;      xp->xp_pattern = (char_u *)arg; + +    if (*xp->xp_pattern == '$') { +      xp->xp_context = EXPAND_ENV_VARS; +      xp->xp_pattern++; +    } +      break;    case CMD_function: @@ -9049,8 +9056,10 @@ makeopens(      // cursor can be set.  This is done again below.      // winminheight and winminwidth need to be set to avoid an error if the      // user has set winheight or winwidth. -    if (put_line(fd, "set winminheight=1 winminwidth=1 winheight=1 winwidth=1") -        == FAIL) { +    if (put_line(fd, "set winminheight=0") == FAIL +        || put_line(fd, "set winheight=1") == FAIL +        || put_line(fd, "set winminwidth=0") == FAIL +        || put_line(fd, "set winwidth=1") == FAIL) {        return FAIL;      }      if (nr > 1 && ses_winsizes(fd, restore_size, tab_firstwin) == FAIL) { diff --git a/src/nvim/testdir/test_unlet.vim b/src/nvim/testdir/test_unlet.vim index 3f06058d03..b02bdaab3b 100644 --- a/src/nvim/testdir/test_unlet.vim +++ b/src/nvim/testdir/test_unlet.vim @@ -28,3 +28,37 @@ 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 + +func Test_unlet_complete() +  let g:FOOBAR = 1 +  call feedkeys(":unlet g:FOO\t\n", 'tx') +  call assert_true(!exists('g:FOOBAR')) + +  let $FOOBAR = 1 +  call feedkeys(":unlet $FOO\t\n", 'tx') +  call assert_true(!exists('$FOOBAR') || empty($FOOBAR)) +endfunc | 
