I was recently made aware of the fact that doom emacs implements a way to implement regex search inside org-id links itself, I translated the functions to vanilla and created a wrapper script with consult-org-heading to automate insertion of these fuzzy links. This way there is no necessity to create ID for headings – even those that I want to refer to because I can trivially do
[[id:<idvalue>::*Heading-name]] and it would automatically link to that heading inside the file where the ID originates from.
I have been told that org-ql and embark can make my life a lot easier – but I dont use those packages, so I have to come up with hacky ways to get job done.
This will reduce the need to create unnecessary IDs for linking.
;; requires consult-org-heading
(defun org-roam-node-insert-fuzzy ()
"Insert a new Org Roam note with fuzzy search."
(interactive)
(org-mark-ring-push)
(org-roam-node-find)
(goto-char (point-min))
(let ((node-id (org-entry-get nil "ID")))
(message "node-id: %s" node-id)
(consult-org-heading)
(let ((headline-text (org-get-heading t t t t)))
(message "headline-text: %s" headline-text)
(org-mark-ring-goto 1)
(message "[[id:%s::*%s][%s]]" node-id headline-text headline-text)
(insert (format "[[id:%s::*%s][%s]]" node-id headline-text headline-text))
)))
;; no dependencies
(defun org-id-open--support-search (fn link &optional arg)
"Support ::SEARCH syntax for id: links."
;; Save match data to prevent modifications by string matching functions.
(save-match-data
;; Split the link at the '::' delimiter.
(let* ((parts (split-string link "::")) ; Split the link into parts.
(id (car parts)) ; Extract the ID part.
(search (cadr parts))) ; Extract the search part.
;; Execute the original function and perform search operations.
;; Return the normal id for future compatibility
(prog1 (funcall fn id arg)
;; Conditionally execute additional actions based on the search part.
(cond ((null search)) ; Do nothing if search part is null.
((string-match-p "\\`[0-9]+\\'" search) ; If search part is a number.
(forward-line (string-to-number search))) ; Move N lines after the ID.
((string-match "^/\\([^/]+\\)/$" search) ; If search part is a regex match.
(let ((match (match-string 1 search))) ; Extract the match string.
(save-excursion (org-link-search search)) ; Search for the match.
(when (re-search-forward match) ; When match is found.
(goto-char (match-beginning 0))))) ; Move point to the match.
((org-link-search search))))))) ; Otherwise, perform org-link-search.
;; Add Advice around id open functions
(advice-add 'org-id-open :around #'org-id-open--support-search)
(advice-add 'org-roam-id-open :around #'org-id-open--support-search)
Update
- Fixed a typographic error which resulted in ::number not resolving properly