Получить все имена файлов в текущем буфере Dired с помощью Elisp


10

Как видно из заголовка, как получить все записи в буфере Dired с помощью Elisp?


1
Если этот вопрос так прост, как кажется, все, что вам нужно, это directory-files.
Джордон Биондо

@JordonBiondo Хорошо знать еще одну более общую функцию. Первоначально я намеревался использовать with-current-bufferбуфер Dired для получения списка файлов или помеченных файлов. Для списка всех файлов теперь я могу использовать directory-files.
Ту До

@JordonBiondo Я попробовал это снова. Ваш метод работает только тогда, когда у нас есть «правильный» буфер Dired. Если у нас есть специальный буфер Dired, который вставляется с произвольными файлами из разных каталогов, то directory-filesэто не вариант.
Ту До

Ответы:


7

Управление метками кажется ненужным и, возможно, проблематичным.

Очевидно, в dired есть функциональные возможности, позволяющие делать подобные вещи (хотя и не до конца документированные). Вот простой подход:

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

Редактировать:

В комментариях вы говорите, что хотите, чтобы в результирующем списке были указаны пути к каталогам, а также пути к файлам.

dired-map-dired-file-linesявно исключает каталоги, и нет возможности включить их; но легко определить функцию, которая просто копирует оригинал и пропускает нежелательный тест:

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

Просто используйте это вместо dired-map-dired-file-linesначальной функции. Затем вы также можете исключить declare-functionвызов.

Конечно, вы могли бы дополнительно изменить эту новую функцию, чтобы создать нужный список напрямую, вместо вызова функции для этого. Я чувствую, что более общий подход хорош на практике, но вы можете предпочесть идею объединить все это в одну функцию.


Есть ли не CL версия? Мне нравится CL, но я не могу использовать зависимость CL в Projectile.
Ту До

cl-fletпросто определяет функцию. Это делает код чище, но все же это просто функция, поэтому определите ее так, как вам нужно. Или вообще не используйте dired-map-dired-file-lines, а дублируйте и изменяйте его код по мере необходимости.
Фил

вы правы. Переключение меток удаляет старые метки, что проблематично. Я считаю ваш ответ правильным.
Ту До

кажется, ваше решение извлекает только файлы, но не каталог. Пожалуйста, обновите его, когда это возможно.
Ту До

Да, я только что изменил, чтобы dired-get-filenameрасстаться, (dired-get-filename t t)чтобы получить все.
Ту До

6

Я не знаю, есть ли одна функция, которая делает это, но это может работать для вас:

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

Иногда вы можете упростить это до:

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

3

В дополнение к ответу @ abo-abo, в котором рассказывается, как получить список имен файлов (& dir):

В зависимости от того, что вы хотите, вы можете альтернативно использовать dired-copy-filename-as-kill(привязанный к w) вместо dired-get-marked-files.

Он помещает имена файлов в одну строку , разделенную пробелами , и помещает эту строку в kill-ring.

(Разделение пробела, конечно, означает, что это не очень полезно, когда некоторые имена файлов содержат пробелы. ;-))

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.