Skip to content

Commit 82253f0

Browse files
committed
Add: (org-ql-find) Snippet functions
The default is even more like org-rifle now.
1 parent ede1a6b commit 82253f0

File tree

1 file changed

+65
-10
lines changed

1 file changed

+65
-10
lines changed

org-ql-find.el

+65-10
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,28 @@
4545
"Functions called when selecting an entry."
4646
:type 'hook)
4747

48+
(defcustom org-ql-find-snippet-length 51
49+
"Size of snippets of entry content to include in `org-ql-find' annotations.
50+
Only used when `org-ql-find-snippet-function' is set to
51+
`org-ql-find--snippet-regexp'."
52+
:type 'integer)
53+
54+
(defcustom org-ql-find-snippet-function #'org-ql-find--snippet-regexp
55+
"Function used to annotate results in `org-ql-find'.
56+
Function is called at entry beginning. (When set to
57+
`org-ql-find--snippet-regexp', it is called with a regexp
58+
matching plain query tokens.)"
59+
:type '(choice (function-item :tag "Show context around search terms" org-ql-find--snippet-regexp)
60+
(function-item :tag "Show first N characters" org-ql-find--snippet-simple)
61+
(function :tag "Custom function")))
62+
63+
(defcustom org-ql-find-snippet-prefix nil
64+
"String prepended to snippets.
65+
For an experience like `org-rifle', use a newline."
66+
:type '(choice (const :tag "None (shown on same line)" nil)
67+
(const :tag "New line (shown under heading)" "\n")
68+
string))
69+
4870
(defface org-ql-find-snippet '((t (:inherit font-lock-comment-face)))
4971
"Snippets.")
5072

@@ -81,7 +103,8 @@ single predicate)."
81103
;; made possible by the example Clemens Radermacher shared at
82104
;; <https://github.com/radian-software/selectrum/issues/114#issuecomment-744041532>.
83105
(let ((table (make-hash-table :test #'equal))
84-
(window-width (window-width)))
106+
(window-width (window-width))
107+
query-tokens snippet-regexp)
85108
(cl-labels ((action
86109
() (font-lock-ensure (point-at-bol) (point-at-eol))
87110
(let* ((path (thread-first (org-get-outline-path t t)
@@ -106,17 +129,15 @@ single predicate)."
106129
"")
107130
collect (list completion todo-state snippet)))
108131
(annotate (candidate)
109-
(or (snippet (gethash candidate table)) ""))
132+
(while-no-input
133+
;; Using `while-no-input' here doesn't make it as
134+
;; responsive as, e.g. Helm while typing, but it seems to
135+
;; help a little when using the org-rifle-style snippets.
136+
(or (snippet (gethash candidate table)) "")))
110137
(snippet (marker)
111138
(org-with-point-at marker
112-
(org-end-of-meta-data t)
113-
(unless (org-at-heading-p)
114-
(let ((end (min (+ (point) 51)
115-
(org-entry-end-position))))
116-
(truncate-string-to-width
117-
(replace-regexp-in-string "\n" " " (buffer-substring (point) end)
118-
t t)
119-
50 nil nil t)))))
139+
(or (funcall org-ql-find-snippet-function snippet-regexp)
140+
(org-ql-find--snippet-simple))))
120141
(group (candidate transform)
121142
(pcase transform
122143
(`nil (buffer-name (marker-buffer (gethash candidate table))))
@@ -134,6 +155,15 @@ single predicate)."
134155
(`t (unless (string-empty-p str)
135156
(when query-filter
136157
(setf str (funcall query-filter str)))
158+
(pcase org-ql-find-snippet-function
159+
('org-ql-find--snippet-regexp
160+
(setf query-tokens
161+
;; Remove any tokens that specify predicates.
162+
(--select (not (string-match-p (rx bos (1+ (not (any ":"))) ":") it))
163+
(split-string str nil t (rx space)))
164+
snippet-regexp (rx-to-string `(seq (optional (repeat 1 3 (1+ (not space)) (0+ space)))
165+
bow (or ,@query-tokens) (0+ (not space))
166+
(optional (repeat 1 3 (0+ space) (1+ (not space)))))))))
137167
(org-ql-select buffers-files (org-ql--query-string-to-sexp (concat query-prefix str))
138168
:action #'action))))))
139169
(let* ((completion-styles '(org-ql-find))
@@ -181,6 +211,31 @@ multiple buffers to search with completion."
181211
(current-buffer))))
182212
(org-ql-find buffers-files :prompt "Find outline path: " :query-prefix "outline-path:"))
183213

214+
(defun org-ql-find--snippet-simple (&optional _regexp)
215+
"Return a snippet of the current entry.
216+
Returns up to `org-ql-find-snippet-length' characters."
217+
(org-end-of-meta-data t)
218+
(unless (org-at-heading-p)
219+
(let ((end (min (+ (point) org-ql-find-snippet-length)
220+
(org-entry-end-position))))
221+
(concat org-ql-find-snippet-prefix
222+
(truncate-string-to-width
223+
(replace-regexp-in-string "\n" " " (buffer-substring (point) end)
224+
t t)
225+
50 nil nil t)))))
226+
227+
(defun org-ql-find--snippet-regexp (regexp)
228+
"Return a snippet of the current entry's matches for REGEXP."
229+
(org-end-of-meta-data t)
230+
(unless (org-at-heading-p)
231+
(let* ((end (org-entry-end-position))
232+
(snippets (cl-loop while (re-search-forward regexp end t)
233+
concat (match-string 0) concat ""
234+
do (goto-char (match-end 0)))))
235+
(unless (string-empty-p snippets)
236+
(concat org-ql-find-snippet-prefix
237+
(replace-regexp-in-string (rx (1+ "\n")) " " snippets t t))))))
238+
184239
(provide 'org-ql-find)
185240

186241
;;; org-ql-find.el ends here

0 commit comments

Comments
 (0)