karthink / gptel

A simple LLM client for Emacs
GNU General Public License v3.0
1.14k stars 119 forks source link

gptel-send region in read-only buffer or text #48

Closed vhallac closed 1 year ago

vhallac commented 1 year ago

I've added the following code in my init script to have gptel-send output the answer to the end of a buffer gptel-answer when the selected region is in a read-only buffer, or the :position points to a text that is read-only. Current beahvior is to error out, and leave the curl answer buffer available.

  (defun vh/gptel-insert-response-advice (old-function response info &rest args)
    (let ((gptel-buffer (plist-get info :buffer)))
      (with-current-buffer gptel-buffer
        (when (or buffer-read-only
                  (get-text-property (plist-get info :position) 'read-only))
          (let ((answer-buffer (get-buffer-create "*gptel-answer*")))
            (setq info (plist-put info :buffer answer-buffer))
            (setq info (plist-put info :position (with-current-buffer answer-buffer (point-max))))
            (when (not (get-buffer-window answer-buffer 'visible))
              (pop-to-buffer answer-buffer))))
        (apply old-function (cons response (cons info args)))
        (when buffer-read-only
          (pop-to-buffer "*gptel-answer*")))))
  (advice-add #'gptel--insert-response :around #'vh/gptel-insert-response-advice)
  (advice-add #'gptel-curl--stream-insert-response :around #'vh/gptel-insert-response-advice)

You might consider using this approach or something along these lines in your code.

karthink commented 1 year ago

Yes, this has been a TODO in the code for a while. Thanks for the reminder, I'll look into it soon.

karthink commented 1 year ago

Read only buffers are now handled by gptel. If you run into any edge cases, please let me know.

vhallac commented 1 year ago

I've tried out the updated code and it works just fine. Thanks for the fast implementation.