Holen Sie sich mit Elisp alle Dateinamen in den aktuellen Dired-Puffer

10

Wie erhalte ich, wie der Titel schon sagt, mit Elisp alle Dateieinträge in einem Dired-Puffer?

Tu Do.
quelle
1
Wenn diese Frage so einfach ist, wie sie aussieht, brauchen Sie nur directory-files.
Jordon Biondo
@JordonBiondo Gut zu wissen, eine andere allgemeinere Funktion. Ursprünglich wollte ich with-current-buffereinen Dired-Puffer verwenden, um eine Liste von Dateien oder markierten Dateien zu erhalten. Für eine Liste aller Dateien kann ich jetzt verwenden directory-files.
Tu Do
@JordonBiondo Ich habe es erneut versucht. Ihre Methode funktioniert nur, wenn wir einen "richtigen" Dired-Puffer haben. Wenn wir einen benutzerdefinierten Dired-Puffer haben, der mit beliebigen Dateien aus verschiedenen Verzeichnissen eingefügt wird, directory-filesist dies keine Option.
Tu Do

Antworten:

7

Das Manipulieren von Markierungen erscheint unnötig und möglicherweise problematisch.

Offensichtlich gibt es Funktionen, die dazu bestimmt sind (wenn auch nicht gut dokumentiert). Hier ist ein einfacher Ansatz:

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

Bearbeiten:

In den Kommentaren möchten Sie, dass die resultierende Liste sowohl die Verzeichnispfade als auch die Dateipfade enthält.

dired-map-dired-file-linesschließt Verzeichnisse ausdrücklich aus, und es gibt keine Möglichkeit, sie einzuschließen. Es ist jedoch einfach, eine Funktion zu definieren, die dies tut, indem Sie einfach das Original kopieren und den unerwünschten Test weglassen:

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

Verwenden Sie dies einfach anstelle dired-map-dired-file-linesder ursprünglichen Funktion. Sie können den declare-functionAnruf dann auch ausschließen .

Sie können diese neue Funktion natürlich weiter modifizieren, um die gewünschte Liste direkt zu erstellen, anstatt eine Funktion aufzurufen, um dies zu tun. Ich bin der Meinung, dass der allgemeinere Ansatz in der Praxis in Ordnung ist, aber Sie könnten die Idee bevorzugen, alles in eine einzige Funktion zu packen.

Phils
quelle
Gibt es eine Nicht-CL-Version? Ich mag CL, kann aber die CL-Abhängigkeit in Projectile nicht verwenden.
Tu Do
cl-fletdefiniert nur eine Funktion. Es macht den Code sauberer, aber es ist immer noch nur eine Funktion. Definieren Sie also eine, wie Sie müssen. Oder verwenden Sie es überhaupt nicht dired-map-dired-file-linesund duplizieren und ändern Sie stattdessen den Code nach Bedarf.
Phils
Du hast recht. Durch das Umschalten von Markierungen werden die alten Markierungen gelöscht, was problematisch ist. Ich halte Ihre Antwort für die richtige.
Tu Do
Ihre Lösung scheint nur Dateien abzurufen, aber kein Verzeichnis. Bitte aktualisieren Sie es wenn möglich.
Tu Do
Ja, ich habe nur auf modifizierte dired-get-filenameTeil (dired-get-filename t t)alles zu bekommen.
Tu Do
6

Ich weiß nicht, ob es eine einzige Funktion gibt, die dies tut, aber dies kann für Sie funktionieren:

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

Manchmal können Sie es vereinfachen, um:

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

Zusätzlich zur Antwort von @ abo-abo, in der Sie erfahren, wie Sie eine Liste der Dateinamen (& dir) erhalten:

Je nachdem, was Sie möchten, können Sie alternativ dired-copy-filename-as-kill(gebunden an w) anstelle von verwenden dired-get-marked-files.

Es fügt die Dateinamen in eine einzelne, durch Leerzeichen getrennte Zeichenfolge ein und verschiebt diese Zeichenfolge an die kill-ring.

(Leerzeichen bedeutet natürlich, dass es nicht so hilfreich ist, wenn einige der Dateinamen selbst Leerzeichen enthalten. ;-))

Drew
quelle