267

When I'm editing a file in Vim, is there a command to see the path of the current file? Sometimes this is very handy if there are multiple files with the same name in a project.

1
  • 1
    TLDR: press 1 then ctrl+g
    – stevec
    Commented Apr 4, 2023 at 1:13

13 Answers 13

326

You can press {count}Ctrl-G:

{count}CTRL-G       Like CTRL-G, but prints the current file name with
                    full path.  If the count is higher than 1 the current
                    buffer number is also given.

Pressing 1 followed by Ctrl+G shows the full path of the current file. If {count} is higher than 1, the buffer name will also be shown.

(Pressing only Ctrl+G shows the path relative to Vim's current working directory, as pointed out by Jasper in the comments.)

You can use the following command in your .vimrc to add the full path to the status line, so it is always visible:

set statusline+=%F
5
  • 12
    Isn't Ctrl+G more like 'path relative to vim's cwd'?
    – Jasper
    Commented Feb 3, 2015 at 18:58
  • @Jasper Good catch! Updated the answer.
    – thameera
    Commented Feb 3, 2015 at 19:06
  • 6
    It seems C-g is default for 0C-g, and 2C-g shows buffer index number (starting from 1) as well in addition.
    – user10767
    Commented Apr 24, 2017 at 16:27
  • 1
    I'm so happy to be the 100th to upvote your answer! Thanks for this 1C-g!
    – vault
    Commented Nov 6, 2018 at 15:08
  • 1
    also add set laststatus=2 to ~/.vimrc if you would like the status line to always show
    – Alex
    Commented Mar 4, 2020 at 4:00
153

Register % contains the name of the current file.

The following commands could be entered to display the information shown:

:echo @%                |" directory/name of file
:echo expand('%:t')     |" name of file ('tail')
:echo expand('%:p')     |" full path
:echo expand('%:p:h')   |" directory containing file ('head')

or alternatively, using the shell's echo:

:!echo %
:!echo %:t
:!echo %:p
:!echo %:p:h

If all that is wanted is to display the name of the current file, type :f/:ls or press Ctrl-g (for full path press 1 then Ctrl-g).

In insert mode, type Ctrl-r then % to insert the name of the current file.

The following commands insert lines consisting of the full path of the current and alternate files into the buffer:

:put =expand('%:p')
:put =expand('#:p')

Source: Get the name of the current file at vim wikia

Related:

1
  • 3
    It may be worth noting that you can also use those =expand... expressions after Ctrl-R when in insert mode, too. Commented Jan 3, 2018 at 2:01
38

You can use :!ls %:p to get the full path to the current file.

Depending on the ex context, % will either mean the contents of the file or the filename. When shelling out, it represents the file path relative to the current directory. The command '%:p' will add the full path filename modifier to %.

There are a few other interesting filename modifiers such as:

  • :~: Get the file path relative to the home directory (this one didn't work for me for some reason)
  • :.: Get the file path relative to the current directory (% default)
  • :r: File name root. The name of the file without the extension.
  • :e: File's extension.
  • :h: Split on / and return the left half (i.e. if I'm editing a file in a path of /tmp/test.txt and run %:p:h will return /tmp
  • :t: Split on / and return the right half (i.e. if I'm editing a file in a path of /tmp/test.txt and run %:p:t will return text.txt
2
  • I think you meant %:p: t will return text.txt
    – John O'M.
    Commented Feb 5, 2015 at 4:20
  • @JohnO'M. yep, that's right thanks :D. Fixed.
    – CharlesL
    Commented Feb 5, 2015 at 12:43
14

One can see the current working directory with :pwd. Of course, this is only the directory, and not the filename. To get the working directory and filename, we can use the special register %, which contains information about the current file.

If you use :echo @%, you'll get the directory and filename of the current file.
If you use :echo expand('%:p'), you'll get the full path and filename of the current file. This is very similar to CharlesL's answer.

I remember this one, though, because if you use vim's help :h expand, then it mentions that % and %:p and their relatives.

11

There are aleady better answers, but if (for some reason) you wanted to use the shell to get the full path of the file (this is more useful if you're going to perform some other operation on the file with the shell), on a Unix-like system you could run:

:!realpath %

or:

:'<,'>!realpath %

to insert the path into the document over the current selection.

Register % always contains the name of the file. A realworld example might be if you're editing a config file, but don't have write permissions (and don't want ot run Vim as root), you could edit the file, then run:

:w ! sudo tee %

to save the file (a tiny bit offtopic there, but it's a good example of what else can be done with the % register).

1
  • 1
    realpath isn't POSIX, so it might be simpler to do: !echo "$PWD/%"
    – muru
    Commented Feb 18, 2015 at 0:57
9

You need to set your status line to be viewable and also set it to path. I did so permanently by adding the two lines below to my ~/.vimrc

set laststatus=2
set statusline+=%F

If you want to just run that once. Then when VIing a document type

:set laststatus=2       <ENTER>
:set statusline+=%F     <ENTER>
1
9

The following will display the path relative to your current directory:

:f[ile]

That is :f or :file.

4
  • Simple and useful
    – Morteza
    Commented Jun 22, 2019 at 8:49
  • 1
    doesnt show the full path
    – sjas
    Commented Nov 3, 2019 at 1:50
  • @sjas indeed, updated Commented Nov 6, 2019 at 17:26
  • added a proper answer to the OP:s question after i found it elsewhere
    – sjas
    Commented Nov 7, 2019 at 16:17
6

To show the full path for all files, including resolved symlinks, use the following.

:echo resolve(expand('%:p'))
2

Lua with nvim

I wrote this function to get the full path of my current directory and then mapped it to the lualine (any status line is the same). I am pretty much sure, this solution is package ignostic, so no need to worry about the lualine status bar, any status bar is ok. tested on 3 different status bars already.

local full_path = function ()
     return'%<%F%m %#__accent_red#%#__restore__#'
end

this is similar to (.zsh) if you want to add a full path to your prompt configurations.

Mapping with lualine status bar,

Assume, you want to put the full path on section (c) then:

lualine_c = { full_path() },

Alternative solution

if you don't like this solution, you can try (lualine) and give (2) for full path string in the configurations.

lualine_c = {
{'filename',
      file_status = true,  -- displays file status (readonly status, modified status)
      path = 2,            -- 0 = just filename, 1 = relative path, 2 = absolute path
      shorting_target = 40 -- Shortens path to leave 40 space in the window
                           -- for other components. Terrible name any suggestions?
      }
    },

Notes

  • In lua-nvim configurations, this can get you the full path:

local filename = vim.fn.expand "%:F", or using local file = vim.fn.expand('%:p')

then simply put in your init.lua

print(file) 

change (f:filename)

Reference

1

I use vim airline for that and some nice features:

enter image description here

1

You can show the complete path of the file you are editing in the title bar, which is a convenient way to show the file path in my opinion.

In order to do that, you need to set the title option and titlestring. Current I am using the following settings:

set title
set titlestring=%{hostname()}\ \ %F\ \ %{strftime('%Y-%m-%d\ %H:%M',getftime(expand('%')))}

It will show the hostname of Vim, then the complete path of the file and followed by last modified time of the file. See the figure below for a demo

enter image description here

0

Linux can try realpath command.

:!realpath %

If you use MacOS, try brew install coreutils first.

3
  • This only works for Linux.
    – jdhao
    Commented Dec 7, 2020 at 8:42
  • Welcome to Vi and Vim! As jdhao points out and I’ve learned the hard way, realpath isn’t available on all systems (not even all *nixes!). Consider adding a caveat by editing your answer
    – D. Ben Knoble
    Commented Dec 7, 2020 at 13:21
  • This is actually a duplicate answer. Already mentioned in vi.stackexchange.com/a/1886/15292
    – jdhao
    Commented Dec 8, 2020 at 7:10
0

If you want to yank the full canonical path to your system clipboard, use:

:let @+=expand("%:p")

Depending on your GUI vs. X11 situation, you may want to use:


:let @*=expand("%:p")

In many cases, there won't be a functional difference between using the + or * selection registers. But it's always worth being aware of the distinction.

1
  • Welcome to this site! Note that your answer is basically the same as kernob's one from 7 years ago (i.e. use expand("%:p"), the question is not about copying the result of a command unlike this one. As a general advice this kind of old and popular questions with already a lot of answers are not really good candidates for first answers, don't hesitate to check the newer questions which don't already have an answer: your work will be much more valuable to these questions.
    – statox
    Commented Mar 17, 2022 at 9:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.