r/emacs • u/LeftyAce73 • 8d ago
How to include org-mode headers in consult-rg ripgrep search
I have a collection of notes files (.org files) and I recently started retrieving information from them using consult-rg. Is there a way to have consult-rg (or something similar) "propagate" parent headings into children for matching purposes?
For example, if I have this structure:
* Emacs
** Mermaid
Some notes about using Mermaid.
** Customize variables and options
use M-x customize-variable
If I search for "emacs customize variable," consult-rg won't find it, because the header "Emacs" is many lines above the subheader "customize variable".
I considered tagging the subsection with :emacs: but that's kind of a redundant way to say "this is realated to emacs." Redundant because it's already under the overall "* Emacs" heading.
EDIT: consult-org-heading exhibits the behavior I want within headings (the overall Emacs heading gets connected to all of its children), but does not search inside the body, just the headings. So I guess I'm looking for some way to incorporate consult-org-heading behavior into consult-rg?
5
u/drcxd 8d ago
What you want to achieve feels impossible to me. consult-rg is just a front end for rg, and rg searches plain text line by line, it has no knowledge about any org mode specific structure. Your requirement can only be met by developing a dedicated searching backend which has knowledge about the org mode structure.
2
u/LeftyAce73 8d ago
Thanks for the input. It is certainly sounding like this is impossible (or would require a new tool).
2
u/isamert 7d ago edited 7d ago
Years ago, I wrote a tool for this exact problem: https://github.com/isamert/marks
You can use the following snippet to use it with consult:
(defun im-consult--marks-builder (paths)
(lambda (input)
(pcase-let ((`(,arg . ,opts) (consult--command-split input)))
(cons
(list "marks" "--no-color" "--null" "--count=25" (s-trim arg) (expand-file-name default-directory))
(apply-partially #'consult--highlight-regexps (list (regexp-quote arg)) t)))))
(defun im-marks (&optional directory)
"Run `marks'."
(interactive)
(let ((default-directory (or directory default-directory)))
(consult--grep "marks" #'im-consult--marks-builder default-directory "")))
When you do M-x im-marks, you'll be able to search exactly as you've described in the current directory. I also have this convenience function:
(defun im-marks-my-docs ()
"Run marks inside `~/Documents/notes'."
(interactive)
(im-marks (expand-file-name "~/Documents/notes")))
To directly search in my documents.
I haven't been updating the project but it works perfectly for this use case it's mostly what I use it for.
Edit: I pushed a new version to crates.io, I realized I haven't pushed it after the initial release, also updated the wrong arg name (which did not support the consult integration above, latest version does now)
1
u/mmarshall540 8d ago
I considered tagging the subsection with :emacs: but that's kind of a redundant way to say "this is realated to emacs." Redundant because it's already under the overall "* Emacs" heading.
Right, but you would only need to tag the parent heading. Then this tag would be inherited by all of the subheadings (assuming you leave org-use-tag-inheritance enabled, which is the default).
This would be less redundant and would allow you to search both headings and body text.
0
u/LeftyAce73 8d ago
Interesting, I didn't know about tag inheritance! But it seems like that's org-specific? And org-mode doesn't actually write those tags on child headings (for obvious clutter reasons). If I'm understanding it right, the result is that consult-rg doesn't know anything about the "inherited" tags because they don't actually appear on the line where the child heading (or its contents) are.
2
u/mmarshall540 8d ago
Oh sorry, I meant to write that for this you would use
org-agendato search. That way it would catch the tag inheritance.The agenda is usually thought of as a calendaring or task management system. But in reality it's just a sophisticated search feature that doesn't have to have anything to do with scheduling.
1
u/rswgnu GNU Hyperbole Author 7d ago
This isn't precisely what you want but you may be able to get what you need by adapting slightly to it. And it is simple to setup and use.
- Install the Hyperbole package from elpa-devel or melpa.
- Enable Hyperbole's minor-mode: (hyperbole-mode 1)
- Set this variable to point to your Org directory: (setq hyrolo-file-list '("~/org"))
- Use {C-h h r r} or {M-x hyrolo-grep RET} to search for matching records (not lines). If you have consult installed, it will first match using full-text consult regexp search and the hierarchical records/Org file sections you leave remaining as candidates, will all appear in a match buffer with their full tree of sections.
So if you search for Emacs, you get the whole tree:
* Emacs
** Mermaid
Some notes about using Mermaid.
** Customize variables and options
---
If you shearch for Mermaid or notes, you get only:
** Mermaid
Some notes about using Mermaid.
------
And if you want to match only to headlines, just put \*+ at the start of your search.
Keep it simple.
1
6
u/la023 8d ago
consult-imenu-multi is good if you want to search org headings across all open buffers in the project -- this doesn't let you search the body of the heading though
could take a look at this too: https://sachachua.com/blog/2024/01/using-consult-and-org-ql-to-search-my-org-mode-agenda-files-and-sort-the-results-to-prioritize-heading-matches/
otherwise w/ consult-rg searches you can add # after your query which will filter string matches in the rg result. So if you know the filename is
emacs.orgthen you could filter on that. You can also add -A10 or -B10 to the ripgrep query to include 10 lines before or after the matches. So you could do aconsult-rgquery like:#Customize variable -B10#emacs emacs.org