Pobierz wszystkie nazwy plików w bieżącym buforze Dired za pomocą Elisp


10

Jak sugeruje tytuł, jak uzyskać wszystkie wpisy pliku w buforze Dired za pomocą Elisp?


1
Jeśli to pytanie jest tak proste, jak się wydaje, wystarczy directory-files.
— Jordon Biondo

@JordonBiondo Dobrze wiedzieć o innej bardziej ogólnej funkcji. Pierwotnie zamierzałem używać with-current-bufferbufora Dired, aby uzyskać listę plików lub oznaczonych plików. Aby wyświetlić listę wszystkich plików, mogę teraz użyć directory-files.
— Tu Do

@JordonBiondo Próbowałem jeszcze raz. Twoja metoda działa tylko wtedy, gdy mamy „właściwy” bufor Dired. Jeśli mamy niestandardowy bufor Dired wstawiany z dowolnymi plikami z różnych katalogów, directory-filesnie ma takiej opcji.
— Tu Do

Odpowiedzi:


7

Manipulowanie znakami wydaje się niepotrzebne i być może problematyczne.

Oczywiście istnieje funkcjonalność w obrębie dired do robienia takich rzeczy (choć nie jest to dobrze udokumentowane). Oto proste podejście:

;; 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)))

Edytować:

W komentarzach mówisz, że chcesz, aby powstała lista zawierała ścieżki katalogu, a także ścieżki plików.

dired-map-dired-file-lineswyraźnie wyklucza katalogi i nie ma możliwości ich włączenia; ale łatwo jest zdefiniować funkcję, która działa, po prostu kopiując oryginał i pomijając niechciany test:

(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)))))

Po prostu użyj tego zamiast dired-map-dired-file-linesfunkcji początkowej. Następnie możesz również wykluczyć declare-functionpołączenie.

Można oczywiście zmodyfikować tę nową funkcję, aby bezpośrednio utworzyć żądaną listę, zamiast wywoływać funkcję, aby to zrobić. Wydaje mi się, że bardziej ogólne podejście jest dobre w praktyce, ale może wolisz pomysł zawinięcia tego w jedną funkcję.


Czy istnieje wersja inna niż CL? Lubię CL, ale nie jestem w stanie używać zależności CL w pocisku.
— Tu Do

cl-fletpo prostu definiuje funkcję. Sprawia, że ​​kod jest czystszy, ale wciąż jest tylko funkcją, więc zdefiniuj ją, jednak musisz. Lub nie używaj go dired-map-dired-file-lineswcale, zamiast tego powielaj i modyfikuj jego kod w razie potrzeby.
— phils

masz rację. Przełączanie znaków usuwa stare znaki, co jest problematyczne. Uważam, że twoja odpowiedź jest prawidłowa.
— Tu Do

Twoje rozwiązanie wydaje się pobierać tylko pliki, ale nie ma katalogu. Zaktualizuj go, jeśli to możliwe.
— Tu Do

Tak, właśnie zmodyfikowałem, aby się dired-get-filenamerozstać, (dired-get-filename t t)aby uzyskać wszystko.
— Tu Do

6

Nie wiem, czy jest jedna funkcja, która to robi, ale może to działać dla Ciebie:

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

Czasami możesz to uprościć:

(progn (dired-toggle-marks)
       (dired-get-marked-files))

3

Oprócz odpowiedzi @ abo-abo, która mówi, jak uzyskać listę nazw plików (i katalogów):

W zależności od tego, czego chcesz, możesz alternatywnie użyć dired-copy-filename-as-kill(związany z w) zamiast dired-get-marked-files.

Umieszcza nazwy plików w jednym ciągu oddzielonym spacjami i przekazuje ten ciąg do pliku kill-ring.

(Separacja spacji oznacza oczywiście, że nie jest to tak pomocne, gdy niektóre nazwy plików zawierają spacje. ;-))

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.