Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dedicated buffer like gptel-inspect-query, but just to edit the response at point with the same major mode #573

Closed
Closed
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
gptel: introduce gptel-edit-response
Lucian Knock committed Jan 17, 2025
commit 87638e3117b34ca2cbbf3588aba96e4b5865da95
61 changes: 61 additions & 0 deletions gptel.el
Original file line number Diff line number Diff line change
@@ -658,6 +658,12 @@ This opens up advanced options in `gptel-menu'.")
(defvar-local gptel--bounds nil)
(put 'gptel--bounds 'safe-local-variable #'always)

(defvar-local gptel--edit-response-buffer nil
"Original buffer for gptel response being edited.")

(defvar-local gptel--edit-response-pos nil
"Original position in `gptel--edit-response-buffer' where editing started.")

(defvar gptel--num-messages-to-send nil)
(put 'gptel--num-messages-to-send 'safe-local-variable #'always)

@@ -2080,6 +2086,61 @@ context for the ediff session."
(interactive "p")
(gptel--previous-variant (- arg)))

(defun gptel-edit-response ()
"Edit the LLM response at point in a separate buffer."
(interactive)
(unless (gptel--in-response-p)
(user-error "No gptel response at point"))
(let ((response (gptel--current-response))
(mode (buffer-local-value 'major-mode (current-buffer))))
(gptel--setup-edit-buffer)))

(defun gptel--setup-edit-buffer ()
"Set up an edit buffer for the response at point."
(let* ((response (gptel--current-response))
(mode (buffer-local-value 'major-mode (current-buffer)))
(orig-buf (current-buffer))
(orig-point (point))
(bounds (gptel--get-bounds))
(offset (- orig-point (car bounds))))
(with-current-buffer (get-buffer-create "*gptel-edit*")
(let ((inhibit-read-only t))
(erase-buffer)
(funcall mode)
(insert response)
(use-local-map (make-composed-keymap
(define-keymap
"C-c C-c" #'gptel--commit-edit
"C-c C-k" #'quit-window)
(current-local-map)))
(setq header-line-format
(substitute-command-keys
"Edit response. \\[gptel--commit-edit]: Save changes, \\[quit-window]: Cancel")
gptel--edit-response-buffer orig-buf
gptel--edit-response-pos orig-point)
(goto-char (point-min))
(forward-char offset)
(switch-to-buffer (current-buffer))))))

(defun gptel--commit-edit ()
"Commit edited response back to the original buffer."
(interactive)
(unless (equal (buffer-name) "*gptel-edit*")
(user-error "This command is meant for use in a gptel edit buffer"))
(let* ((edited-text (buffer-substring (point-min) (point-max)))
(orig-buf gptel--edit-response-buffer)
(orig-pos gptel--edit-response-pos))
(quit-window t)
(with-current-buffer orig-buf
(goto-char orig-pos)
(when-let ((bounds (gptel--get-bounds)))
(let ((beg (car bounds))
(end (cdr bounds)))
(delete-region beg end)
(goto-char beg)
(insert edited-text)
(goto-char orig-pos))))))

(provide 'gptel)
;;; gptel.el ends here