20

When Vim is started, it grabs many of the environment variables from the operating system (like PATH) and it also sets it own environment variables (like MYVIMRC).

How do I list or view all the environment variables that Vim understands, together with their respective values from inside Vim?

ib.
  • 27,830
  • 11
  • 80
  • 100
Ashwin Nanjappa
  • 76,204
  • 83
  • 211
  • 292
  • 1
    http://vim.wikia.com/wiki/Displaying_the_current_Vim_environment could be of help – epsilonhalbe Jun 24 '12 at 07:54
  • So you're looking for a complete list of env vars vim inherits, or are you looking for all env vars Vim creates on its own (by itself)? – Tarek Fadel Jun 24 '12 at 08:03
  • 2
    As far as I know, it is not possible to do that by Vim-only means. However, in Unix-like systems one can just use `:!env`. – ib. Jun 24 '12 at 09:40
  • Tarek Fadel: As indicated in my question, I am interested in both. Vim too, refers to both, as environment variables. – Ashwin Nanjappa Jun 24 '12 at 13:18

6 Answers6

24

In Vimscript, there is not a direct way of getting the list of currently defined environment variables. However, it is possible to exploit Vim command-line completion feature to make one.

Consider possible completions for the following unfinished command:

:echo $

It is not difficult to see that, according to Vimscript syntax, the completions must be the names of the environment variables. Pressing the wildchar key (Tab, by default) or Ctrl+D will display all of them.

In order to get this list of completions from within a script, we need to overcome its interactive nature. A possible trick that I propose herein relies on a combination of features. The first of them is the Ctrl+A command. In Command-line mode, this shortcut triggers insertion of every available completion in front of the cursor. The inserted completions are listed in alphabetical order and separated with spaces.

If we could make Vim print those completions out right into the command line, we would easily capture them by redirecting command output with the :redir command. But all we need to achieve that side effect is to quote the text inserted with Ctrl+A: Quoting makes the rest of our :echo command a string literal that can be just printed out!

:echo 'NAME1 NAME2 NAME3'
NAME1 NAME2 NAME3

To edit the command line in this way, the user can type :ec (an alias for :echo) followed by $, press Ctrl+A, type ', jump to the beginning of the line by pressing Ctrl+B, move the cursor over the dollar sign by pressing  (the right arrow key) twice, delete that $, and, finally, insert ' instead. The same sequence of key presses can easily be reproduced non-interactively using the :normal command.

Putting all these pieces together, we obtain the following function:

function! Env()
    redir => s
    sil! exe "norm!:ec$\<c-a>'\<c-b>\<right>\<right>\<del>'\<cr>"
    redir END
    return split(s)
endfunction

For this approach to work, Vim must be compiled with the +cmdline_compl feature.

ib.
  • 27,830
  • 11
  • 80
  • 100
  • 1
    It is better to change `echo` to `return`: that works for me: `execute "fu! Test()\nexe'silent normal!:return $\'')\\\\split('''.\"\\n\"\nendfu"`. – ZyX Jun 25 '12 at 16:56
22

To list all environment variables, use

:echo $<C-D>

Then, you can start typing the name of the variable of interest, auto-complete with Tab, finally press Enter to show its value.

You didn't tell whether you need this interactively or in a script. For the latter, it's unfortunately not possible to capture the output via :redir.

Ingo Karkat
  • 167,457
  • 16
  • 250
  • 324
  • Ingo Karkat: Thanks. Interactive is fine with me. – Ashwin Nanjappa Jun 24 '12 at 13:18
  • It is possible to capture command-line completion using `:redir`. It requires a non-trivial trick, though. If interested, see my [answer](http://stackoverflow.com/a/11192777/254635). – ib. Jun 25 '12 at 15:55
8

The previous answers have been made obsolescent by the vimscript environ() function.

For example, to list them all in order:

:let evars = environ()
:for var in evars->keys()->sort()
:    echo var . '=' . evars[var]
:endfor
JohnLittle
  • 133
  • 2
  • 6
3

Looking at the other anwers, you can do it without a script.

Enter insert mode, and then press

<C-R>=

Where Ctrl+R allows you to insert any of the registers available (see :help i_Ctrl-R). But particularly you'll use the expression register = here to evaluate a string (see :help @=).

So, now you can insert the expression introduced by ib.'s answer. Enter this:

$<C-A>"<HOME>"<CR><ESC>

Now, you should be back to normal mode and the expression should have evaluated to a string and been placed in the buffer. You can further clean it up with a substitute command:

:s/\s/\r$/g

That should place every environment variable on a different line.

2

Based on the idea by ib and the comments from ZyX, here's the function that I ended up using:

function! GetEnvVars()
    silent execute "normal! :return $\<C-a>')\<C-b>\<C-right>\<Right>\<Del>split('\<CR>"
endfunction
Ingo Karkat
  • 167,457
  • 16
  • 250
  • 324
2
:let

displays all (inc current buffer/windows) variables. Or, if you need to list e.g. all window scope variable, use this isntead:

:let w:
Oleg Khalidov
  • 5,108
  • 1
  • 28
  • 29