Yank nama file / jalur buffer saat ini di Vim

188

Dengan asumsi buffer saat ini adalah file yang terbuka untuk diedit, jadi :etidak ditampilkan E32: No file name.

Saya ingin menarik salah satu atau semua:

  • Nama file persis seperti yang ditunjukkan pada baris status, mis ~\myfile.txt
  • Path lengkap ke file, misalnya c:\foo\bar\myfile.txt
  • Hanya nama file, mis myfile.txt
davetapley
sumber
Ke clipboard: vi.stackexchange.com/questions/3686/…
Ciro Santilli 郝海东 冠状 病 六四 六四 事件 法轮功

Jawaban:

209

TL; DR

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

ini akan menyalin nama file ke register yang tidak dikenal , lalu Anda bisa menggunakan yang lama puntuk menempelkannya. dan tentu saja Anda dapat memetakan ini ke tombol untuk penggunaan yang lebih cepat.

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

Anda juga dapat menggunakan ini untuk path lengkap

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

Penjelasan

Vim menggunakan register tanpa nama untuk menyimpan teks yang telah dihapus atau disalin (disentak), juga ketika Anda menempelkannya membaca teks dari register ini.

Menggunakan letkita dapat secara manual menyimpan teks dalam register menggunakan :let @" = "text"tetapi kita juga dapat menyimpan hasil ekspresi.

Dalam contoh di atas kami menggunakan fungsi expandyang memperluas wildcard dan kata kunci. dalam contoh kita, kita gunakan expand('%')untuk memperluas nama file saat ini. Kita dapat memodifikasinya sebagaiexpand('%:p') untuk nama file lengkap.

Lihat :help let :help expand :help registersdetailnya

JD Frias
sumber
23
Cool baru saja menambahkan ini ke vimrc saya: noremap <silent> <F4>: let @ + = expand ("%: p") <CR>
ThePosey
9
Di Windows, Anda sebaiknya menggunakan: let @ * = expand ("%"), jika Anda ingin berada di clipboard Windows .
KFL
15
Jika Anda menggunakan unnamedplusclipboard Anda gunakanlet @+ = expand("%")
Kevin Cox
4
Gunakan "%:h"untuk mendapatkan path lengkap tanpa nama file.
Polymorphix
Terkait, khususnya jika Anda memerlukan direktori tanpa nama file - stackoverflow.com/a/2233924/1882064
arcseldon
94

Hampir apa yang Anda minta, dan itu bisa dilakukan: Ctrl+R %menarik nama file saat ini ke tempat Anda berada (command prompt, edit buffer, ...). Lihat Tip Vim ini untuk lebih lanjut.

dwc
sumber
1
ketika Anda keluar dari mode edit Anda dapat menambahkan nama file: ctrl- "ctrl-% p
stefanB
13
Ctrl+R %berfungsi saat dalam insertmode - tetapi dalam editmode, Ctrl+Rberarti mengulang.
Kevin Panko
3
Apa yang dimaksud stefanB adalah "% p untuk mode normal / perintah. Itu sama dengan <Cr>% dalam mode insert / cmdline.
graywh
Hanya untuk meringkas kembali atau menyatakan secara berbeda: jawaban untuk graywh dan dwc adalah "tempel dari register%". Satu melakukan ini untuk mode penyisipan, yang lainnya untuk mode normal. Dalam macvim, tampaknya% register tidak dapat ditimpa.
Eric Hu
apakah ada perintah sederhana yang sama untuk mendapatkan linenumber? ) thx for solution
itsnikolay
73

Jika Anda ingin meletakkan nama file buffer saat ini di clipboard tingkat sistem Anda, coba ubah register ke @ +:

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

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

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

Sunting 20140421: Saya biasanya menggunakan ini, jadi saya membuat beberapa cara pintas. Linux Vims tampaknya beroperasi sedikit berbeda dari Mac Vims , jadi ada kasus khusus untuk itu juga. Jika Anda memasukkan yang berikut ini di ~/.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

Maka misalnya <leader>cfakan menyalin path relatif dari buffer saat ini (pemimpin default adalah backslash ( \)). Saya sering menggunakan ini untuk menjalankan perintah pada file atau melakukan hal-hal lain pada baris perintah. Saya tidak terlalu sering menggunakan nama file / nama direktori.

Anda dapat mempertimbangkan pemetaan yang lebih intuitif seperti <leader>cfruntuk relatif, <leader>cfauntuk absolut, <leader>cffhanya nama file, <leader>cfduntuk direktori.

Anthony Panozzo
sumber
2
Di windows dan mac "*dan "+setara, sehingga Anda dapat membuang platform check dan gunakan saja@+
Gabe Moothart
1
Anehnya ini sepertinya tidak berfungsi dalam fungsi vimscript: "echo bufname ('%: p')" kosong, tetapi Anda dapat memperbaikinya dengan "fnamemodify (bufname ('%'), ': p' yang lebih panjang ) "
David Ljung Madison Stellar
6

Jika Anda melakukannya, :regAnda akan melihat nama file saat ini di %register. Anda dapat menempelkannya dengan "%p, misalnya.

Jika, seperti saya, Anda sering beralih ke buffer 'alternatif', sangat berguna bahwa path-dan-file-nama lengkapnya dimasukkan ke dalam #register. Anda dapat menempelkannya dengan"#p , misalnya.

Catatan (kalau-kalau ini adalah perilaku khusus untuk pengaturan saya): Saya menggunakan VIM 7.4.52 di Ubuntu 14.04.4 LTS.

Robert
sumber
4

Menggabungkan informasi dari beberapa jawaban lain: Jika Anda ingin menarik path lengkap saat ini ke file dan memasukkannya ke dalam buffer perintah di jendela lain, pertama lakukan :let @" = expand("%:p"), kemudian pindah ke jendela lain dan ketik Ctrl+R ".

Berguna untuk menyalin file sambil tetap berada di direktori yang sama dan menjaga yang lama terbuka. Sebagai contoh:

Mulai : Mengedit src / com / benatkin / cat / bentuk / Circle.java

  1. Ketik :let @" = expand("%:p") (Jalur akan ditarik ke buffer clipboard utama.)

  2. Buka jendela baru dengan :sp

  3. Tipe :e Ctrl+R"

  4. Gunakan tombol panah untuk kembali ke Lingkaran dan mengubahnya ke Kotak, dan tekan <CR>

Akhir : Mengedit src / com / benatkin / cat / bentuk / Square.java

Benjamin Atkin
sumber
1

Ini solusinya:

" 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
sumber
-1

Saya menggunakan xclip untuk mengakses clipboard X, jadi saya menggunakan:

nmap <localleader>d :call system("xclip -i -selection clipboard", expand("%:p"))<CR>
pengguna189557
sumber
"+ atau" * melakukan hal yang sama secara native di vim tanpa harus menggunakan perintah eksternal.
Dorian B.