249

Assuming the current buffer is a file open for edit, so :e does not display E32: No file name.

I would like to yank one or all of:

  • The file name exactly as show on the status line, e.g. ~\myfile.txt
  • A full path to the file, e.g. c:\foo\bar\myfile.txt
  • Just the file name, e.g. myfile.txt
davetapley
  • 17,000
  • 12
  • 60
  • 86

13 Answers13

280

TL;DR

:let @" = expand("%")

this will copy the file name to the unamed register, then you can use good old p to paste it. and of course you can map this to a key for quicker use.

:nmap cp :let @" = expand("%")<cr>

you can also use this for full path

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

Explanation

Vim uses the unnamed register to store text that has been deleted or copied (yanked), likewise when you paste it reads the text from this register.

Using let we can manually store text in the register using :let @" = "text" but we can also store the result of an expression.

In the above example we use the function expand which expands wildcards and keywords. in our example we use expand('%') to expand the current file name. We can modify it as expand('%:p') for the full file name.

See :help let :help expand :help registers for details

Razzi Abuissa
  • 3,337
  • 2
  • 28
  • 29
JD Frias
  • 4,418
  • 3
  • 21
  • 24
127

Almost what you're asking for, and it might do: in INSERT mode, Ctrl+R % pulls the current filename into where you are (command prompt, edit buffer, ...). See this Vim Tip for more.

toraritte
  • 6,300
  • 3
  • 46
  • 67
dwc
  • 24,196
  • 7
  • 44
  • 55
114

If you want to put the current buffer filename in your system-level clipboard, try changing the register to @+:

" relative path
:let @+ = expand("%")

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

" just filename
:let @+ = expand("%:t")

Edit 20140421: I commonly use these, so I created some shortcuts. Linux Vims apparently operate slightly differently than Mac Vims, so there is a special case for that as well. If you put the following in your ~/.vimrc:

" copy current file name (relative/absolute) to system clipboard
if has("mac") || has("gui_macvim") || has("gui_mac")
  " relative path  (src/foo.txt)
  nnoremap <leader>cf :let @*=expand("%")<CR>

  " absolute path  (/something/src/foo.txt)
  nnoremap <leader>cF :let @*=expand("%:p")<CR>

  " filename       (foo.txt)
  nnoremap <leader>ct :let @*=expand("%:t")<CR>

  " directory name (/something/src)
  nnoremap <leader>ch :let @*=expand("%:p:h")<CR>
endif

" copy current file name (relative/absolute) to system clipboard (Linux version)
if has("gui_gtk") || has("gui_gtk2") || has("gui_gnome") || has("unix")
  " relative path (src/foo.txt)
  nnoremap <leader>cf :let @+=expand("%")<CR>

  " absolute path (/something/src/foo.txt)
  nnoremap <leader>cF :let @+=expand("%:p")<CR>

  " filename (foo.txt)
  nnoremap <leader>ct :let @+=expand("%:t")<CR>

  " directory name (/something/src)
  nnoremap <leader>ch :let @+=expand("%:p:h")<CR>
endif

Then for example <leader>cf will copy the relative path of the current buffer (the default leader is backslash (\)). I often use these for running commands on a file or doing other things on the command line. I don't really use the last filename / directory name often.

You might consider more intuitive mappings like <leader>cfr for relative, <leader>cfa for absolute, <leader>cff for just filename, <leader>cfd for directory.

Community
  • 1
  • 1
Anthony Panozzo
  • 3,274
  • 1
  • 24
  • 22
18

Answer tested on Neovim/Ubunutu.

:let @+=@%

From what I can tell, the % register already contains the relative filepath, so it's as simple as moving the contents of the % register to whatever register represents your favourite clipboard.

This SO answer deals with copying from one register to another

Seems pretty straightforward to me. No need for any hard-to-remember expand() stuff.

Chris Stryczynski
  • 30,145
  • 48
  • 175
  • 286
LondonRob
  • 73,083
  • 37
  • 144
  • 201
12

If you do :reg you will see the name of the current file in the % register. You can paste it with "%p, for example.

If, like me, you often switch to the 'alternate' buffer, it is very handy that its full path-and-file-name are put in the # register. You can paste it with "#p, for example.

Note (just in case this is behaviour specific to my setup): I am using VIM 7.4.52 on Ubuntu 14.04.4 LTS.

