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

Reply via email to