Patch 8.1.1305
Problem:    There is no easy way to manipulate environment variables.
Solution:   Add environ(), getenv() and setenv(). (Yasuhiro Matsumoto,
            closes #2875)
Files:      runtime/doc/eval.txt, runtime/doc/usr_41.txt, src/evalfunc.c,
            src/testdir/Make_all.mak, src/testdir/test_environ.vim


*** ../vim-8.1.1304/runtime/doc/eval.txt        2019-05-09 13:50:13.366401975 
+0200
--- runtime/doc/eval.txt        2019-05-09 14:44:18.849767366 +0200
***************
*** 1369,1374 ****
--- 1369,1381 ----
  
  The String value of any environment variable.  When it is not defined, the
  result is an empty string.
+ 
+ The functions `getenv()` and `setenv()` can also be used and work for
+ environment variables with non-alphanumeric names.
+ The function `environ()` can be used to get a Dict with all environment
+ variables.
+ 
+ 
                                                *expr-env-expand*
  Note that there is a difference between using $VAR directly and using
  expand("$VAR").  Using it directly will only expand environment variables that
***************
*** 2303,2308 ****
--- 2310,2316 ----
  diff_filler({lnum})           Number  diff filler lines about {lnum}
  diff_hlID({lnum}, {col})      Number  diff highlighting at {lnum}/{col}
  empty({expr})                 Number  |TRUE| if {expr} is empty
+ environ()                     Dict    return environment variables
  escape({string}, {chars})     String  escape {chars} in {string} with '\'
  eval({string})                        any     evaluate {string} into its value
  eventhandler()                        Number  |TRUE| if inside an event 
handler
***************
*** 2360,2365 ****
--- 2368,2374 ----
                                List    list of cmdline completion matches
  getcurpos()                   List    position of the cursor
  getcwd([{winnr} [, {tabnr}]]) String  get the current working directory
+ getenv({name})                        String  return environment variable
  getfontname([{name}])         String  name of font being used
  getfperm({fname})             String  file permissions of file {fname}
  getfsize({fname})             Number  size in bytes of file {fname}
***************
*** 2568,2573 ****
--- 2577,2583 ----
                                none    set {varname} in buffer {expr} to {val}
  setcharsearch({dict})         Dict    set character search from {dict}
  setcmdpos({pos})              Number  set cursor position in command-line
+ setenv({name}, {val})         none    set environment variable
  setfperm({fname}, {mode})     Number  set {fname} file permissions to {mode}
  setline({lnum}, {line})               Number  set line {lnum} to {line}
  setloclist({nr}, {list} [, {action} [, {what}]])
***************
*** 3905,3910 ****
--- 3915,3928 ----
                The highlight ID can be used with |synIDattr()| to obtain
                syntax information about the highlighting.
  
+ environ()                                             *environ()*
+               Return all of environment variables as dictionary. You can
+               check if an environment variable exists like this: >
+                       :echo has_key(environ(), 'HOME')
+ <             Note that the variable name may be CamelCase; to ignore case
+               use this: >
+                       :echo index(keys(environ()), 'HOME', 0, 1) != -1
+ 
  empty({expr})                                         *empty()*
                Return the Number 1 if {expr} is empty, zero otherwise.
                - A |List| or |Dictionary| is empty when it does not have any
***************
*** 4970,4982 ****
                        " Get the working directory of current tabpage
                        :echo getcwd(-1, 0)
  <
! getfsize({fname})                                     *getfsize()*
!               The result is a Number, which is the size in bytes of the
!               given file {fname}.
!               If {fname} is a directory, 0 is returned.
!               If the file {fname} can't be found, -1 is returned.
!               If the size of {fname} is too big to fit in a Number then -2
!               is returned.
  
  getfontname([{name}])                                 *getfontname()*
                Without an argument returns the name of the normal font being
--- 4988,4998 ----
                        " Get the working directory of current tabpage
                        :echo getcwd(-1, 0)
  <
! getenv({name})                                                *getenv()*
!               Return the value of environment variable {name}.
!               When the variable does not exist |v:null| is returned.  That
!               is different from a variable set to an empty string.
!               See also |expr-env|.
  
  getfontname([{name}])                                 *getfontname()*
                Without an argument returns the name of the normal font being
***************
*** 5009,5014 ****
--- 5025,5038 ----
  
                For setting permissions use |setfperm()|.
  
+ getfsize({fname})                                     *getfsize()*
+               The result is a Number, which is the size in bytes of the
+               given file {fname}.
+               If {fname} is a directory, 0 is returned.
+               If the file {fname} can't be found, -1 is returned.
+               If the size of {fname} is too big to fit in a Number then -2
+               is returned.
+ 
  getftime({fname})                                     *getftime()*
                The result is a Number, which is the last modification time of
                the given file {fname}.  The value is measured as seconds
***************
*** 8012,8017 ****
--- 8036,8046 ----
                Returns 0 when successful, 1 when not editing the command
                line.
  
+ setenv({name}, {val})                                         *setenv()*
+               Set environment variable {name} to {val}.
+               When {val} is |v:null| the environment variable is deleted.
+               See also |expr-env|.
+ 
  setfperm({fname}, {mode})                             *setfperm()* *chmod*
                Set the file permissions for {fname} to {mode}.
                {mode} must be a string with 9 characters.  It is of the form
*** ../vim-8.1.1304/runtime/doc/usr_41.txt      2019-05-07 22:06:48.675310695 
+0200
--- runtime/doc/usr_41.txt      2019-05-09 14:28:20.978545651 +0200
***************
*** 774,779 ****
--- 774,782 ----
        rename()                rename a file
        system()                get the result of a shell command as a string
        systemlist()            get the result of a shell command as a list
+       environ()               get all environment variables
+       getenv()                get one environment variable
+       setenv()                set an environment variable
        hostname()              name of the system
        readfile()              read a file into a List of lines
        readdir()               get a List of file names in a directory
***************
*** 903,908 ****
--- 906,912 ----
        getwinposy()            Y position of the Vim window
        balloon_show()          set the balloon content
        balloon_split()         split a message for a balloon
+       balloon_gettext()       get the text in the balloon
  
  Vim server:                                   *server-functions*
        serverlist()            return the list of server names
*** ../vim-8.1.1304/src/evalfunc.c      2019-05-09 13:50:13.362401997 +0200
--- src/evalfunc.c      2019-05-09 14:45:25.653442537 +0200
***************
*** 137,142 ****
--- 137,143 ----
  static void f_diff_filler(typval_T *argvars, typval_T *rettv);
  static void f_diff_hlID(typval_T *argvars, typval_T *rettv);
  static void f_empty(typval_T *argvars, typval_T *rettv);
+ static void f_environ(typval_T *argvars, typval_T *rettv);
  static void f_escape(typval_T *argvars, typval_T *rettv);
  static void f_eval(typval_T *argvars, typval_T *rettv);
  static void f_eventhandler(typval_T *argvars, typval_T *rettv);
***************
*** 187,192 ****
--- 188,194 ----
  static void f_getcmdtype(typval_T *argvars, typval_T *rettv);
  static void f_getcmdwintype(typval_T *argvars, typval_T *rettv);
  static void f_getcwd(typval_T *argvars, typval_T *rettv);
+ static void f_getenv(typval_T *argvars, typval_T *rettv);
  static void f_getfontname(typval_T *argvars, typval_T *rettv);
  static void f_getfperm(typval_T *argvars, typval_T *rettv);
  static void f_getfsize(typval_T *argvars, typval_T *rettv);
***************
*** 365,370 ****
--- 367,373 ----
  static void f_setbufvar(typval_T *argvars, typval_T *rettv);
  static void f_setcharsearch(typval_T *argvars, typval_T *rettv);
  static void f_setcmdpos(typval_T *argvars, typval_T *rettv);
+ static void f_setenv(typval_T *argvars, typval_T *rettv);
  static void f_setfperm(typval_T *argvars, typval_T *rettv);
  static void f_setline(typval_T *argvars, typval_T *rettv);
  static void f_setloclist(typval_T *argvars, typval_T *rettv);
***************
*** 629,634 ****
--- 632,638 ----
      {"diff_filler",   1, 1, f_diff_filler},
      {"diff_hlID",     2, 2, f_diff_hlID},
      {"empty",         1, 1, f_empty},
+     {"environ",               0, 0, f_environ},
      {"escape",                2, 2, f_escape},
      {"eval",          1, 1, f_eval},
      {"eventhandler",  0, 0, f_eventhandler},
***************
*** 681,686 ****
--- 685,691 ----
  #endif
      {"getcurpos",     0, 0, f_getcurpos},
      {"getcwd",                0, 2, f_getcwd},
+     {"getenv",                1, 1, f_getenv},
      {"getfontname",   0, 1, f_getfontname},
      {"getfperm",      1, 1, f_getfperm},
      {"getfsize",      1, 1, f_getfsize},
***************
*** 873,878 ****
--- 878,884 ----
      {"setbufvar",     3, 3, f_setbufvar},
      {"setcharsearch", 1, 1, f_setcharsearch},
      {"setcmdpos",     1, 1, f_setcmdpos},
+     {"setenv",                2, 2, f_setenv},
      {"setfperm",      2, 2, f_setfperm},
      {"setline",               2, 2, f_setline},
      {"setloclist",    2, 4, f_setloclist},
***************
*** 3340,3345 ****
--- 3346,3404 ----
  }
  
  /*
+  * "environ()" function
+  */
+     static void
+ f_environ(typval_T *argvars UNUSED, typval_T *rettv)
+ {
+ #if !defined(AMIGA)
+     int                       i = 0;
+     char_u            *entry, *value;
+ # ifdef MSWIN
+     extern wchar_t    **_wenviron;
+ # else
+     extern char               **environ;
+ # endif
+ 
+     if (rettv_dict_alloc(rettv) != OK)
+       return;
+ 
+ # ifdef MSWIN
+     if (*_wenviron == NULL)
+       return;
+ # else
+     if (*environ == NULL)
+       return;
+ # endif
+ 
+     for (i = 0; ; ++i)
+     {
+ # ifdef MSWIN
+       short_u         *p;
+ 
+       if ((p = (short_u *)_wenviron[i]) == NULL)
+           return;
+       entry = utf16_to_enc(p, NULL);
+ # else
+       if ((entry = (char_u *)environ[i]) == NULL)
+           return;
+       entry = vim_strsave(entry);
+ # endif
+       if (entry == NULL) // out of memory
+           return;
+       if ((value = vim_strchr(entry, '=')) == NULL)
+       {
+           vim_free(entry);
+           continue;
+       }
+       *value++ = NUL;
+       dict_add_string(rettv->vval.v_dict, (char *)entry, value);
+       vim_free(entry);
+     }
+ #endif
+ }
+ 
+ /*
   * "escape({string}, {chars})" function
   */
      static void
