Efficient File Searching in Emacs: Leveraging completing-read with Customizable Methods

I thought I would share a little bit of elisp that I’ve been using for a while now that allows me to quickly find a file. It leverages completing-read, allows the selection of the find method and will search recursively.

When called you can select which search type you prefer:

You can select the built-in find-name-dired but as you see I can also choose an external find tool such as find, fd or rg and it should be flexible enough to add in any others by expanding find-options in the function below:

(defun my/find-file ()
  "Find file from current directory in many different ways."
  (interactive)
  (let* ((find-options '(("find -type f -printf \"$PWD/%p\\0\"" . :string)
                          ("fd --absolute-path --type f -0" . :string)
                          ("rg --follow --files --null" . :string)
                          ("find-name-dired" . :command)))
          (selection (completing-read "Select : " find-options))
          (metadata '((category . file)))
          (file-list)
          (file))
    (pcase (alist-get selection find-options nil nil #'string=)
      (:command
        (call-interactively (intern selection)))
      (:string
        (setq file-list (split-string (shell-command-to-string selection) "\0" t))
        (setq file (completing-read (format "Find file in %s: " (abbreviate-file-name default-directory))
                     (lambda (str pred action)
                       (if (eq action 'metadata)
                         `(metadata . ,metadata)
                         (complete-with-action action file-list str pred)))
                     nil t nil 'file-name-history)))
      (when file (find-file (expand-file-name file))))))

To be completely honest, I don’t really use Emacs’ built-in find functions, such as find-file and find-name-dired. Here are a few reasons why:

By considering these reasons, I’ve found that external tools better fit my workflow compared to the built-in Emacs find functions when wanting to find a file quickly.

P.S. I still have a fondness for the basic find command, which I continue to use, particularly on the command line and especially when operating through SSH. However, I still can’t remember how to prune directories!, but then who can? 😀

Comments

comments powered by Disqus