From 2d981adb5a83922ab8c71acea64a37e468f43495 Mon Sep 17 00:00:00 2001 From: Henrik Ahlgren Date: Thu, 20 Mar 2025 21:38:54 +0200 Subject: [PATCH] gptel-context: Improve context management of buffers * gptel-context.el (gptel-context-add-buffer): Introduce new function for adding a buffer (object or name). This is useful for incorporating buffers from Lisp code in addition to interactive usage. (gptel-add-buffer): Create an alias (similar to `gptel-add-file'). (gptel-context-add): Utilize the new function. Add support for adding/removing items in the Buffer List menu. (gptel-context-remove): Add functionality to remove (entire) buffers from context (used when removing from the Buffer List). --- gptel-context.el | 40 ++++++++++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/gptel-context.el b/gptel-context.el index bae1748c..31849df2 100644 --- a/gptel-context.el +++ b/gptel-context.el @@ -97,6 +97,9 @@ context chunk. This is accessible as, for example: CONFIRM is non-nil. With negative prefix ARG, remove all files from the context instead. +- If in Buffer List, add buffer at point to the context, or remove + if it already included in the context. + - Otherwise add the current buffer to the context. With positive prefix ARG, prompt for a buffer name and add it to the context. @@ -125,6 +128,12 @@ context chunk. This is accessible as, for example: (length dirs) (if (= (length dirs) 1) "y" "ies")))) (mapc action-fn files)))) + ;; If in Buffer List + ((eq major-mode 'Buffer-menu-mode) + (funcall (if (alist-get (tabulated-list-get-id) gptel-context--alist) + #'gptel-context-remove + #'gptel-context-add-buffer) + (tabulated-list-get-id))) ;; If in an image buffer ((and (derived-mode-p 'image-mode) (gptel--model-capable-p 'media) @@ -135,13 +144,7 @@ context chunk. This is accessible as, for example: (buffer-file-name))) ;; No region is selected, and ARG is positive. ((and arg (> (prefix-numeric-value arg) 0)) - (let* ((buffer-name (read-buffer "Choose buffer to add as context: " - (current-buffer) t)) - (start (with-current-buffer buffer-name (point-min))) - (end (with-current-buffer buffer-name (point-max)))) - (gptel-context--add-region - (get-buffer buffer-name) start end t) - (message "Buffer '%s' added as context." buffer-name))) + (call-interactively #'gptel-context-add-buffer (current-buffer))) ;; No region is selected, and ARG is negative. ((and arg (< (prefix-numeric-value arg) 0)) (when (or (null confirm) @@ -224,14 +227,29 @@ PATH should be readable as text." (gptel-context--add-binary-file path)) ((gptel-context--add-text-file path)))) -;;;###autoload (autoload 'gptel-add-file "gptel-context" "Add files to gptel's context." t) +;;;###autoload (autoload 'gptel-add-file "gptel-context" "Add a file to gptel's context." t) (defalias 'gptel-add-file #'gptel-context-add-file) +(defun gptel-context-add-buffer (buffer-or-name) + "Add BUFFER-OR-NAME to the gptel context." + (interactive "bChoose buffer to add as context: ") + (with-current-buffer buffer-or-name + (gptel-context--add-region + (get-buffer buffer-or-name) (point-min) (point-max) t)) + (message "Buffer \"%s\" added as context." + (if (bufferp buffer-or-name) + (buffer-name buffer-or-name) + buffer-or-name))) + +;;;###autoload (autoload 'gptel-add-buffer "gptel-context" "Add a buffer to gptel's context." t) +(defalias 'gptel-add-buffer #'gptel-context-add-buffer) + (defun gptel-context-remove (&optional context) "Remove the CONTEXT overlay from the contexts list. If CONTEXT is nil, removes the context at point. If selection is active, removes all contexts within selection. +if CONTEXT is a file or a buffer, removes from contexts. If CONTEXT is a directory, recursively removes all files in it." (cond ((overlayp context) @@ -247,6 +265,12 @@ If CONTEXT is a directory, recursively removes all files in it." (gptel-context--add-directory context 'remove) (setf (alist-get context gptel-context--alist nil 'remove #'equal) nil) (message "File \"%s\" removed from context." context))) + ((bufferp context) + (cl-loop + for cxt in (alist-get context gptel-context--alist) + do (delete-overlay cxt)) + (setf (alist-get context gptel-context--alist nil 'remove #'equal) nil) + (message "Buffer \"%s\" removed from context." (buffer-name context))) ((region-active-p) (when-let* ((contexts (gptel-context--in-region (current-buffer) (region-beginning)