Skip to content

Commit cc3d74d

Browse files
committed
gptel-org: Obey gptel-org settings when sending regions
* gptel.el (gptel--create-prompt): Change how prompts are created from active regions in Org mode. Previously the text in the region was parsed verbatim without any pre-processing irrespective of major-mode. Now active regions in Org mode are subjected to gptel-org-related settings such as `gptel-org-branching-context' and `gptel-org-ignore-elements', as well as `gptel-prompt-filter-hook'. The hope is that this approach is more intuitive and in line with the user's expectations. * gptel-org.el (gptel-org--create-prompt): Rewrite how branching context is handled. Previously the lineage calculation included an 'org-data element at point 1. Now the lineage calculation only returns headline start positions, and we tack on (point-min) to the list explicitly, avoiding a couple of edge cases. The headline start positions returned by the lineage calculation are now adjusted correctly for narrowed buffers and active-regions. * test: Update tests for new prompt-from-region rules
1 parent 8a289e9 commit cc3d74d

File tree

3 files changed

+31
-30
lines changed

3 files changed

+31
-30
lines changed

gptel-org.el

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,8 @@
2323
;;
2424

2525
;;; Code:
26-
(eval-when-compile
27-
(require 'cl-lib)
28-
(require 'gptel))
26+
(eval-when-compile (require 'gptel))
27+
(require 'cl-lib)
2928
(require 'org-element)
3029
(require 'outline)
3130

@@ -202,7 +201,11 @@ recent exchanges.
202201
The prompt is constructed from the contents of the buffer up to
203202
point, or PROMPT-END if provided. Its contents depend on the
204203
value of `gptel-org-branching-context', which see."
205-
(unless prompt-end (setq prompt-end (point)))
204+
(when (use-region-p)
205+
(narrow-to-region (region-beginning) (region-end)))
206+
(if prompt-end
207+
(goto-char prompt-end)
208+
(setq prompt-end (point)))
206209
(let ((max-entries (and gptel--num-messages-to-send
207210
(* 2 gptel--num-messages-to-send)))
208211
(topic-start (gptel-org--get-topic-start)))
@@ -218,30 +221,28 @@ value of `gptel-org-branching-context', which see."
218221
;; Create prompt from direct ancestors of point
219222
(save-excursion
220223
(let* ((org-buf (current-buffer))
221-
(start-bounds (gptel-org--element-lineage-map
222-
(org-element-at-point) #'gptel-org--element-begin
223-
'(headline org-data) 'with-self))
224+
;; Collect all heading start positions in the lineage
225+
(full-bounds (gptel-org--element-lineage-map
226+
(org-element-at-point) #'gptel-org--element-begin
227+
'(headline) 'with-self) )
228+
;; lineage-map returns the full lineage in the unnarrowed
229+
;; buffer. Remove heading start positions at or before
230+
;; (point-min) that are invalid due to narrowing, and add
231+
;; (point-min) explicitly
232+
(start-bounds (nconc (cl-delete-if (lambda (p) (<= p (point-min)))
233+
full-bounds)
234+
(list (point-min))))
224235
(end-bounds
225236
(cl-loop
226-
for (pos . rest) on (cdr start-bounds)
227-
while
228-
(and (>= pos (point-min)) ;respect narrowing
229-
(goto-char pos)
230-
;; org-element-lineage always returns an extra
231-
;; (org-data) element at point 1. If there is also a
232-
;; heading here, it is either a false positive or we
233-
;; would be double counting it. So we reject this node
234-
;; when also at a heading.
235-
(not (and (eq pos 1) (org-at-heading-p)
236-
;; Skip if at the last element of start-bounds,
237-
;; since we captured this heading already (#476)
238-
(null rest))))
239-
do (outline-next-heading)
237+
;; (car start-bounds) is the begining of the current element,
238+
;; not relevant
239+
for pos in (cdr start-bounds)
240+
do (goto-char pos) (outline-next-heading)
240241
collect (point) into ends
241242
finally return (cons prompt-end ends))))
242243
(gptel--with-buffer-copy org-buf nil nil
243244
(cl-loop for start in start-bounds
244-
for end in end-bounds
245+
for end in end-bounds
245246
do (insert-buffer-substring org-buf start end)
246247
(goto-char (point-min)))
247248
(goto-char (point-max))

gptel.el

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2589,25 +2589,25 @@ If `gptel-context--alist' is non-nil and the additional
25892589
context needs to be included with the user prompt, add it.
25902590
25912591
If PROMPT-END (a marker) is provided, end the prompt contents
2592-
there."
2592+
there. This defaults to (point)."
25932593
(save-excursion
25942594
(save-restriction
25952595
(let* ((max-entries (and gptel--num-messages-to-send
25962596
(* 2 gptel--num-messages-to-send)))
2597-
(prompt-end (or prompt-end (point-max)))
25982597
(buf (current-buffer))
25992598
(prompts
26002599
(cond
2600+
((derived-mode-p 'org-mode)
2601+
(require 'gptel-org)
2602+
;; Also handles regions in Org mode
2603+
(gptel-org--create-prompt prompt-end))
26012604
((use-region-p)
26022605
(let ((rb (region-beginning)) (re (region-end)))
26032606
(gptel--with-buffer-copy buf rb re
26042607
(save-excursion (run-hooks 'gptel-prompt-filter-hook))
26052608
(gptel--parse-buffer gptel-backend max-entries))))
2606-
((derived-mode-p 'org-mode)
2607-
(require 'gptel-org)
2608-
(goto-char prompt-end)
2609-
(gptel-org--create-prompt prompt-end))
2610-
(t (gptel--with-buffer-copy buf (point-min) prompt-end
2609+
(t (unless prompt-end (setq prompt-end (point)))
2610+
(gptel--with-buffer-copy buf (point-min) prompt-end
26112611
(save-excursion (run-hooks 'gptel-prompt-filter-hook))
26122612
(gptel--parse-buffer gptel-backend max-entries))))))
26132613
;; NOTE: prompts is modified in place here

test

0 commit comments

Comments
 (0)