像consult-line一样搜索dired buffer

最近有用orderless筛选dired buffer的需求,所以才有了标题所说的

方案一:dired-goto-file emacs自带,但是只能搜索当前dired-header下的目录,如果使用dired-insert-subdir插入了多个目录,不能同时搜索这些目录。

方案二:用consult-line,缺点因为是基于occor-mode,embark-export没法导出为dired buffer,如果想进一步做文件管理相关的操作不太好用。

方案三: consult-find或者consult-fd之类的补全命令,能避免之前两个方案的缺点,不过这样好像不算搜索dired buffer,而是直接搜索文件名了。

方案四: 让dired-goto-file 支持补全整个dired buffer,需要自己写一个:

  (defun dired-list-files (&optional localp no-error-if-not-filep)
    "List all files in current Dired buffer.

Adapted from `dired-toggle-marks'."
    (if (derived-mode-p 'dired-mode)
        (save-excursion
          (let (files
                (inhibit-read-only t)
                (beg (dired-mark--region-beginning))
                (end (dired-mark--region-end)))
            (goto-char beg)
            (while (< (point) end)
              (or (dired-between-files)
                  (looking-at-p dired-re-dot)
                  (push (cons (dired-get-filename localp no-error-if-not-filep) (point)) files))
              (forward-line 1))
            files))
      (user-error "Not A Dired Buffer!")))

  (defun dired-swiper ()
    "Jump to files in current Dired buffer with completion."
    (interactive nil dired-mode)
    (let* ((files (dired-list-files))
           (completion-extra-properties '(:category file))
           (file (completing-read "Find Files: " files nil t)))
      (when file
        (goto-char (cdr (assoc file files))))))

目前我自己用方案四,功能很简单不过够用了

2 个赞

consult-focus-line 也挺好用 需要用以下hook 确保搜索完后光标移动到文件位置

(defun consult-focus-lines-dired()
  (run-with-timer
   0.001 nil #'(lambda()
                 (when (and consult--focus-lines-overlays
                            (eq major-mode 'dired-mode))
                   (if (dired-get-filename t t)
                       (dired-move-to-filename)
                     (dired-previous-line 1))
                   ))))
(add-hook 'minibuffer-exit-hook 'consult-focus-lines-dired)

(pro
1 个赞
(defun my/dired-goto-random-file ()
  "Goto random file in current-buffer."
  (interactive nil dired-mode)
  (dired-goto-file
   (seq-random-elt
    (mapcan (lambda (a) (directory-files (car a) t "^[^.]" t)) dired-subdir-alist))))

写过一个类似的,把 seq-random-elt 换成 completing-read,正则改一下应该就好了

1 个赞

Nice👍,甚至都不用改正则,加个completion category让embark-export能工作就行了

(defun my/dired-goto-file ()
  "Goto file in current-buffer."
  (interactive nil dired-mode)
  (let* ((files (mapcan (lambda (a) (directory-files (car a) t "^[^.]" t)) dired-subdir-alist))
         (completion-extra-properties '(:category file))
         (file (completing-read "Find Files: " files nil t)))
    (dired-goto-file file)))
1 个赞