Fungsi untuk menampilkan path lengkap file saat ini dalam buffer mini

98

Saya perlu mendapatkan path lengkap dari file yang saya edit dengan emacs.

  • Apakah ada fungsi untuk itu?
  • Jika tidak, apa fungsi elisp untuk mendapatkannya?
  • Bagaimana cara menyalin hasil (nama jalur) ke papan klip sehingga saya dapat menggunakannya kembali?

Saya menggunakan Mac OS X dan Aqumacs.

(setq filepath (get-fullpath-current-file)) ???
(copy-to-clipboard 'filepath) ???

DITAMBAHKAN

(defun show-file-name ()
  "Tunjukkan nama file jalur lengkap di minibuffer."
  (interaktif)
  (pesan (buffer-file-name))
  (kill-new (nama-file-nama-file-nama-file))
)
(global-set-key "\ C-cz" 'show-file-name)

Menggabungkan dua jawaban yang saya dapatkan, saya bisa mendapatkan apa yang saya inginkan. Terima kasih atas jawabannya. Dan beberapa pertanyaan lagi.

  • Untuk apa (file-truename)?
  • Dapatkah saya menyalin nama jalur ke papan klip Sistem (OS), bukan cincin pemutus sehingga saya dapat menggunakan info tersebut dengan aplikasi lain?
prosseek
sumber

Jawaban:

91

Ini adalah fungsi buffer-file-namebawaan yang memberi Anda jalur lengkap file Anda.

Hal terbaik untuk dilakukan adalah membuat jendela emacs Anda selalu menampilkan nama sistem Anda dan jalur lengkap buffer yang saat ini Anda edit:

(setq frame-title-format
      (list (format "%s %%S: %%j " (system-name))
        '(buffer-file-name "%f" (dired-directory dired-directory "%b"))))

Anda juga dapat melakukan sesuatu seperti ini:

(defun show-file-name ()
  "Show the full path file name in the minibuffer."
  (interactive)
  (message (buffer-file-name)))

(global-set-key [C-f1] 'show-file-name) ; Or any other key you want
Jérôme Radix
sumber
7
Dalam emacs 24 buffer-file-nameadalah variabel
barracel
5
... tetapi juga masih berfungsi
phils
16
Jika itu sebuah fungsi lalu mengapa tidak muncul di M-x?
asmeurer
8
asmeurer - karena tidak interaktif
Ben Fitzgerald
2
@Talespin_Kit Ya, tentu saja. Elisp adalah "lisp-2" sebagai lawan dari "lisp-1", yang berarti ada dua ruang nama independen (variabel dan fungsi). Oleh karena itu, setiap simbol memiliki "slot fungsi" dan "slot nilai", dan slot mana yang diakses bergantung pada konteksnya. Ada banyak contoh dalam praktiknya (mis. Nama mode minor apa pun akan menjadi fungsi dan variabel). Ini juga mengapa Anda perlu menggunakan suka dari funcalluntuk memanggil fungsi yang disimpan sebagai nilai variabel foo, karena jika Anda menggunakan (foo)Anda akan menggunakan slot fungsi foodaripada slot nilai.
phils
73

Untuk meminjam dari jawaban Jérôme Radix, jika Anda hanya ingin melihat jalur file buffer saat ini dengan cepat, Anda dapat melakukannya M-: buffer-file-name.

Bergantian, ketik (buffer-file-name)buffer di suatu tempat dan jalankan C-x C-edi kurung tutup (ini akan bekerja dalam mode apa pun, bukan hanya mode lisp).

asmeurer
sumber
3
Terima kasih, saya pikir itu buffer-file-namesebagai fungsi, tetapi tidak muncul di M-x, tetapi muncul M-:sebagai emacs eval, di sana saya dapat menjalankan perintah, berkat jawaban Anda :)
PeterZD
6
Ya, M-xhanya menjalankan fungsi interaktif, sedangkan M-:menjalankan fungsi elisp apa pun.
asmeurer
40

Trik saya adalah melakukan C-x C-flike untuk membuka file, itu akan mengisi minibuff dengan jalur file saat ini, C-guntuk keluar. Lebih cepat dari M-: buffer-file-nametapi jauh lebih jelek dari metode lainnya.

Julien Palard
sumber
Saya melakukan ini juga. Ini bukan sebagai emacs-y hardcore tetapi jika yang saya pedulikan hanyalah jalur ke file saat ini, itu berhasil.
andrunix
Jika Anda membuka file, katakan A, lalu lompat ke file lain, katakan B, misalnya menggunakan fungsi lompat ke definisi plugin, metode ini menunjukkan jalur A, bukan B! Jadi, jawaban ini tidak selalu menawarkan apa yang diminta OP.
Abhishek Anand
4
Cx Cv akan menunjukkan bukan hanya jalur saat ini tetapi juga nama file saat ini
kuzzooroo
@kuzzooroo itu tepat untuk pengguna non-ido-mode (Nama ditampilkan di Cx Cf dengan Anda menggunakan ido-mode).
Julien Palard
16

Implementasi langsung dari apa yang Anda inginkan adalah:

(defun copy-full-path-to-kill-ring ()
  "copy buffer's full path to kill ring"
  (interactive)
  (when buffer-file-name
    (kill-new (file-truename buffer-file-name))))

Karena itu, saya merasa sangat berguna untuk bisa mendapatkan jalur lengkap dari apa yang ada di minibuffer, dan inilah yang saya gunakan:

(define-key minibuffer-local-completion-map "\C-r" 'resolve-sym-link)
(defun resolve-sym-link ()
  "Try to resolve symbolic links into true paths."
  (interactive)
  (beginning-of-line)
  (let* ((file (buffer-substring (point)
                                 (save-excursion (end-of-line) (point))))
         (file-dir (file-name-directory file))
         (file-true-dir (file-truename file-dir))
         (file-name (file-name-nondirectory file)))
    (delete-region (point) (save-excursion (end-of-line) (point)))
    (insert (concat file-true-dir file-name))))

Dan kemudian jika saya menginginkannya di clipboard, saya hanya mematikan baris ( C-a C-k). Tetapi kita dapat dengan mudah menyalin nama asli ke clipboard pada perintah di atas, cukup ubah baris terakhir menjadi:

(insert (kill-new (concat file-true-dir file-name)))))

Bagian baru adalah panggilan 'kill-newyang menempatkan string di cincin penghentian.

Trey Jackson
sumber
Dapatkah Anda menjelaskan cara menggunakan pengaturan ini? Dan apa artinya "\ Cr"?
pemodel
Lupakan. Saya menemukan jawabannya. Saya rasa ini berguna ketika saya dalam mode ido dan menunjuk ke sebuah file, lalu saya cukup menekan Cr untuk mendapatkan path lengkap dari file itu. Sangat bermanfaat. Namun saya masih tidak tahu mengapa menggunakan \ C daripada C.
pemodel
11

Tidak perlu fungsi ekstra, cukup

M-! pwd
thanhpk.dll
sumber
Meskipun dapat berfungsi, ini tidak akan berfungsi pada sistem Windows, dan gagal memperhitungkan fakta bahwa direktori kerja emacs saat ini dapat berbeda dari direktori file buffer saat ini. Anda dapat melihatnya sendiri dengan mengunjungi file dengan C-x C-f, menjalankan M-! pwd, lalu M-x cdmemilih direktori lain, lalu menjalankan M-! pwdlagi.
josaphatv
3

Saya memiliki kode berikut sudah digunakan untuk waktu yang lama. Ini menyalin path file lengkap ke kill ring ketika saya menekan tombol tengah mouse pada nama buffer di mode-line. Ini hanya menyalin nama buffer ke kill-ring ketika saya menekan shift-mouse-2 pada nama buffer di mode-line.

(defun copy-buffer-file-name (event &optional bufName)
  "Copy buffer file name to kill ring.
If no file is associated with buffer just get buffer name.
"
  (interactive "eP")
  (save-selected-window
    (message "bufName: %S" bufName)
    (select-window (posn-window (event-start event)))
    (let ((name (or (unless bufName (buffer-file-name)) (buffer-name))))
      (message "Saved file name \"%s\" in killring." name)
      (kill-new name)
      name)))

(define-key mode-line-buffer-identification-keymap [mode-line mouse-2] 'copy-buffer-file-name)
(define-key mode-line-buffer-identification-keymap [mode-line S-mouse-2] '(lambda (e) (interactive "e") (copy-buffer-file-name e 't)))
Tobias
sumber
3

C-x C-d, juga dapat dipanggil melalui M-x list-directory, akan menampilkan direktori untuk file Anda saat ini, dan Anda hanya perlu menekan tombol "Enter" untuk menghapus minibuffer. Detail tambahan tersedia di sini .

MLev
sumber
jawaban favorit saya, sederhana, cepat dan mudah!
ticktock
2

C-x C-b menunjukkan daftar buffer dan jalur file untuk setiap buffer jika berlaku.

David
sumber
2

C-u C-x C-b daftar buffer yang sedang mengunjungi file.

memeplex
sumber
1

Dapatkah saya menyalin nama jalur ke papan klip Sistem (OS), bukan cincin pemutus sehingga saya dapat menggunakan info tersebut dengan aplikasi lain?

Anda bisa jika Anda keluar untuk sesuatu seperti xclip (Linux), pbcopy (Mac), putclip (Cygwin).

Saya pribadi menggunakan skrip pembungkus cdan puntuk salin dan tempel masing-masing, bacaan pertama dari input standar, tulisan terakhir ke output standar. Dengan begitu, ini berfungsi di semua platform pengembangan saya:

(shell-command (format "echo '%s' | c" buffer-file-name))

Saya merasa ini lebih dapat diandalkan dan dapat dikonfigurasi daripada menggunakan dukungan papan klip Emacs. Misalnya, cperintah saya menyalin input ke semua 3 papan klip di Linux (primer, sekunder, papan klip), jadi saya dapat menempel dengan Ctrl-V atau klik tengah.

Barry Kelly
sumber
Ini seharusnya berhasil tetapi tidak untuk saya. (Ubuntu 14.04.1.) Yaitu, date | xclipdan xclip filekeduanya berfungsi seperti yang diiklankan (menyimpan tanggal atau konten file ke primer) jika diketik di shell. Tetapi jika saya mengetik salah satu dari perintah ini setelah M-! di emacs (dan tekan kembali) tidak ada yang terjadi; kursor tetap berada di minibuffer seolah-olah mengharapkan lebih banyak input; dan jika saya menyela untuk mendapatkan kembali kendali, tidak ada yang disimpan di primer.
Retribusi Silvio
Oke, ide Anda bekerja dengan baik dengan xsel daripada xclip: (shell-command (format "echo '%s' | xsel -i" buffer-file-name))- dan ketika dibuat menjadi perintah interaktif (seperti yang disarankan dalam jawaban yang paling banyak dipilih oleh @JeromeRadix di atas), ini adalah KEBERANGKATAN BESAR! Terima kasih!
Retribusi Silvio
0

Cara paling sederhana dan pasti

(buffer-name)<(C-x)(C-e)> for the file name to appear in the echo area

(buffer-name)<(C-u)(C-x)(C-e)> would print the location <here>

Meminjam dari Trey Jackson, saya mendapatkan ini:

(defun buffer-kill-path ()
  "copy buffer's full path to kill ring"
  (interactive)
  (kill-new (buffer-file-name)))

Anda dapat menemukan informasi lebih lanjut di situs

DJJ
sumber