gptel-transient: New gptel-menu transient options
* gptel-transient.el (gptel-menu, gptel--suffix-send, gptel--suffix-send-existing, gptel--suffix-send-new): Rewrite `gptel-menu' to allow for selecting prompt sources and response sinks independently. Sensible combinations of the following are now possible: - prompt from minibuffer - Replace prompt with response - Response to echo area - Response to new gptel session - Response to existing gptel session - Response to kill-ring The transient suffixes `gptel--suffix-send-existing' and `gptel--suffix-send-new' are now obsolete and have been removed.
This commit is contained in:
parent
23332a9bc5
commit
c11e53061c
1 changed files with 144 additions and 46 deletions
|
@ -52,23 +52,44 @@ Or is it the other way around?"
|
||||||
|
|
||||||
(define-obsolete-function-alias 'gptel-send-menu 'gptel-menu "0.3.2")
|
(define-obsolete-function-alias 'gptel-send-menu 'gptel-menu "0.3.2")
|
||||||
|
|
||||||
|
;; BUG: The `:incompatible' spec doesn't work if there's a `:description' below it.
|
||||||
;;;###autoload (autoload 'gptel-menu "gptel-transient" nil t)
|
;;;###autoload (autoload 'gptel-menu "gptel-transient" nil t)
|
||||||
(transient-define-prefix gptel-menu ()
|
(transient-define-prefix gptel-menu ()
|
||||||
"Change parameters of prompt to send ChatGPT."
|
"Change parameters of prompt to send ChatGPT."
|
||||||
[:description
|
;; :incompatible '(("-m" "-n" "-k" "-e"))
|
||||||
(lambda () (format "Directive: %s"
|
[:description
|
||||||
(truncate-string-to-width
|
(lambda () (format "Directive: %s"
|
||||||
gptel--system-message (max (- (window-width) 14) 20) nil nil t)))
|
(truncate-string-to-width
|
||||||
("h" "Set directives for chat" gptel-system-prompt)]
|
gptel--system-message (max (- (window-width) 14) 20) nil nil t)))
|
||||||
[["Session Parameters"
|
("h" "Set directives for chat" gptel-system-prompt)]
|
||||||
(gptel--infix-max-tokens)
|
[["Session Parameters"
|
||||||
(gptel--infix-num-messages-to-send)
|
(gptel--infix-max-tokens)
|
||||||
(gptel--infix-temperature)
|
(gptel--infix-num-messages-to-send)
|
||||||
(gptel--infix-model)]
|
(gptel--infix-temperature)
|
||||||
["Send"
|
(gptel--infix-model)]
|
||||||
(gptel--suffix-send-existing)
|
["Prompt:"
|
||||||
(gptel--suffix-send-new)
|
("-r" "From minibuffer instead" "-r")
|
||||||
("RET" "Send prompt" gptel-send)]])
|
("-i" "Overwrite/Delete prompt" "-i")
|
||||||
|
"Response to:"
|
||||||
|
("-m" "Minibuffer instead" "-m")
|
||||||
|
("-n" "New session" "-n"
|
||||||
|
:class transient-option
|
||||||
|
:prompt "Name for new session: "
|
||||||
|
:reader
|
||||||
|
(lambda (prompt _ history)
|
||||||
|
(read-string
|
||||||
|
prompt (generate-new-buffer-name "*ChatGPT*") history)))
|
||||||
|
("-e" "Existing session" "-e"
|
||||||
|
:class transient-option
|
||||||
|
:prompt "Existing session: "
|
||||||
|
: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)))
|
||||||
|
("-k" "Kill-ring" "-k")]
|
||||||
[:description gptel--refactor-or-rewrite
|
[:description gptel--refactor-or-rewrite
|
||||||
:if use-region-p
|
:if use-region-p
|
||||||
("r"
|
("r"
|
||||||
|
@ -80,7 +101,6 @@ Or is it the other way around?"
|
||||||
gptel-rewrite-menu)]
|
gptel-rewrite-menu)]
|
||||||
["Send" (gptel--suffix-send)]])
|
["Send" (gptel--suffix-send)]])
|
||||||
|
|
||||||
;; ** Prefix for setting the system prompt.
|
|
||||||
|
|
||||||
;; ** Prefix for setting the system prompt.
|
;; ** Prefix for setting the system prompt.
|
||||||
|
|
||||||
|
@ -228,36 +248,6 @@ will get progressively longer!"
|
||||||
(read-from-minibuffer "Set temperature (0.0-2.0, leave empty for default): "
|
(read-from-minibuffer "Set temperature (0.0-2.0, leave empty for default): "
|
||||||
(number-to-string gptel-temperature))))
|
(number-to-string gptel-temperature))))
|
||||||
|
|
||||||
(transient-define-suffix gptel--suffix-send-existing ()
|
|
||||||
"Send query in existing chat session."
|
|
||||||
:if #'use-region-p
|
|
||||||
:key "E"
|
|
||||||
:description "Send in existing session"
|
|
||||||
(interactive)
|
|
||||||
(when-let* ((this (buffer-name))
|
|
||||||
(prompt (buffer-substring (region-beginning)
|
|
||||||
(region-end)))
|
|
||||||
(buf
|
|
||||||
(completing-read
|
|
||||||
"Send query in buffer: " (mapcar #'buffer-name (buffer-list))
|
|
||||||
(lambda (buf) (and (buffer-local-value 'gptel-mode (get-buffer buf))
|
|
||||||
(not (equal this buf)))))))
|
|
||||||
(with-current-buffer buf
|
|
||||||
(goto-char (point-max))
|
|
||||||
(insert prompt)
|
|
||||||
(gptel-send))
|
|
||||||
(pop-to-buffer buf)))
|
|
||||||
|
|
||||||
(transient-define-suffix gptel--suffix-send-new ()
|
|
||||||
"Send query in new session."
|
|
||||||
:if #'use-region-p
|
|
||||||
:description "Send in new session"
|
|
||||||
:key "N"
|
|
||||||
(interactive)
|
|
||||||
(let* ((current-prefix-arg t)
|
|
||||||
(buf (call-interactively #'gptel)))
|
|
||||||
(and (bufferp buf)
|
|
||||||
(with-current-buffer buf (gptel-send)))))
|
|
||||||
;; ** Infix for the refactor/rewrite system message
|
;; ** Infix for the refactor/rewrite system message
|
||||||
|
|
||||||
(transient-define-infix gptel--infix-rewrite-prompt ()
|
(transient-define-infix gptel--infix-rewrite-prompt ()
|
||||||
|
@ -277,6 +267,114 @@ will get progressively longer!"
|
||||||
;; * Transient Suffixes
|
;; * Transient Suffixes
|
||||||
|
|
||||||
;; ** Suffix to send prompt
|
;; ** Suffix to send prompt
|
||||||
|
|
||||||
|
(transient-define-suffix gptel--suffix-send (args)
|
||||||
|
"Send ARGS."
|
||||||
|
:key "RET"
|
||||||
|
:description "Send prompt"
|
||||||
|
(interactive (list (transient-args transient-current-command)))
|
||||||
|
(let ((stream gptel-stream)
|
||||||
|
(in-place (and (member "-i" args) t))
|
||||||
|
(output-to-other-buffer-p)
|
||||||
|
(buffer) (position)
|
||||||
|
(callback) (buffer-name)
|
||||||
|
(prompt
|
||||||
|
(and (member "-r" args)
|
||||||
|
(read-string
|
||||||
|
"Ask ChatGPT: "
|
||||||
|
(apply #'buffer-substring-no-properties
|
||||||
|
(if (use-region-p)
|
||||||
|
(list (region-beginning) (region-end))
|
||||||
|
(list (line-beginning-position) (line-end-position))))))))
|
||||||
|
(cond
|
||||||
|
((member "-m" args)
|
||||||
|
(setq stream nil)
|
||||||
|
(setq callback
|
||||||
|
(lambda (resp info)
|
||||||
|
(if resp
|
||||||
|
(message "ChatGPT response: %s" resp)
|
||||||
|
(message "ChatGPT response error: %s" (plist-get info :status))))))
|
||||||
|
((member "-k" args)
|
||||||
|
(setq stream nil)
|
||||||
|
(setq callback
|
||||||
|
(lambda (resp info)
|
||||||
|
(if (not resp)
|
||||||
|
(message "ChatGPT response error: %s" (plist-get info :status))
|
||||||
|
(kill-new resp)
|
||||||
|
(message "ChatGPT response: copied to kill-ring.")))))
|
||||||
|
((setq buffer-name
|
||||||
|
(cl-some (lambda (s) (and (string-prefix-p "-n" s)
|
||||||
|
(substring s 2)))
|
||||||
|
args))
|
||||||
|
(setq buffer
|
||||||
|
(gptel buffer-name
|
||||||
|
(condition-case nil
|
||||||
|
(gptel--api-key)
|
||||||
|
((error user-error)
|
||||||
|
(setq gptel-api-key
|
||||||
|
(read-passwd "OpenAI API key: "))))
|
||||||
|
(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))
|
||||||
|
(point))))))
|
||||||
|
(setq position (with-current-buffer buffer (point)))
|
||||||
|
(setq output-to-other-buffer-p t))
|
||||||
|
((setq buffer-name
|
||||||
|
(cl-some (lambda (s) (and (string-prefix-p "-e" s)
|
||||||
|
(substring s 2)))
|
||||||
|
args))
|
||||||
|
(setq buffer (get-buffer buffer-name))
|
||||||
|
(setq output-to-other-buffer-p t)
|
||||||
|
(let ((reduced-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))
|
||||||
|
(point)))))
|
||||||
|
(with-current-buffer buffer
|
||||||
|
(goto-char (point-max))
|
||||||
|
(insert reduced-prompt)
|
||||||
|
(setq position (point))))))
|
||||||
|
|
||||||
|
(when in-place
|
||||||
|
(setq prompt (gptel--create-prompt (point)))
|
||||||
|
(let ((beg
|
||||||
|
(if (use-region-p)
|
||||||
|
(region-beginning)
|
||||||
|
(save-excursion
|
||||||
|
(text-property-search-backward
|
||||||
|
'gptel 'response
|
||||||
|
(when (get-char-property (max (point-min) (1- (point)))
|
||||||
|
'gptel)
|
||||||
|
t))
|
||||||
|
(point))))
|
||||||
|
(end (if (use-region-p) (region-end) (point))))
|
||||||
|
(kill-region beg end)))
|
||||||
|
|
||||||
|
(gptel-request
|
||||||
|
prompt
|
||||||
|
:buffer (or buffer (current-buffer))
|
||||||
|
:position position
|
||||||
|
:in-place (and in-place (not output-to-other-buffer-p))
|
||||||
|
:stream stream
|
||||||
|
:callback callback)))
|
||||||
|
|
||||||
;; ** Set system message
|
;; ** Set system message
|
||||||
(transient-define-suffix gptel--suffix-system-message ()
|
(transient-define-suffix gptel--suffix-system-message ()
|
||||||
"Set directives sent to ChatGPT."
|
"Set directives sent to ChatGPT."
|
||||||
|
|
Loading…
Add table
Reference in a new issue