branch: elpa/gptel commit cc3d74de856297169de868488136923d118d77ec Author: Karthik Chikmagalur <karthikchikmaga...@gmail.com> Commit: Karthik Chikmagalur <karthikchikmaga...@gmail.com>
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 --- gptel-org.el | 45 +++++++++++++++++++++++---------------------- gptel.el | 14 +++++++------- test | 2 +- 3 files changed, 31 insertions(+), 30 deletions(-) diff --git a/gptel-org.el b/gptel-org.el index 0745463993..e3de310073 100644 --- a/gptel-org.el +++ b/gptel-org.el @@ -23,9 +23,8 @@ ;; ;;; Code: -(eval-when-compile - (require 'cl-lib) - (require 'gptel)) +(eval-when-compile (require 'gptel)) +(require 'cl-lib) (require 'org-element) (require 'outline) @@ -202,7 +201,11 @@ recent exchanges. The prompt is constructed from the contents of the buffer up to point, or PROMPT-END if provided. Its contents depend on the value of `gptel-org-branching-context', which see." - (unless prompt-end (setq prompt-end (point))) + (when (use-region-p) + (narrow-to-region (region-beginning) (region-end))) + (if prompt-end + (goto-char prompt-end) + (setq prompt-end (point))) (let ((max-entries (and gptel--num-messages-to-send (* 2 gptel--num-messages-to-send))) (topic-start (gptel-org--get-topic-start))) @@ -218,30 +221,28 @@ value of `gptel-org-branching-context', which see." ;; Create prompt from direct ancestors of point (save-excursion (let* ((org-buf (current-buffer)) - (start-bounds (gptel-org--element-lineage-map - (org-element-at-point) #'gptel-org--element-begin - '(headline org-data) 'with-self)) + ;; Collect all heading start positions in the lineage + (full-bounds (gptel-org--element-lineage-map + (org-element-at-point) #'gptel-org--element-begin + '(headline) 'with-self) ) + ;; lineage-map returns the full lineage in the unnarrowed + ;; buffer. Remove heading start positions at or before + ;; (point-min) that are invalid due to narrowing, and add + ;; (point-min) explicitly + (start-bounds (nconc (cl-delete-if (lambda (p) (<= p (point-min))) + full-bounds) + (list (point-min)))) (end-bounds (cl-loop - for (pos . rest) on (cdr start-bounds) - while - (and (>= pos (point-min)) ;respect narrowing - (goto-char pos) - ;; org-element-lineage always returns an extra - ;; (org-data) element at point 1. If there is also a - ;; heading here, it is either a false positive or we - ;; would be double counting it. So we reject this node - ;; when also at a heading. - (not (and (eq pos 1) (org-at-heading-p) - ;; Skip if at the last element of start-bounds, - ;; since we captured this heading already (#476) - (null rest)))) - do (outline-next-heading) + ;; (car start-bounds) is the begining of the current element, + ;; not relevant + for pos in (cdr start-bounds) + do (goto-char pos) (outline-next-heading) collect (point) into ends finally return (cons prompt-end ends)))) (gptel--with-buffer-copy org-buf nil nil (cl-loop for start in start-bounds - for end in end-bounds + for end in end-bounds do (insert-buffer-substring org-buf start end) (goto-char (point-min))) (goto-char (point-max)) diff --git a/gptel.el b/gptel.el index 98c72bcbb9..a8c19d6ef5 100644 --- a/gptel.el +++ b/gptel.el @@ -2589,25 +2589,25 @@ If `gptel-context--alist' is non-nil and the additional context needs to be included with the user prompt, add it. If PROMPT-END (a marker) is provided, end the prompt contents -there." +there. This defaults to (point)." (save-excursion (save-restriction (let* ((max-entries (and gptel--num-messages-to-send (* 2 gptel--num-messages-to-send))) - (prompt-end (or prompt-end (point-max))) (buf (current-buffer)) (prompts (cond + ((derived-mode-p 'org-mode) + (require 'gptel-org) + ;; Also handles regions in Org mode + (gptel-org--create-prompt prompt-end)) ((use-region-p) (let ((rb (region-beginning)) (re (region-end))) (gptel--with-buffer-copy buf rb re (save-excursion (run-hooks 'gptel-prompt-filter-hook)) (gptel--parse-buffer gptel-backend max-entries)))) - ((derived-mode-p 'org-mode) - (require 'gptel-org) - (goto-char prompt-end) - (gptel-org--create-prompt prompt-end)) - (t (gptel--with-buffer-copy buf (point-min) prompt-end + (t (unless prompt-end (setq prompt-end (point))) + (gptel--with-buffer-copy buf (point-min) prompt-end (save-excursion (run-hooks 'gptel-prompt-filter-hook)) (gptel--parse-buffer gptel-backend max-entries)))))) ;; NOTE: prompts is modified in place here diff --git a/test b/test index 13887f8d01..77947a55f9 160000 --- a/test +++ b/test @@ -1 +1 @@ -Subproject commit 13887f8d018bd1f3ff6158693975f7eaeec19522 +Subproject commit 77947a55f95db24f240bd896cb3d04d72fe6ed00