karthink / gptel

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

Two more interface-related feature requests #278

Closed jwiegley closed 3 months ago

jwiegley commented 3 months ago

Hi @karthink! Two more things that I've noticed so far:

It's be nice to have a customization variable for switching the gptel-send binding to RET instead of C-c RET. I can easily do this myself with a custom keybinding, but maybe others would want it to be easier to setup.

It would be great if M-p and M-n could cycle through past prompts, so that I can quickly edit or re-use a prompt from my history.

karthink commented 3 months ago

It's be nice to have a customization variable for switching the gptel-send binding to RET instead of C-c RET.

Just checking: Was it clear to you that the user prompt is not limited to the single-line Org/Markdown headline when you used gptel? I ask since you mentioned chatgpt-shell before and might be continuing to think about shell-like line-based interaction instead of free-form buffer-oriented interaction. For example, here is a partial transcript from a recent Chat:

*Prompt*: How do I assign a value to a variable whose symbol representation in Julia is :a?
i.e.:

#+begin_src julia
b = :a
something(b) = 4
a
#+end_src

I want a to be set to 4 above.

*Response*:
In Julia, you can assign a value to a variable represented by the symbol =:a= using the =setproperty!= function. Here's an example:

#+begin_src julia
a = setproperty!(Val{:a}, :something, 4).something
#+end_src

This assigns the value =4= to the variable =a= represented by the symbol =:a=.

Here I've set the prompt and response prefixes (gptel-prompt-prefix-alist and gptel-response-prefix-alist) to the strings *Prompt*: and *Response*:\n. So I use Org mode normally, including the regular use of RET, to type out the user prompt. My prompts are often quite long, sometimes several paragraphs.

Considering this, I'm not sure encouraging the use of RET to send the prompt instead is a good idea, especially since this can be an expensive operation (in terms of money), there's no y-or-n-p confirmation step, and it's easy to mistype RET expecting a newline.

(Of course, Emacs-veterans know what they're doing and can use it however they want.)

Re: free-form interaction: I often move into the response and remove parts of it, or type in clarification questions in the middle of a response (which creates another user prompt in between), edit my previous prompts, move the cursor into the response and regenerate it with M-RET:

screenshot_20240403T185218

So there is no linear time-ordering imposed by gptel like in a shell.

It would be great if M-p and M-n could cycle through past prompts, so that I can quickly edit or re-use a prompt from my history.

I'm not sure what "past prompts" means here -- perhaps you mean like command history in a shell? This doesn't make sense for gptel's buffer-oriented paradigm either, any more than making all lines of live buffers available elsewhere with M-n and M-p does. I personally use hippie-expand's try-expand-whole-line for this, which I think I learnt about from one of your interviews with Sacha Chua. :)

jwiegley commented 3 months ago

I see what you mean, I suppose I got used to the comint-based approach of chatgpt-shell. Most of my prompts tend to be one-liners, so RET ends up working best for me 95% of the time. When I wanted to edit something long-form, I would use C-c C-e to edit in a buffer before submitting the whole contents.

I will give your approach more time to grow on me, and see how it goes!

karthink commented 3 months ago

Sure!

A little more background about the differences with comint-style interaction: You're not limited to calling M-x gptel and creating a dedicated buffer to use it. gptel's goal is to be available in any buffer in Emacs, even in read-only/special buffers like dired, or inside the minibuffer prompt. This demo video of gptel [16 minutes] showcases a few very different uses and highlights the buffer-orientedness.