mirror of
https://github.com/chrisbarrett/nursery
synced 2025-08-23 14:03:33 -05:00
Add org-roam-consult
This commit is contained in:
@@ -26,6 +26,10 @@ UI. Contrasts with the normal org-roam buffer, which only shows backlinks.
|
|||||||
Search your org-roam files for a string and display a buffer of results. Results
|
Search your org-roam files for a string and display a buffer of results. Results
|
||||||
are shown with collapsible previews, like in the org-roam buffer.
|
are shown with collapsible previews, like in the org-roam buffer.
|
||||||
|
|
||||||
|
** INCUBATING [[file:lisp/org-roam-consult.el][org-roam-consult]]
|
||||||
|
A version of =consult-ripgrep= that shows node titles instead of filenames so you
|
||||||
|
don't have to guess anymore.
|
||||||
|
|
||||||
** SPIKE [[file:lisp/org-roam-gc.el][org-roam-gc]]
|
** SPIKE [[file:lisp/org-roam-gc.el][org-roam-gc]]
|
||||||
Automatically delete empty dailies files so they don't build up forever.
|
Automatically delete empty dailies files so they don't build up forever.
|
||||||
|
|
||||||
|
163
lisp/org-roam-consult.el
Normal file
163
lisp/org-roam-consult.el
Normal file
@@ -0,0 +1,163 @@
|
|||||||
|
;;; org-roam-consult.el --- Search org-roam nodes with consult -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
|
;; Copyright (C) 2022 Chris Barrett
|
||||||
|
|
||||||
|
;; Author: Chris Barrett <chris@walrus.cool>
|
||||||
|
|
||||||
|
;; This program is free software; you can redistribute it and/or modify
|
||||||
|
;; it under the terms of the GNU General Public License as published by
|
||||||
|
;; the Free Software Foundation, either version 3 of the License, or
|
||||||
|
;; (at your option) any later version.
|
||||||
|
|
||||||
|
;; This program is distributed in the hope that it will be useful,
|
||||||
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
;; GNU General Public License for more details.
|
||||||
|
|
||||||
|
;; You should have received a copy of the GNU General Public License
|
||||||
|
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
;;; Commentary:
|
||||||
|
|
||||||
|
;; This package exposes a command, `org-roam-consult', which is a version
|
||||||
|
;; of`consult-ripgrep' that shows the titles of org files rather than their
|
||||||
|
;; filepath. This is desirable when searching org-roam files, since filenames
|
||||||
|
;; may not correspond to a note's title.
|
||||||
|
|
||||||
|
;; Example configuration:
|
||||||
|
;;
|
||||||
|
;; (use-package org-roam-consult
|
||||||
|
;; :commands (org-roam-consult))
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(require 'consult)
|
||||||
|
(require 'org)
|
||||||
|
(require 'org-roam)
|
||||||
|
(require 'memoize)
|
||||||
|
(require 'pcre2el)
|
||||||
|
|
||||||
|
(defgroup org-roam-consult nil
|
||||||
|
"Search org-roam nodes with consult."
|
||||||
|
:group 'productivity
|
||||||
|
:prefix "org-roam-consult-")
|
||||||
|
|
||||||
|
|
||||||
|
(defface org-roam-consult-highlight
|
||||||
|
`((t (:inherit highlight)))
|
||||||
|
"Face for hits for a search term."
|
||||||
|
:group 'org-roam-consult)
|
||||||
|
|
||||||
|
(defvar org-roam-consult-title-search-byte-limit 1024
|
||||||
|
"The max number of bytes to look at when trying to find a roam node's title.")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(defun org-roam-consult--replace-links-in-string (str)
|
||||||
|
(save-match-data
|
||||||
|
(with-temp-buffer
|
||||||
|
(insert str)
|
||||||
|
(goto-char (point-min))
|
||||||
|
|
||||||
|
;; Replace links with their descriptions.
|
||||||
|
(save-excursion
|
||||||
|
(while (search-forward-regexp org-link-bracket-re nil t)
|
||||||
|
(replace-match (match-string 2))))
|
||||||
|
|
||||||
|
;; Best-effort processing for remaining line-wrapped links
|
||||||
|
(save-excursion
|
||||||
|
(while (search-forward-regexp (rx "[[" (+? nonl) "][" (group (+? nonl)) (? "]")) nil t)
|
||||||
|
(replace-match (match-string 1))))
|
||||||
|
|
||||||
|
(buffer-substring (point-min) (point-max)))))
|
||||||
|
|
||||||
|
(defun org-roam-consult--candidate-group (cand transform)
|
||||||
|
"Return title for CAND or TRANSFORM the candidate."
|
||||||
|
(let* ((line (substring cand (1+ (length (get-text-property 0 'consult--grep-file cand)))))
|
||||||
|
(filename (get-text-property 0 'consult--grep-file cand)))
|
||||||
|
(if transform
|
||||||
|
(org-roam-consult--replace-links-in-string line)
|
||||||
|
(org-roam-consult--format-group-title filename))))
|
||||||
|
|
||||||
|
(defun org-roam-consult--lookup-title (file)
|
||||||
|
(with-temp-buffer
|
||||||
|
(insert-file-contents (expand-file-name file org-roam-directory) nil nil org-roam-consult-title-search-byte-limit)
|
||||||
|
(goto-char (point-min))
|
||||||
|
(if (search-forward-regexp (rx bol "#+title:" (* space) (group (+ any)) eol))
|
||||||
|
(match-string 1)
|
||||||
|
file)))
|
||||||
|
|
||||||
|
(defun org-roam-consult--format-group-title (file)
|
||||||
|
(let ((title (org-roam-consult--lookup-title file))
|
||||||
|
(dir (-some->> (file-name-directory file) (string-remove-prefix "/") (string-remove-suffix "/"))))
|
||||||
|
(if (or (null dir) (string-blank-p dir))
|
||||||
|
title
|
||||||
|
(format "%s > %s" dir title))))
|
||||||
|
|
||||||
|
(ignore-errors
|
||||||
|
(memoize 'org-roam-consult--format-group-title 60))
|
||||||
|
|
||||||
|
;; HACK: brutal copy-pasta to tweak two expressions in `consult--grep-format' to
|
||||||
|
;; make outputs more readable.
|
||||||
|
(defun org-roam-consult--format-results (async builder)
|
||||||
|
"Return ASYNC function highlighting grep match results.
|
||||||
|
BUILDER is the command argument builder."
|
||||||
|
(let ((highlight))
|
||||||
|
(lambda (action)
|
||||||
|
(cond
|
||||||
|
((stringp action)
|
||||||
|
(setq highlight (plist-get (funcall builder action) :highlight))
|
||||||
|
(funcall async action))
|
||||||
|
((consp action)
|
||||||
|
(let (result)
|
||||||
|
(save-match-data
|
||||||
|
(dolist (str action)
|
||||||
|
(when (and (string-match consult--grep-match-regexp str)
|
||||||
|
;; Filter out empty context lines
|
||||||
|
(or (/= (aref str (match-beginning 3)) ?-)
|
||||||
|
(/= (match-end 0) (length str))))
|
||||||
|
(let* ((file (match-string 1 str))
|
||||||
|
(line (format "%4s" (match-string 2 str)))
|
||||||
|
(ctx (= (aref str (match-beginning 3)) ?-))
|
||||||
|
(sep (if ctx "-" " "))
|
||||||
|
(content (substring str (match-end 0)))
|
||||||
|
(file-len (length file))
|
||||||
|
(line-len (length line)))
|
||||||
|
(when (> (length content) consult-grep-max-columns)
|
||||||
|
(setq content (substring content 0 consult-grep-max-columns)))
|
||||||
|
(when highlight
|
||||||
|
(funcall highlight content))
|
||||||
|
(setq str (concat file sep line sep content))
|
||||||
|
;; Store file name in order to avoid allocations in `consult--grep-group'
|
||||||
|
(add-text-properties 0 file-len `(face consult-file consult--grep-file ,file) str)
|
||||||
|
(put-text-property (1+ file-len) (+ 1 file-len line-len) 'face 'consult-line-number str)
|
||||||
|
(when ctx
|
||||||
|
(add-face-text-property (+ 2 file-len line-len) (length str) 'consult-grep-context 'append str))
|
||||||
|
(push str result)))))
|
||||||
|
(funcall async (nreverse result))))
|
||||||
|
(t (funcall async action))))))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun org-roam-consult (&optional initial)
|
||||||
|
"Search for regexp with rg in `org-roam-directory' with INITIAL input."
|
||||||
|
(interactive)
|
||||||
|
(let* ((default-directory org-roam-directory)
|
||||||
|
(read-process-output-max (max read-process-output-max (* 1024 1024))))
|
||||||
|
(consult--read
|
||||||
|
(consult--async-command #'consult--ripgrep-builder
|
||||||
|
(org-roam-consult--format-results #'consult--ripgrep-builder)
|
||||||
|
:file-handler t)
|
||||||
|
:prompt "Search Roam: "
|
||||||
|
:lookup #'consult--lookup-member
|
||||||
|
:state (consult--grep-state)
|
||||||
|
:initial (consult--async-split-initial initial)
|
||||||
|
:add-history (consult--async-split-thingatpt 'symbol)
|
||||||
|
:require-match t
|
||||||
|
:category 'consult-grep
|
||||||
|
:group #'org-roam-consult--candidate-group
|
||||||
|
:history '(:input consult--grep-history)
|
||||||
|
:sort nil)))
|
||||||
|
|
||||||
|
(provide 'org-roam-consult)
|
||||||
|
|
||||||
|
;;; org-roam-consult.el ends here
|
Reference in New Issue
Block a user