Is there any way to get the vim executable path from within vim?

664 views
Skip to first unread message

Viktor Kojouharov

unread,
Mar 12, 2014, 3:45:25 PM3/12/14
to vim...@googlegroups.com
I was hoping using the python sys.argv would return the vim path as the first item, but its filled with garbage? Is there any way to get it, either from a built-in viml function or from the python interface?

Gary Johnson

unread,
Mar 12, 2014, 4:35:18 PM3/12/14
to vim...@googlegroups.com
I don't know about Windows, but on Linux you can get it from either
of these.

substitute(system('readlink /proc/$PPID/exe'), '\n$', '', '')
substitute(system('ls -l /proc/$PPID/exe'), '^.*-> \(.*\)\n$', '\1', '')

HTH,
Gary

Viktor Kojouharov

unread,
Mar 13, 2014, 7:04:53 AM3/13/14
to vim...@googlegroups.com, gary...@spocom.com
That is, unfortunately, only available on linux, whereas I am looking for a more generic solution.

I noticed that vim has a v:progname variable, which unfortunately only displays the executable, without the path. Any way to expand that into the full path?

Fredrik Gustafsson

unread,
Mar 13, 2014, 7:10:26 AM3/13/14
to vim...@googlegroups.com, gary...@spocom.com
On Thu, Mar 13, 2014 at 04:04:53AM -0700, Viktor Kojouharov wrote:
> That is, unfortunately, only available on linux, whereas I am looking for a more generic solution.
>

Why do you need this information? I'm curious...

--
Med vänlig hälsning
Fredrik Gustafsson

tel: 0733-608274
e-post: iv...@iveqy.com

Viktor Kojouharov

unread,
Mar 13, 2014, 7:13:53 AM3/13/14
to vim...@googlegroups.com, gary...@spocom.com, iv...@iveqy.com
To easily use the remote-expr feature. You need to start a new instance of vim and point it to the current running vim server. And I need the full executable path in order to start the remote-expr. Vim is usually in the path on linux systems, but that's not the case on windows and macvim

Fredrik Gustafsson

unread,
Mar 13, 2014, 9:11:06 AM3/13/14
to Viktor Kojouharov, vim...@googlegroups.com, gary...@spocom.com, iv...@iveqy.com
On Thu, Mar 13, 2014 at 04:13:53AM -0700, Viktor Kojouharov wrote:
> To easily use the remote-expr feature. You need to start a new instance of vim and point it to the current running vim server. And I need the full executable path in order to start the remote-expr. Vim is usually in the path on linux systems, but that's not the case on windows and macvim

I don't know of any vim-specific way to do this, but here's a list of
how you do on different systems:
http://stackoverflow.com/questions/1023306/finding-current-executables-path-without-proc-self-exe

I however would just assume that vim is in path otherwise I think it's
okay to fail.

tooth pik

unread,
Mar 13, 2014, 9:59:55 AM3/13/14
to vim...@googlegroups.com
On Thu, Mar 13, 2014 at 04:13:53AM -0700, Viktor Kojouharov wrote:
> To easily use the remote-expr feature. You need to start a new instance of vim and point it to the current running vim server. And I need the full executable path in order to start the remote-expr. Vim is usually in the path on linux systems, but that's not the case on windows and macvim

if, when you start your first vim that's going to be the server, you
specify a name in the --servername option, you can then use that name in
subsequent vim instances to talk directly to that server, no need for
PIDs or other tricks

see

:help servername

for more details -- in fact, all of $RUNTIME/doc/remote.txt will help
you

--
_|_ _ __|_|_ ._ o|
|_(_)(_)|_| ||_)||<
|

Christian Brabandt

unread,
Mar 13, 2014, 10:48:36 AM3/13/14
to vim...@googlegroups.com
Something like this maybe? This should work on Windows on Linux,
don't know for other Operating Systems.