Robert
  • 1,530
  • 1
  • 16
  • 24
4

Combining information from a couple of other answers: If you want to yank the current full path to a file and put it into the command buffer in another window, first do :let @" = expand("%:p"), then move to another window and type Ctrl+R ".

Useful for copying a file while staying in the same directory and keeping the old one open. For example:

Start: Editing src/com/benatkin/paint/shapes/Circle.java

  1. Type :let @" = expand("%:p") (The path gets yanked to the main clipboard buffer.)

  2. Open a new window with :sp

  3. Type :e Ctrl+R"

  4. Use the arrow keys to go back to Circle and change it to Square, and press <CR>

End: Editing src/com/benatkin/paint/shapes/Square.java

Community
  • 1
  • 1
Benjamin Atkin
  • 14,071
  • 7
  • 61
  • 60
3

If you're on terminal vim, and want to copy to system clipboard: For something easy to remember, that doesn't requiring predefined mappings/functions:

:!echo %

prints the current buffer's relative path to terminal, where you can copy it and then ENTER back to vim. (as already mentioned, you can postfix the command with :p or :t to get absolute or basename, if you can remember that....)

tonywoode
  • 166
  • 1
  • 6
2

Here is my solution:

" filename / dirname of the current file {{{
    " copy result to the system clipboard and echo the result
    " the cb> prompt means the clipboard
    " *f*ile *n*ame, ex. init.vim
    map <Leader>fn :let @+ = expand("%:t") \| echo 'cb> ' . @+<CR>
    " *f*ile *p*ath, ex. /home/user/nvim/init.vim
    map <Leader>fp :let @+ = expand("%:p") \| echo 'cb> ' . @+<CR>
    " *d*irectory *p*ath, ex. /home/user/nvim
    map <Leader>dp :let @+ = expand("%:p:h") \| echo 'cb> ' . @+<CR>
    " *d*irectory *n*ame, ex. nvim
    map <Leader>dn :let @+ = expand("%:p:h:t") \| echo 'cb> ' . @+<CR>
" }}}
Jabba
  • 19,598
  • 6
  • 52
  • 45
0

I put it in my vimc:

nnoremap yl :let @" = expand("%:p")<cr>
Good Pen
  • 625
  • 6
  • 10
0

As an alternative to other answers, if you happen to have vim-fugitive installed, you can use default y<C-G> (that's y followed by Ctrl+g) mapping.

From :help vim-fugitive:

                                                *fugitive_y_CTRL-G*
["x]y<C-G>              Yank the path to the current |fugitive-object|.

Even though it specifies fugitive-object it actually works on usual files too, yanking file path.

For me it's even simpler to remember than having to remember how to use expand. And there's no need to create extra mapping.

im.pankratov
  • 1,768
  • 1
  • 19
  • 19
0

Rather than using map commands (:h map-commands), this might be an ideal application for using abbreviations (:h abbreviations). They behave like TextExpander, but are native to Vim.

Start by adding the following lines to $MYVIMRC. Change the trigger (the <y..> to suit your preferences.

cabbrev yfn   :let @+ = expand("%:t")
cabbrev yfp   :let @+ = expand("%:p")
cabbrev yrp   :let @+ = expand("%")

Using $MYVIMRC as an example:

  • yfn%:t tail (filename, last path component only); e.g. cwd: ~/<any/dir>/, result: .vimrc
  • yfp%:p expand to full path; e.g. cwd: ~/any/dir/, result: /Users/<home_dir>/.vimrc
  • yrp% current file name (relative path); e.g. cwd: ~/, result: .vimrc

So, in command-line mode, <:cabbrev> + <CR> executes the command immediately, or you can start editing it right away.

ssent1
  • 651
  • 5
  • 4
-1

I use xclip to access X's clipboard, so I use:

nmap <localleader>d :call system("xclip -i -selection clipboard", expand("%:p"))<CR>
glts
  • 21,808
  • 12
  • 73
  • 94
user189557
  • 169
  • 1
  • 3
-1

If you wish to simply yank the path of the currently open file name then simply press:

  1. step1: ctrl + g [You will see the entire root path at the bottom of window]
  2. step2: select the path with the mouse
  3. step3: Paste with the middle mouse wheel