Ottieni tutti i nomi di file nel buffer Dired corrente con Elisp


10

Come suggerisce il titolo, come posso ottenere tutte le voci del file in un buffer Dired usando Elisp?


1
Se questa domanda è semplice come sembra, tutto ciò che serve è directory-files.
Jordon Biondo,

@JordonBiondo Buono a sapersi un'altra funzione più generica. Inizialmente intendevo utilizzare with-current-bufferun buffer Dired per ottenere un elenco di file o file contrassegnati. Per un elenco di tutti i file, ora posso usare directory-files.
Tu Do

@JordonBiondo L'ho provato di nuovo. Il tuo metodo funziona solo quando abbiamo un buffer Dired "corretto". Se abbiamo un buffer Dired personalizzato che è stato inserito con file arbitrari di directory diverse, allora directory-filesnon è un'opzione.
Ma Do,

Risposte:


7

Manipolare i segni sembra superfluo e forse problematico.

Ovviamente c'è una funzionalità all'interno di dired per fare questo genere di cose (anche se non ben documentato). Ecco un approccio semplice:

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

Modificare:

Nei commenti dici che desideri che l'elenco risultante includa i percorsi della directory e i percorsi dei file.

dired-map-dired-file-linesesclude esplicitamente le directory e non è possibile includerle; ma è facile definire una funzione che lo fa, semplicemente copiando l'originale e omettendo il test indesiderato:

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

Basta usare questo al posto di dired-map-dired-file-linesnella funzione iniziale. È quindi possibile anche escludere la declare-functionchiamata.

Naturalmente, è possibile modificare ulteriormente questa nuova funzione per creare direttamente l'elenco desiderato, invece di chiamare una funzione per farlo. Penso che l'approccio più generale vada bene in pratica, ma potresti preferire l'idea di racchiudere tutto in un'unica funzione.


Esiste una versione non CL? Mi piace CL, ma non sono in grado di utilizzare la dipendenza CL in Projectile.
Ma Do,

cl-fletdefinisce solo una funzione. Rende il codice più pulito, ma è ancora solo una funzione, quindi definirne uno come è necessario. O non usare dired-map-dired-file-linesaffatto, e invece duplicare e modificare il suo codice secondo necessità.
phils,

hai ragione. La disattivazione dei segni cancella i vecchi segni, il che è problematico. Considero la tua risposta quella corretta.
Tu Do

la tua soluzione sembra recuperare solo i file, ma nessuna directory. Si prega di aggiornarlo quando possibile.
Tu Do

Sì, ho appena modificato la dired-get-filenameparte (dired-get-filename t t)per ottenere tutto.
Tu Do

6

Non so se esiste una sola funzione che lo fa, ma questo può funzionare per te:

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

A volte puoi semplificarlo per:

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

3

Oltre alla risposta di @ abo-abo, che spiega come ottenere un elenco dei nomi dei file (& dir):

A seconda di ciò che si desidera, è possibile utilizzare dired-copy-filename-as-kill(associato a w) anziché dired-get-marked-files.

Mette i nomi dei file in una singola stringa separata da spazio e invia quella stringa al file kill-ring.

(La separazione degli spazi significa, ovviamente, che non è così utile quando alcuni dei nomi dei file stessi contengono caratteri spaziali. ;-))

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.