Getting relative paths in Vim
Asked Answered
T

7

23

Say I am running Vim and pwd returns

/home/rafid/myproject

And say I am currently editing the file

/home/rafid/myproject/website/editpage.php

Is there any command that returns this for me?

website/editpage.php

That is, the path of the file relative to the current folder.

Text answered 24/12, 2010 at 9:0 Comment(0)
H
5

This works for me :

:echo expand("%")
Hower answered 24/12, 2010 at 9:20 Comment(2)
You can also use <c-r>% in insert mode to insert the current file name.Boabdil
This does not always work and is dependent on how you initially opened the file. See @Pourpoint 's answer to this question for a more complete solution.Ragamuffin
P
36

Although expand('%') often works, there are rare occasions where it does not. But you can force Vim to always present the relative path by calling fnamemodify:

:echo fnamemodify(expand("%"), ":~:.")

From the manual:

    :.      Reduce file name to be relative to current directory, if
            possible.  File name is unmodified if it is not below the
            current directory.
            For maximum shortness, use ":~:.".

The :~ is optional. It will reduce the path relative to your home folder if possible (~/...). (Unfortunately that only works on your home; it won't turn /home/fred into ~fred if you aren't logged in as fred.)

As Adam pointed out the comments, this can be shortened to:

:echo expand("%:~:.")

Reference: :h expand<Tab> and :h fnamem<Tab>


If you are limited for space (e.g. using this in your statusline), and can manage with "fuzzy" information about where the file is located, then check out pathshorten() which compresses folder names down to one character:

:echo pathshorten('~/.vim/autoload/myfile.vim')
~/.v/a/myfile.vim

Reference: :h pathsh<Tab>

Pourpoint answered 28/6, 2014 at 3:45 Comment(2)
Thanks for pointing me in the right direction. Just for the record, looks like the modifiers can also be expanded directly using :echo expand("%:~:."). More information can be found at :help filename-modifiers.Hydrated
Thank you for this answer! I am working in vim and trying to execute a command inside a docker container (run a specific test file) so the absolute path won't work for me. Docker can't see the full path and my test runner inside the container throws an error because it can't find the file. fnamemodify worked perfectly!Mud
S
11

Another option would be to write a vim function. Here's my humble attempt:

function! Relpath(filename)
    let cwd = getcwd()
    let s = substitute(a:filename, l:cwd . "/" , "", "")
    return s
endfunction

You call Relpath with any full path name, and it will strip the current directory name from its argument.

For example, try :echo Relpath(expand("%:p")) (the :p modifier asks Vim to return the full path). Obviously, this is not necessary in your case, since % by itself returns relative path. However, it might come in handy in other cases.

Soviet answered 24/12, 2010 at 9:41 Comment(0)
H
5

This works for me :

:echo expand("%")
Hower answered 24/12, 2010 at 9:20 Comment(2)
You can also use <c-r>% in insert mode to insert the current file name.Boabdil
This does not always work and is dependent on how you initially opened the file. See @Pourpoint 's answer to this question for a more complete solution.Ragamuffin
D
1

if you use autocmd to always set the current directory of the buffer that you are working on ( cd %:p:h ) then you can just type :cd

Dexter answered 25/12, 2010 at 11:54 Comment(1)
to the next person landing on this page - check out this vim tip for more details on setting cd with autocmd vim.wikia.com/wiki/Set_working_directory_to_the_current_fileTriquetrous
D
1

This works for me:

:echo expand("%")

This is only working if you opened that file with a relative file:

for vi ./foo, expand("%") will be ./foo

but

for vi /tmp/foo expand("%") will be /tmp/foo
Dahle answered 4/4, 2014 at 8:2 Comment(1)
Not here. If I am in /tmp and do vi /tmp/foo then Vim works out the relativepath, and expand("%") shows me foo. However if I keep vim open in /tmp and do :e /tmp/bar then expand("%") will show the full path.Pourpoint
A
0

Yes, you can use

:args

This will give you the filename of the current file, for informational purposes.

Almuce answered 24/12, 2010 at 9:12 Comment(2)
Notice that I don't want the file name only, I want the relative path. So not just editpage.php, but 'website/editpage.php'.Text
Yes, it will take that into account. Did you try it?Almuce
A
0

A workaround can be :cd . which seems to re-evaluate the path relative-ness. I agree this is very annoying though.

Ablebodied answered 3/5, 2022 at 17:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.