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