diff --git a/gptel-transient.el b/gptel-transient.el index 8add342..e8d1f53 100644 --- a/gptel-transient.el +++ b/gptel-transient.el @@ -127,25 +127,25 @@ which see." ("i" "Replace/Delete prompt" "i") "Response to:" ("m" "Minibuffer instead" "m") - ("n" "New session" "n" + ("g" "gptel session" "g" :class transient-option - :prompt "Name for new session: " + :prompt "Existing or new gptel session: " :reader - (lambda (prompt _ history) - (read-string + (lambda (prompt _ _history) + (read-buffer prompt (generate-new-buffer-name (concat "*" (gptel-backend-name gptel-backend) "*")) - history))) - ("e" "Existing session" "e" + nil (lambda (buf-name) + (if (consp buf-name) (setq buf-name (car buf-name))) + (let ((buf (get-buffer buf-name))) + (and (buffer-local-value 'gptel-mode buf) + (not (eq (current-buffer) buf)))))))) + ("b" "Any buffer" "b" :class transient-option - :prompt "Existing session: " + :prompt "Output to buffer: " :reader - (lambda (prompt _ history) - (completing-read - prompt (mapcar #'buffer-name (buffer-list)) - (lambda (buf) (and (buffer-local-value 'gptel-mode (get-buffer buf)) - (not (equal (current-buffer) buf)))) - t nil history))) + (lambda (prompt _ _history) + (read-buffer prompt (buffer-name (other-buffer)) nil))) ("k" "Kill-ring" "k")] [:description gptel--refactor-or-rewrite :if use-region-p @@ -394,6 +394,7 @@ will get progressively longer!" (backend-name (gptel-backend-name gptel-backend)) (buffer) (position) (callback) (gptel-buffer-name) + ;; Input redirection: grab prompt from elsewhere? (prompt (cond ((member "p" args) @@ -409,6 +410,8 @@ will get progressively longer!" (if current-prefix-arg (read-from-kill-ring "Prompt from kill-ring: ") (current-kill 0)))))) + + ;; Output redirection: Send response elsewhere? (cond ((member "m" args) (setq stream nil) @@ -428,45 +431,13 @@ will get progressively longer!" backend-name (truncate-string-to-width resp 30)))))) ((setq gptel-buffer-name - (cl-some (lambda (s) (and (string-prefix-p "n" s) + (cl-some (lambda (s) (and (string-prefix-p "g" s) (substring s 1))) args)) - (setq buffer - (gptel gptel-buffer-name - (condition-case nil - (gptel--get-api-key) - ((error user-error) - (setq gptel-api-key - (read-passwd - (format "%s API key: " - (gptel-backend-name - gptel-backend)))))) - (or prompt - (if (use-region-p) - (buffer-substring-no-properties (region-beginning) - (region-end)) - (buffer-substring-no-properties - (save-excursion - (text-property-search-backward - 'gptel 'response - (when (get-char-property (max (point-min) (1- (point))) - 'gptel) - t)) - (point)) - (gptel--at-word-end (point))))))) - (with-current-buffer buffer - (setq gptel-backend backend) - (setq gptel-model model) - (gptel--update-status " Waiting..." 'warning) - (setq position (point))) - (setq output-to-other-buffer-p t)) - ((setq gptel-buffer-name - (cl-some (lambda (s) (and (string-prefix-p "e" s) - (substring s 1))) - args)) - (setq buffer (get-buffer gptel-buffer-name)) (setq output-to-other-buffer-p t) - (let ((reduced-prompt + (let ((reduced-prompt ;For inserting into the gptel buffer as + ;context, not the prompt used for the + ;request itself (or prompt (if (use-region-p) (buffer-substring-no-properties (region-beginning) @@ -480,18 +451,51 @@ will get progressively longer!" t)) (point)) (gptel--at-word-end (point))))))) - (with-current-buffer buffer - (goto-char (point-max)) - (if (or buffer-read-only - (get-char-property (point) 'read-only)) - (setq prompt reduced-prompt) - (insert reduced-prompt)) - (setq position (point)) - (when gptel-mode - (gptel--update-status " Waiting..." 'warning)))))) + (cond + ((buffer-live-p (get-buffer gptel-buffer-name)) + ;; Insert into existing gptel session + (progn + (setq buffer (get-buffer gptel-buffer-name)) + (with-current-buffer buffer + (goto-char (point-max)) + (unless (or buffer-read-only + (get-char-property (point) 'read-only)) + (insert reduced-prompt)) + (setq position (point)) + (when gptel-mode + (gptel--update-status " Waiting..." 'warning))))) + ;; Insert into new gptel session + (t (setq buffer + (gptel gptel-buffer-name + (condition-case nil + (gptel--get-api-key) + ((error user-error) + (setq gptel-api-key + (read-passwd + (format "%s API key: " + (gptel-backend-name + gptel-backend)))))) + reduced-prompt)) + ;; Set backend and model in new session from current buffer + (with-current-buffer buffer + (setq gptel-backend backend) + (setq gptel-model model) + (gptel--update-status " Waiting..." 'warning) + (setq position (point))))))) + ((setq gptel-buffer-name + (cl-some (lambda (s) (and (string-prefix-p "b" s) + (substring s 1))) + args)) + (setq output-to-other-buffer-p t) + (setq buffer (get-buffer-create gptel-buffer-name)) + (with-current-buffer buffer (setq position (point))))) + + ;; Create prompt, unless doing input-redirection above + (unless prompt + (setq prompt (gptel--create-prompt (gptel--at-word-end (point))))) (when in-place - (setq prompt (gptel--create-prompt (point))) + ;; Kill the latest prompt (let ((beg (if (use-region-p) (region-beginning) diff --git a/gptel.el b/gptel.el index 0d806d7..65151a9 100644 --- a/gptel.el +++ b/gptel.el @@ -755,8 +755,10 @@ RESPONSE is nil if there was no response or an error. The INFO plist has (at least) the following keys: :prompt - The full prompt that was sent with the request -:position - marker at the point the request was sent. -:buffer - The buffer current when the request was sent. +:position - marker at the point the request was sent, unless + POSITION is specified. +:buffer - The buffer current when the request was sent, + unless BUFFER is specified. :status - Short string describing the result of the request Example of a callback that messages the user with the response @@ -780,12 +782,15 @@ Or, for just the response: If CALLBACK is omitted, the response is inserted at the point the request was sent. -BUFFER is the buffer the request belongs to. If omitted the -current buffer is recorded. +BUFFER and POSITION are the buffer and position (integer or +marker) at which the response is inserted. If a CALLBACK is +specified, no response is inserted and these arguments are +ignored, but they are still available in the INFO plist passed +to CALLBACK for you to use. -POSITION is a buffer position (integer or marker). If omitted, -the value of (point) or (region-end) is recorded, depending on -whether the region is active. +BUFFER defaults to the current buffer, and POSITION to the value +of (point) or (region-end), depending on whether the region is +active. CONTEXT is any additional data needed for the callback to run. It is included in the INFO argument to the callback.