1

I often look for information that could be either in some org-mode document, in an old email, or somewhere in the file system (and probably other places). Now I can use org-search, notmuch-search, and locate/find (in the shell) separately, but this is a little tedious as I need to modify the search to figure out the correct incantation. I was sure there was a way to combine searches, but Googling for it, I came up empty handed. Surely there is a solution?

1 Answer 1

1

First improvement may be instead of running "locate/find" queries "in the shell", using interactive Emacs command e.g. consult-grep and consult-find (or whatever other package/completion framework that can help you with this e.g. counsel, icicles, avy, etc. The point is to define your search functions in Elisp so that you don't have to bother with manual input of shell commands every time.

The details of the implementation will best be left to you as you know best your requirements, file and directory structure, types of searches but I can give some general tips:

  1. Learn how you can parametrize search commands so that you can easily define the kind of results you expect - e.g. instead of M-x consult-find and manually inputting everything, you can define a function that fills out some initial data for you (either a predefined argument to a function or an initial string in the minibuffer). For example if you use consult you may create a new interactive defun which calls consult-find like this: (consult-find "~/org-docs/" ".org"). This will search for files in the "~/org-docs/" directory no matter where you call the command in. It also fills the minibuffer with ".org" which is a simplistic way of narrowing the result set to org files. Though for extensions a more proper way could be modifying the arguments/flags used by your backend (grep, ripgrep, find, etc.) around your custom command (just like you often see default-directory set with let to alter it for one command). For example: the built-in grep.el has grep-find-use-xargs, consult has consult-find-args - use describe-variable with keywords such as flag, arg and grep, find to see what is possible.

  2. Consider whether you actually need to combine the search results everytime - often you know from context (e.g. the major mode of the buffer you're in) what you will look for: so you can keep using the dedicated search commands you're using (for notmuch, for text in org files) and if you create a custom command that would dispatch a proper search function, you can bind this to a single key and can combine multiple searches while avoiding doing any merging or writing much Elisp yourself.

  3. However, if you can't rely on context too much, you can try writing more complex functions yourself. I would suggest browsing the source of consult and vertico - keywords: source, group, multi. You can similarly combine whatever you desire and have a uniform interface in the minibuffer for browsing, navigating and running actions on results. Right now you can try command that does this (try consult-grep) and notice how you can go between groups with vertico-next-group and vertico-previous-group. I think helm implemented something similar - dividing results into buffers, files, directories in some commands.

Lastly, if you don't want to bother with result types at all but just want to quickly search for "everything", what will work surprisingly well in some cases is a text search on all your opened buffers. Obviously this won't search whole directory in the filesystem and all the files - just what you have opened. But if you have long-running Emacs sessions you may have hundreds of buffers opened with a small but currently relevant text. This should work (based on consult):

(defun consult-line-multi-all-buffers ()
  (interactive)
  (let ((current-prefix-arg (or 'all-buffers arg))) (call-interactively 'consult-line-multi))
  )

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.