***************
*** 5261,5266 ****
--- 5320,5346 ----
  }
  
  /*
+  * "getenv()" function
+  */
+     static void
+ f_getenv(typval_T *argvars, typval_T *rettv)
+ {
+     int           mustfree = FALSE;
+     char_u  *p = vim_getenv(tv_get_string(&argvars[0]), &mustfree);
+ 
+     if (p == NULL)
+     {
+       rettv->v_type = VAR_SPECIAL;
+       rettv->vval.v_number = VVAL_NULL;
+       return;
+     }
+     if (!mustfree)
+       p = vim_strsave(p);
+     rettv->vval.v_string = p;
+     rettv->v_type = VAR_STRING;
+ }
+ 
+ /*
   * "getfontname()" function
   */
      static void
***************
*** 11425,11430 ****
--- 11505,11527 ----
  }
  
  /*
+  * "setenv()" function
+  */
+     static void
+ f_setenv(typval_T *argvars, typval_T *rettv UNUSED)
+ {
+     char_u   namebuf[NUMBUFLEN];
+     char_u   valbuf[NUMBUFLEN];
+     char_u  *name = tv_get_string_buf(&argvars[0], namebuf);
+ 
+     if (argvars[1].v_type == VAR_SPECIAL
+                                     && argvars[1].vval.v_number == VVAL_NULL)
+       vim_unsetenv(name);
+     else
+       vim_setenv(name, tv_get_string_buf(&argvars[1], valbuf));
+ }
+ 
+ /*
   * "setfperm({fname}, {mode})" function
   */
      static void
