Dapatkan semua nama file dalam buffer Dired saat ini dengan Elisp

10

Seperti judulnya, bagaimana cara mendapatkan semua entri file dalam buffer Dired menggunakan Elisp?

Tu Do
sumber
1
Jika pertanyaan ini sesederhana kelihatannya, yang Anda butuhkan adalah directory-files.
Jordon Biondo
@JordonBiondo Baik untuk mengetahui fungsi lain yang lebih umum. Awalnya saya bermaksud menggunakan with-current-bufferbuffer Dired untuk mendapatkan daftar file atau file yang ditandai. Untuk daftar semua file, sekarang saya dapat menggunakan directory-files.
Tu Do
@JordonBiondo Saya sudah mencobanya lagi. Metode Anda hanya berfungsi ketika kami memiliki buffer Dired "benar". Jika kami memiliki buffer Dired khusus yang disisipkan dengan file sewenang-wenang dari direktori yang berbeda, maka directory-filesitu bukan opsi.
Tu Do

Jawaban:

7

Memanipulasi tanda tampaknya tidak perlu, dan mungkin bermasalah.

Jelas ada fungsi dalam dired untuk melakukan hal semacam ini (meskipun tidak didokumentasikan dengan baik). Inilah pendekatan sederhana:

;; Silence compile-time warning:
(declare-function dired-map-dired-file-lines "dired-aux")

(defun my-dired-files ()
  "Return a list of files (only) in the current dired buffer."
  (eval-when-compile (require 'cl-lib))
  (require 'dired-aux)
  (let (flist)
    (cl-flet ((fpush (fname) (push fname flist)))
      (dired-map-dired-file-lines #'fpush))
    (nreverse flist)))

Edit:

Dalam komentar yang Anda katakan Anda ingin daftar yang dihasilkan untuk menyertakan jalur direktori serta jalur file.

dired-map-dired-file-linessecara eksplisit mengecualikan direktori, dan tidak ada opsi untuk memasukkannya; tetapi mudah untuk mendefinisikan fungsi yang berfungsi, cukup dengan menyalin yang asli dan menghilangkan tes yang tidak diinginkan:

(defun my-dired-map-over-files-and-dirs (fun)
  "Perform FUN with point at the end of each file or directory line.
FUN takes one argument, the absolute filename."
  (save-excursion
    (let (file buffer-read-only)
      (goto-char (point-min))
      (while (not (eobp))
        (save-excursion
          (and (not (eolp))
               (setq file (dired-get-filename nil t)) ; nil on non-file
               (progn (end-of-line)
                      (funcall fun file))))
        (forward-line 1)))))

Cukup gunakan ini sebagai pengganti dired-map-dired-file-linesfungsi awal. Anda juga dapat mengecualikan declare-functionpanggilan.

Anda dapat, tentu saja, lebih lanjut memodifikasi fungsi baru ini untuk membuat daftar yang diinginkan secara langsung, alih-alih memanggil fungsi untuk melakukan itu. Saya merasa pendekatan yang lebih umum baik-baik saja dalam praktiknya, tetapi Anda mungkin lebih suka gagasan membungkus semuanya menjadi satu fungsi.

phils
sumber
Apakah ada versi non-CL? Saya suka CL, tetapi saya tidak dapat menggunakan dependensi CL di Projectile.
Tu Do
cl-flethanya mendefinisikan suatu fungsi. Itu membuat kode lebih bersih, tetapi masih hanya sebuah fungsi, jadi tentukan satu namun Anda perlu. Atau jangan gunakan dired-map-dired-file-linessama sekali, dan sebaliknya duplikat dan modifikasi kodenya sesuai kebutuhan.
phils
kamu benar. Toggling mark menghapus bekas yang bermasalah. Saya menganggap jawaban Anda yang benar.
Tu Do
solusi Anda tampaknya hanya mengambil file, tetapi tidak ada direktori. Harap perbarui jika memungkinkan.
Tu Do
Ya, saya baru saja memodifikasi dired-get-filenamebagian (dired-get-filename t t)untuk mendapatkan semuanya.
Tu Do
6

Saya tidak tahu apakah ada satu fungsi yang melakukan ini, tetapi ini bisa bekerja untuk Anda:

(let (r)
  (dired-unmark-all-files ?\r nil)
  (dired-toggle-marks)
  (setq r (dired-get-marked-files))
  (dired-toggle-marks)
  r)

Terkadang Anda dapat menyederhanakannya menjadi:

(progn (dired-toggle-marks)
       (dired-get-marked-files))
abo-abo
sumber
3

Selain jawaban @ abo-abo, yang memberi tahu Anda cara mendapatkan daftar nama file (& dir):

Bergantung pada apa yang Anda inginkan, Anda dapat menggunakan dired-copy-filename-as-kill(secara terikat w) sebagai gantinya dired-get-marked-files.

Ini menempatkan nama file menjadi string tunggal, dipisahkan oleh spasi , dan mendorong string itu ke kill-ring.

(Pemisahan ruang berarti, tentu saja, itu tidak begitu membantu ketika beberapa nama file itu sendiri mengandung karakter spasi. ;-))

Drew
sumber