karthink / gptel

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

Move point to the end of inserted text when inserting into a buffer #269

Closed jwr closed 3 months ago

jwr commented 3 months ago

I would suggest that gptel move the point to the end of the inserted text when generating into a buffer. Right now, if I'm running gptel several times, each reply gets inserted before the previous one. I expected to be able to generate several replies into a buffer, one after another, separated by a newline.

I tried (add-hook 'gptel-post-response-functions 'gptel-end-of-response), but that only seems to work for the gptel buffer, not for other text buffers (I am testing with *scratch* in Markdown mode).

karthink commented 3 months ago

I tried (add-hook 'gptel-post-response-functions 'gptel-end-of-response), but that only seems to work for the gptel buffer, not for other text buffers (I am testing with scratch in Markdown mode).

This was a bug, thanks for reporting it! It's not that it was only running in gptel chat buffers -- the problem is that moving point like this:

(with-current-buffer gptel-buffer
  (goto-char (somewhere)))

does not move the point in a window showing that buffer unless the window is selected. Each window has its own point in the buffer and it only moves if the buffer is selected -- a fact I have to remind myself of every couple of years. Fixed by selecting the window (if possible) before running the hook.

I would suggest that gptel move the point to the end of the inserted text when generating into a buffer.

I will not do this by default. It breaks the async behavior, Emacs or the user can be doing any number of other things in the buffer. The hook method is the recommended way to do this.

jwr commented 3 months ago

Thank you for fixing this 🙏 — I can now implement the behavior I need using gptel-post-response-functions and it works well.

Incidentally, I think this variable needs a docstring fix. The docstring says "This hook is called in the buffer from which the prompt was sent", it probably should say "This hook is called in the buffer to which the response was sent"?

Also, not sure if that is intentional or not, but the gptel-post-response-functions does not follow the -hook naming convention, so one can't use it in the :hooks section of use-package. Not a big problem, obviously.

karthink commented 3 months ago

Incidentally, I think this variable needs a docstring fix. The docstring says "This hook is called in the buffer from which the prompt was sent", it probably should say "This hook is called in the buffer to which the response was sent"?

Fixed, thanks for catching that.

Also, not sure if that is intentional or not, but the gptel-post-response-functions does not follow the -hook naming convention

I am following the guidelines for naming hooks as laid out in the Elisp manual (info "(elisp) Hooks"):

If the hook variable’s name does not end with ‘-hook’, that indicates it is probably an “abnormal hook”. These differ from normal hooks in two ways: they can be called with one or more arguments, and their return values can be used in some way. The hook’s documentation says how the functions are called and how their return values are used. Any functions added to an abnormal hook must follow the hook’s calling convention. By convention, abnormal hook names end in ‘-functions’.

The problem is use-package's bad defaults. You can change it by adjusting use-package-hook-name-suffix.