*** ../vim-8.1.1304/src/testdir/Make_all.mak    2019-05-08 21:58:54.446597033 
+0200
--- src/testdir/Make_all.mak    2019-05-09 14:24:07.663891160 +0200
***************
*** 104,109 ****
--- 104,110 ----
        test_erasebackword \
        test_escaped_glob \
        test_eval_stuff \
+       test_environ \
        test_ex_equal \
        test_ex_undo \
        test_ex_z \
***************
*** 320,325 ****
--- 321,327 ----
        test_digraph.res \
        test_display.res \
        test_edit.res \
+       test_environ.res \
        test_erasebackword.res \
        test_escaped_glob.res \
        test_eval_stuff.res \
*** ../vim-8.1.1304/src/testdir/test_environ.vim        2019-05-09 
14:51:39.467575511 +0200
--- src/testdir/test_environ.vim        2019-05-09 14:24:07.663891160 +0200
***************
*** 0 ****
--- 1,44 ----
+ scriptencoding utf-8
+ 
+ func Test_environ()
+   unlet! $TESTENV
+   call assert_equal(0, has_key(environ(), 'TESTENV'))
+   let $TESTENV = 'foo'
+   call assert_equal(1, has_key(environ(), 'TESTENV'))
+   let $TESTENV = 'こんにちわ'
+   call assert_equal('こんにちわ', environ()['TESTENV'])
+ endfunc
+ 
+ func Test_getenv()
+   unlet! $TESTENV
+   call assert_equal(v:null, getenv('TESTENV'))
+   let $TESTENV = 'foo'
+   call assert_equal('foo', getenv('TESTENV'))
+ endfunc
+ 
+ func Test_setenv()
+   unlet! $TESTENV
+   call setenv('TEST ENV', 'foo')
+   call assert_equal('foo', getenv('TEST ENV'))
+   call setenv('TEST ENV', v:null)
+   call assert_equal(v:null, getenv('TEST ENV'))
+ endfunc
+ 
+ func Test_external_env()
+   call setenv('FOO', 'HelloWorld')
+   if has('win32')
+     let result = system('echo %FOO%')
+   else
+     let result = system('echo $FOO')
+   endif
+   let result = substitute(result, '[ \r\n]', '', 'g')
+   call assert_equal('HelloWorld', result)
+ 
+   call setenv('FOO', v:null)
+   if has('win32')
+     let result = system('set | grep ^FOO=')
+   else
+     let result = system('env | grep ^FOO=')
+   endif
+   call assert_equal('', result)
+ endfunc
*** ../vim-8.1.1304/src/version.c       2019-05-09 14:14:37.094870868 +0200
--- src/version.c       2019-05-09 14:51:47.387535281 +0200
***************
*** 769,770 ****
--- 769,772 ----
  {   /* Add new patch number below this line */
+ /**/
+     1305,
  /**/

-- 
JOHN CLEESE PLAYED: SECOND SOLDIER WITH A KEEN INTEREST IN BIRDS, LARGE MAN
                    WITH DEAD BODY, BLACK KNIGHT, MR NEWT (A VILLAGE
                    BLACKSMITH INTERESTED IN BURNING WITCHES), A QUITE
                    EXTRAORDINARILY RUDE FRENCHMAN, TIM THE WIZARD, SIR
                    LAUNCELOT
                 "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/201905091252.x49CquW0013433%40masaka.moolenaar.net.
For more options, visit https://groups.google.com/d/optout.

Raspunde prin e-mail lui