Elenca ricorsivamente tutti i file e le sottodirectory


15

Esiste un modo, possibilmente usando un pacchetto, per elencare in modo ricorsivo tutti i file (con percorsi) e le sottodirectory (o almeno le sottodirectory vuote , dal momento che i percorsi di quelle non vuote possono essere raccolti dai percorsi di i file in essa contenuti) della directory corrente?

Il più vicino che ho trovato è la projectile-find-filefunzione del projectilepacchetto (in alternativa, la helm-projectile-find-filefunzione del helm-projectilepacchetto), ma non sembra essere in grado di elencare le cartelle vuote. Inoltre, sembra funzionare solo con Git e altri repository di controllo versione, ma potrebbe esserci una soluzione alternativa per questa limitazione.


2
non so esattamente cosa cerchi di fare, ma [questo post del blog] (www.turingmachine.org/bl/2013-05-29-recursively-listing-directories-in-elisp.html) potrebbe contenere ciò di cui hai bisogno, oppure puoi provare [questo] (ergoemacs.org/emacs/elisp_traverse_dir.html) come antipasto.
theldoria,

Cosa intendi con "elenco"? Vuoi un Emacs Lisp funzioni che restituiscono un elenco di stringhe con i percorsi? Vuoi un buffer con i percorsi in esso, diciamo, uno per riga? Vuoi un buffer diretto con tutti i file? (Quest'ultimo è facile, aggiungi "-R" agli interruttori ls in dired.)
Omar


@Omar: devo soddisfare i requisiti ideali: (1) che farà parte di Emacs o parte di un pacchetto, (2) che funzionerà con uno helmo ivy, cioè che i risultati verranno visualizzati in un helmo ivybuffer. Se è impossibile soddisfare entrambi i requisiti, il secondo è più importante per me.
Evan Aad,

1
Sono davvero due domande diverse. OK, ho fornito una risposta per ciascuno.
Estratto il

Risposte:


8

Supponendo che si utilizza ivyè possibile utilizzare questa funzione

    (defun fhd/counsel-everything ()
      "list everything recursively"
      (interactive)
      (let* ((cands (split-string
                     (shell-command-to-string "find .") "\n" t)))
        (ivy-read "File: " cands
                  :action #'find-file
                  :caller 'fhd/counsel-everything)))

Grazie. Cosa succede se uso helm?
Evan Aad,

1
Scusa, non lo so helm. ivyè abbastanza leggero. Dagli un colpo.
fhdhsni,

13

directory-files-ricorsivamente

(Penso che questo sia stato aggiunto in Emacs 25)

ecco il link al manuale: https://www.gnu.org/software/emacs/manual/html_node/elisp/Contents-of-Directories.html

Restituisce tutti i file nella directory i cui nomi corrispondono a regexp. Questa funzione cerca ricorsivamente nella directory specificata e nelle sue sottodirectory i file i cui nomi di base (ovvero, senza le directory principali) corrispondono al regexp specificato e restituisce un elenco di nomi di file assoluti dei file corrispondenti (vedere nomi di file assoluti) . I nomi dei file vengono restituiti nel primo ordine di profondità, il che significa che i file in alcune sottodirectory vengono restituiti prima dei file nella directory principale. Inoltre, i file corrispondenti trovati in ciascuna sottodirectory sono ordinati alfabeticamente in base ai loro nomi di base. Per impostazione predefinita, le directory i cui nomi corrispondono a regexp sono omesse dall'elenco, ma se l'argomento facoltativo include-directory è diverso da zero, sono inclusi.

Esempio

(directory-files-recursively default-directory "")

Non trova directory vuote
fhdhsni,

1
@fhdhsni Hai provato l'impostazione include-directoriesa t? Sono al lavoro su Emacs 24 e non posso provarlo adesso, ma posso provarlo a casa in poche ore.
wvxvw,

Colpa mia. Non l'ho fatto. Potresti volerlo includere nella tua risposta.
fhdhsni,

4

Questa risposta presuppone che si desideri visualizzare un elenco dei nomi di file e dir, anziché ottenere un elenco di Lisp.

Utilizzare i comandi standard di Emacs find-dired, find-name-diredo find-grep-dired. I nomi dei file e delle directory trovati vengono visualizzati in un buffer in modalità Dired. (Puoi mettere tutta la potenza di Dired per lavorare sui risultati.)

Se usi la libreria, find-dired+.elallora hai versioni migliorate di quei comandi standard di Emacs, ti preghiamo di avere un comando find-time-diredche trova file più recenti o più vecchi di un dato timestamp.


find-diredè esattamente quello che sto cercando, ma c'è un modo per stampare solo i nomi? Perché altrimenti il ​​singolo nome di file prende più righe senza motivo poiché non mi interessa assolutamente la dimensione, la data o le autorizzazioni dei file. Ho provato a correre (setcar find-ls-option "-printf '%p\n'")prima find-dired, ma per qualche motivo in questo modo diretto non voglio aprire un file premendo Invio su un elemento.
Hi-Angel,

2
@ Hi-Angel: il buffer in cui vengono visualizzati i risultati è in modalità Dired. Quindi puoi semplicemente premere (per attivare / disattivare la visualizzazione di più dei nomi dei file. Lo lascio per la maggior parte del tempo (nessun dettaglio mostrato) e lo accendo brevemente quando voglio controllare alcuni dettagli.
Ha

1

Vedi https://github.com/technomancy/find-file-in-project

Ci sono comandi per trovare file o trovare directory. Ma non entrambi.

Se vuoi solo elencare tutte le sottodirectory e i file in modo ricorsivo in un buffer, ci sono due comandi incorporati in Emacs da secoli:

  1. M-x find-dired. Dipende dallo strumento CLI find. Su Windows, è necessario installare Cygwin o MYSYS che hafind

  2. M-x find-lisp-find-dired. Lo stesso di find-diredma scritto in Lisp. Quindi non esiste dipendenza da terzi. Inoltre, è in grado di riconoscere le impostazioni internazionali predefinite. Ma è più lento difind-dired


Il mio caso d'uso sarebbe lo stesso di chiunque usi il comando shell UNIX lso la funzione Emacs find-file, entrambi i quali elencano sia i file che le directory, comprese le directory vuote.
Evan Aad,

Sono find-direde find-lisp-find-diredricorsivo che elencano non solo il contenuto della directory corrente, ma anche il contenuto di ciascuno dei suoi sub-directory, sub-sub-directory, ecc?
Evan Aad,

Sì, ricorsivamente
chen bin

1

Questa risposta presuppone che si desideri ottenere un elenco Lisp dei nomi di file e dir, anziché visualizzarne un elenco.

Se si utilizza la libreria Dired +, è possibile utilizzare la funzione diredp-files-within. (Non è necessario essere in un buffer Dired per usarlo.)

Funziona con qualsiasi versione di Emacs ed è più generale di directory-files-recursively.

  • Puoi passargli un elenco di file e directory e agisce in modo ricorsivo in ciascuno di essi.

  • Oppure puoi passargli una funzione che restituisce un tale elenco.

    • Se esiste un buffer Dired per una directory che viene elaborata, la funzione viene invocata in quel buffer per restituire l'elenco di file da includere.

      Ad esempio, se la funzione è dired-get-marked-files quindi inclusi solo i file e le sottodirectory contrassegnati .

  • Puoi passargli un predicato che deve soddisfare ogni file o directory. La corrispondenza di Regexp è ovviamente un tipo di predicato.

  • Puoi dire di non seguire i collegamenti simbolici.


0
(defun my-dir-list (fonte)
  ;;
  ;; Stampa i file dell'elenco nel buffer corrente
  ;;
  ;; Non testato, tipo di sistema: gnu
  ;; Testato, tipo di sistema: windows-nt
  ;;
  (interattivo "sDirectory:")
  (let ((n 0)
    (l-file-dir (e (cd source) (directory-file-e-attributi "./")))
    (dir-list '())
    (elenco file '())
    )
    (princ (formato "% s \ n" directory predefinita) (buffer corrente))
    (mentre l-file-dir
      (if (nth 1 (car l-file-dir))
      (setq n (1+ n)
        dir-list (contro ((lambda (fonte)
                  (e (non (string-prefix-p "." (sorgente auto)))))
                (car l-file-dir)) dir-list)
        )
    (princ (formato "% s \ n" (concat default-directory
                      (e (stringa-corrispondenza "\\. [0-9 | Az]" (caar l-file-dir))
                       (caar l-file-dir)))) (current-buffer))
    )
      (setq l-file-dir (cdr l-file-dir))
      )
    (while (elenco directory caar)
      (elenco-directory setq (elenco-directory cdr))
      (cd "..")
      )
    )
  'ok
  )
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.