Obter todos os nomes de arquivos no buffer Dired atual com Elisp

10

Como o título sugere, como obtenho todas as entradas de arquivo em um buffer Dired usando o Elisp?

Tu Do
fonte
11
Se esta pergunta é tão simples quanto parece, tudo o que você precisa é directory-files.
Jordon Biondo 26/10
@JordonBiondo É bom conhecer outra função mais genérica. Originalmente, pretendia usar with-current-bufferum buffer Dired para obter uma lista de arquivos ou arquivos marcados. Para uma lista de todos os arquivos, agora posso usar directory-files.
Tu Do
@JordonBiondo Eu tentei novamente. Seu método só funciona quando temos um buffer Dired "adequado". Se tivermos um buffer direcionado personalizado inserido com arquivos arbitrários de diretórios diferentes, directory-filesnão será uma opção.
Tu Do

Respostas:

7

Manipular marcas parece desnecessário e talvez problemático.

Obviamente, há funcionalidade no dired para fazer esse tipo de coisa (embora não esteja bem documentada). Aqui está uma abordagem simples:

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

Editar:

Nos comentários, você diz que deseja que a lista resultante inclua os caminhos do diretório e os arquivos.

dired-map-dired-file-linesexclui explicitamente diretórios e não há opção para incluí-los; mas é fácil definir uma função que sim, simplesmente copiando o original e omitindo o teste indesejado:

(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 usar isso no lugar da dired-map-dired-file-linesfunção inicial. Você também pode excluir a declare-functionchamada também.

É claro que você poderia modificar ainda mais essa nova função para criar a lista desejada diretamente, em vez de chamar uma função para fazer isso. Eu sinto que a abordagem mais geral é boa na prática, mas você pode preferir a ideia de agrupar tudo em uma única função.

phils
fonte
Existe uma versão não-CL? Eu gosto do CL, mas não consigo usar a dependência do CL no Projectile.
Tu Do
cl-fletapenas define uma função. Isso torna o código mais limpo, mas ainda é apenas uma função, então defina uma como você precisar. Ou não use dired-map-dired-file-linesnada e, em vez disso, duplique e modifique seu código, conforme necessário.
phils
você está certo. A alternância de marcas limpa as marcas antigas, o que é problemático. Considero sua resposta a correta.
Tu Do
sua solução parece recuperar apenas arquivos, mas nenhum diretório. Atualize-o quando possível.
Tu Do
Sim, eu apenas modifiquei a dired-get-filenameparte (dired-get-filename t t)para conseguir tudo.
Tu Do
6

Não sei se existe uma única função que faz isso, mas isso pode funcionar para você:

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

Às vezes você pode simplificá-lo para:

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

Além da resposta do @ abo-abo, que mostra como obter uma lista dos nomes dos arquivos (& dir):

Dependendo do que você deseja, você pode usar dired-copy-filename-as-kill(ligado a w) em vez de dired-get-marked-files.

Ele coloca os nomes dos arquivos em uma única string separada por espaço e envia essa string para o kill-ring.

(É claro que a separação de espaço significa que não é tão útil quando alguns dos nomes de arquivo contêm caracteres de espaço. ;-))

Desenhou
fonte