Obtenez tous les noms de fichiers dans le tampon Dired actuel avec Elisp

10

Comme le titre l'indique, comment puis-je obtenir toutes les entrées de fichier dans un tampon Dired en utilisant Elisp?

Tu Do
la source
1
Si cette question est aussi simple qu'elle en a l'air, tout ce dont vous avez besoin est directory-files.
Jordon Biondo du
@JordonBiondo Bon à savoir une autre fonction plus générique. À l'origine, j'avais l'intention d'utiliser with-current-buffersur un tampon Dired pour obtenir une liste de fichiers ou de fichiers marqués. Pour une liste de tous les fichiers, je peux maintenant utiliser directory-files.
Tu Do
@JordonBiondo Je l'ai réessayé. Votre méthode ne fonctionne que lorsque nous avons un tampon Dired "approprié". Si nous avons un tampon Dired personnalisé inséré avec des fichiers arbitraires de différents répertoires, ce directory-filesn'est pas une option.
Tu Do

Réponses:

7

Manipuler les marques semble inutile et peut-être problématique.

De toute évidence, il y a des fonctionnalités dans dired pour faire ce genre de chose (bien que ce ne soit pas bien documenté). Voici une approche simple:

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

Éditer:

Dans les commentaires, vous dites que vous souhaitez que la liste résultante inclue les chemins de répertoire ainsi que les chemins de fichier.

dired-map-dired-file-linesexclut explicitement les répertoires et il n'y a pas d'option pour les inclure; mais il est facile de définir une fonction qui le fait, simplement en copiant l'original et en omettant le test indésirable:

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

Utilisez-le simplement à la place de dired-map-dired-file-linesdans la fonction initiale. Vous pouvez également exclure également l' declare-functionappel.

Vous pouvez, bien sûr, modifier davantage cette nouvelle fonction pour créer directement la liste souhaitée, au lieu d'appeler une fonction pour le faire. Je pense que l'approche plus générale est bien en pratique, mais vous préférerez peut-être l'idée de tout regrouper dans une seule fonction.

phils
la source
Existe-t-il une version non CL? J'aime CL, mais je ne peux pas utiliser la dépendance CL dans Projectile.
Tu Do
cl-fletdéfinit juste une fonction. Cela rend le code plus propre, mais ce n'est qu'une fonction, alors définissez-en une comme vous le souhaitez. Ou n'utilisez pas dired-map-dired-file-linesdu tout, et dupliquez et modifiez son code à la place.
phils
tu as raison. Le basculement des marques efface les anciennes marques, ce qui est problématique. Je considère que votre réponse est la bonne.
Tu Do
votre solution semble récupérer uniquement les fichiers, mais pas de répertoire. Veuillez le mettre à jour lorsque cela est possible.
Tu Do
Ouais, je viens juste de me dired-get-filenameséparer (dired-get-filename t t)pour avoir tout.
Tu Do
6

Je ne sais pas s'il y a une seule fonction qui fait cela, mais cela peut fonctionner pour vous:

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

Parfois, vous pouvez le simplifier pour:

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

En plus de la réponse de @ abo-abo, qui vous indique comment obtenir une liste des noms de fichiers (& dir):

Selon ce que vous voulez, vous pouvez également utiliser dired-copy-filename-as-kill(lié à w) au lieu de dired-get-marked-files.

Il place les noms de fichiers dans une chaîne unique, séparée par des espaces , et pousse cette chaîne dans le kill-ring.

(La séparation d'espace signifie, bien sûr, que ce n'est pas si utile lorsque certains des noms de fichiers contiennent eux-mêmes des caractères d'espace. ;-))

A dessiné
la source