fu! GetProcessPath(id)
let dir=''
if (has("win32") || has("win64"))
if executable("wmic")
if !exists("s:tfile")
let s:tfile = fnamemodify(tempname(), ':r'). '.cmd'
endif
let cr=nr2char(13)
let content=['@ECHO OFF',
\ "FOR /F \"skip=1 tokens=*\" %%T IN ('wmic process
where^(ProcessId^=\"".a:id."\"^)get commandline') DO (echo %%T) &goto
exit",
\ ":exit"]
call map(content, 'v:val.cr')
call writefile(content, s:tfile, 'b')
let dir = system(s:tfile)
call delete(s:tfile)
else
" use globpath ?
let ver = v:version[0].v:version[2]
let dir = get(filter(split(globpath(substitute($PATH, ';', ',',
'g'), v:progname), '\n'), 'v:val =~# "vim".ver'), 0, '')
endif
elseif filereadable("/proc/".a:id."/exe")
let dir = substitute(system(printf("readlink /proc/%d/exe", a:id)),
'\n$', '', '')
endif
echo dir
endfu

com! VimPath :call GetProcessPath(getpid())

guns

unread,
Mar 13, 2014, 12:05:50 PM3/13/14
to vim...@googlegroups.com, Viktor Kojouharov
On Thu 13 Mar 2014 at 08:59:55AM -0500, tooth pik wrote:

> On Thu, Mar 13, 2014 at 04:13:53AM -0700, Viktor Kojouharov wrote:
>
> > To easily use the remote-expr feature. You need to start a new
> > instance of vim and point it to the current running vim server. And
> > I need the full executable path in order to start the remote-expr.
> > Vim is usually in the path on linux systems, but that's not the case
> > on windows and macvim
>
> if, when you start your first vim that's going to be the server, you
> specify a name in the --servername option, you can then use that name
> in subsequent vim instances to talk directly to that server, no need
> for PIDs or other tricks

There is no guarantee that an executable path is unique (multiple hard
links) or stable over time, therefore tooth pik's suggestion is best.

It's also the method implied by the documentation.

guns

Jürgen Krämer

unread,
Mar 14, 2014, 3:20:03 AM3/14/14
to vim...@googlegroups.com

Hi,
at least on Windows Vim puts its own directory at the end of the %PATH%
environment variable. You can check this with ":echo $PATH". So there is
no need to use a full path to the Vim executable.

jkr

--
Sometimes I think the surest sign that intelligent life exists elsewhere
in the universe is that none of it has tried to contact us. (Calvin)

Ingo Karkat

unread,
Mar 14, 2014, 3:36:32 AM3/14/14
to vim...@googlegroups.com
On 14-Mar-2014 08:20 +0100, Jürgen Krämer wrote:

> Hi,
>
> Viktor Kojouharov wrote:
>> To easily use the remote-expr feature. You need to start a new
>> instance of vim and point it to the current running vim server. And I
>> need the full executable path in order to start the remote-expr. Vim
>> is usually in the path on linux systems, but that's not the case on
>> windows and macvim
>>
>
> at least on Windows Vim puts its own directory at the end of the %PATH%
> environment variable. You can check this with ":echo $PATH". So there is
> no need to use a full path to the Vim executable.

If this is for a plugin, I'd also keep this Simple and Stupid: Just
allow (users, individual systems) to specify a full path via a
configuration variable, and default to "vim" found via the PATH, which
should already work on most systems.

Even with a suggested new v:progpath variable, you'd need to handle
older Vim versions, anyway.

-- regards, ingo

Jürgen Krämer

unread,
Mar 14, 2014, 3:40:35 AM3/14/14
to vim...@googlegroups.com

Hi,
I think it should clarify: Vim puts its own directory at the end of $PATH
while it is running, not during some installation routine. So outside of
Vim the path might still miss the Vim directory, but inside Vim itself and
all inherited environments of programs or shells (:sh) that are started
from Vim its directory is included in the %PATH% variable.

Regards,
Jürgen

Tony Mechelynck

unread,
Mar 14, 2014, 4:21:29 AM3/14/14
to vim...@googlegroups.com
On 14/03/14 08:20, Jürgen Krämer wrote:
>
> Hi,
>
> Viktor Kojouharov wrote:
>> To easily use the remote-expr feature. You need to start a new
>> instance of vim and point it to the current running vim server. And I
>> need the full executable path in order to start the remote-expr. Vim
>> is usually in the path on linux systems, but that's not the case on
>> windows and macvim
>>
>
> at least on Windows Vim puts its own directory at the end of the %PATH%
> environment variable. You can check this with ":echo $PATH". So there is
> no need to use a full path to the Vim executable.
>
> jkr
>

On Linux, the Vim executable is placed in one of the directories which
are already in the normal $PATH. Normally the one related with where the
runtime files are. For instance, the Vim defaults (for version 7.4) are:

$VIM = /usr/local/share/vim
$VIMRUNTIME = /usr/local/share/vim/vim74
executable = /usr/local/bin/vim

But that /usr/local/bin directory might contain a lot of softlinks such as

view -> vim
ex -> vi
vi -> vim
gvim -> vim
gview -> gvim
vimdiff -> vim
gvimdiff -> gvim

etc., all ultimately pointing to the binary executable, and sometimes in
relays as in the above example for ex, gview and gvimdiff (on my system,
"vi" is not a softlink but a Tiny build with no optional features). So
if you want to know not only from which directory Vim was loaded but
also under which name… wait… ah no, the usual shell convention is that
argv[0] is the program name as invoked, but inside Vim, argv(0) seems to
be what the shell would call argv[1].

Ah, there, gotcha: v:progname is the program name (with path removed)
under which Vim was invoked. So, under Linux, if $VIMRUNTIME includes
the path element "/share/" (it usually does), remove it (but not its
leading slash) and all after it, and append first "bin/" then v:progname
in its stead. The result is "usually" the full path to the executable;
but in some cases it might not. If $VIMRUNTIME does not include /share/,
I don't know how to go from there to the executable directory. And I use
$VIMRUNTIME rather than $VIM because $VIM is not always $VIMRUNTIME/.. —
for instance, the Vim which comes precompiled with my Linux distro uses
/etc/site for $VIM but /usr/share/vim/current (a link to vim74 in the
same directory) for $VIMRUNTIME. _That_ version of Vim (7.4.52) lives as
/bin/vim but there is also a softlink /usr/bin/vim pointing to it. My
own (and more recent) /usr/local/bin/vim (currently 7.4.205) is before
them in the $PATH so by default it will be the one invoked. For the
other I have a softlink /bin/vim-suse -> vim to unmask it when
needed(the target of a relative softlink is relative to where the
softlink itself is found). And when I invoke that softlink, v:progname
is "vim-suse" which is the name under which it was invoked, before
following the softlinks. QED.

And, yes, it is quite possible (on Linux, and, I think, on the Mac) to
have several versions of Vim (as in my case 7.4.52 and 7.4.205) living
peacefully on one machine, so `which vim` (or `type -P vim` if "which"
is undefined) is not necessarily the right answer. It might, just this
time, be something further down the $PATH.


Best regards,
Tony.
--
A beer delayed is a beer denied.

lith

unread,
Mar 14, 2014, 6:51:54 AM3/14/14
to vim...@googlegroups.com
> I was hoping using the python sys.argv would return the vim path as the first item, but its filled with garbage? Is there any way to get it, either from a built-in viml function or from the python interface?

The executable name is in v:progname. If it is in $PATH, you should be set.

Reply all
Reply to author
Forward
0 new messages