joaotavora / sly

Sylvester the Cat's Common Lisp IDE
1.23k stars 139 forks source link

How to achieve vanilla completion #636

Closed viliaapro closed 2 months ago

viliaapro commented 2 months ago

Dear sir, thank you for Sly! I have a question on achieving vanilla completion, with customizations

'(sly-complete-symbol-function 'sly-simple-completions)
'(sly-symbol-completion-mode nil)

Now, when I use M-Tab in Sly REPL or Sly-enhanced Lisp mode, with a prefix say abo, it lists the alternatives, but doesn't complete up to the longest common prefix abort, like is normally done in, say, Shell mode.

How to achieve such vanilla completion?

aadcg commented 2 months ago

@viliaapro TAB and M-TAB run two distinct commands. The former runs sly-mrepl-indent-and-complete-symbol, while the latter runs complete-symbol. You probably want to run the former.

viliaapro commented 2 months ago

@aadcg Thanks, but sly-mrepl-indent-and-complete-symbol still doesn't complete up to longest common prefix; also we'd want vanilla completion to work in Lisp-mode buffers, too, not just the REPL.

Normally I've customized '(tab-always-indent 'complete), but when I turn it nil, TAB just indents or self-inserts in both Lisp and REPL modes.

viliaapro commented 2 months ago

Should've mentioned up front that the issue affects Lisp-mode buffers, too; sorry.

aadcg commented 2 months ago

@viliaapro From what I understand, when sly-complete-symbol-function is set to sly-simple-completions, you'd expect that abo would expand to abort without showing the *sly-completions* buffer since it is the only match found. It should be easy to return immediately when a single match is found.

viliaapro commented 2 months ago

@aadcg Yes that is the behaviour when sly-symbol-completion-mode is t, but not when it is nil.

There are other reasons for me not wanting to use sly-symbol-completion-mode, such as it picking up a first candidate rather than completing upto longest common prefix, but those are beside the issue here. For long-term robustness, it would be good to solve this issue of Sly and Emacs's default completion having surprising interaction.

joaotavora commented 2 months ago

it would be good to solve this issue of Sly and Emacs's default completion having surprising interaction.

Not suprising here. I can complete to abort using (setq sly-complete-symbol-function #'sly-simple-completions) with vanilla C-M-i just fine. So if you're running into problems I would start with a Emacs -Q recipe that we can follow along to.

viliaapro commented 2 months ago

@joaotavora Thanks, I'll try to find the issue!

viliaapro commented 2 months ago

@joaotavora Alright, it keeps happening with Emacs -Q, too.

Here's my recipe.el

(load-file "~/.emacs.d/elpa/sly-20240408.931/sly-autoloads.el")
(setq sly-complete-symbol-function 'sly-simple-completions)
(setq sly-symbol-completion-mode nil)

(sly "/usr/bin/sbcl")

Still doesn't complete from abo to abort.

I'm using GNU Emacs 29.2.50 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.24.33, cairo version 1.16.0) of 2024-01-31

joaotavora commented 2 months ago

Just to be clear your problem is that it doesn't do the "unique completion" thing? Does it show you an abort completion? I don't know exactly what you want to happen.

viliaapro commented 2 months ago

@joaotavora It does show an abort completion; what I desire is the option to make it insert the characters rt after abo so as to greedily complete up to the longest common prefix abort of all possible completions (in this case, abort and abort-break), like in vanilla Shell mode or interactive Bash in a terminal emulator, for example.

I think it should be readily doable with Emacs's existing completion-at-point facility; however, I'm not familiar with it. Basically every mode in its default style of completion inserts characters up to the longest common prefix.

viliaapro commented 2 months ago

The behaviour I seek seems to be provided by the function completion-in-region; now to find a way to use it from Sly.

joaotavora commented 2 months ago

No, @viliaapro you're off the mark looking there. The problem here is that SLY uses something loosely called "external completion", which I don't have time to go into right now. Unlike Eglot, though, it doesn't use the external-completion.el library (maybe it should one day).

Anyway, your problem may have a solution in SLY, because the completion situation is significantly easier than Eglot's. I'll see what I can do.

But you can keep on investigating yourself.

viliaapro commented 2 months ago

@joaotavora Oh yeah, we wouldn't want to send long lists of completion candidates over the wire. Hmm, there's already a longest-common-prefix function on the Slynk side.

I'll take a look at external-completion.el.

viliaapro commented 2 months ago

Thanks! Seems to work on SBCL, but not on Clozure (v1.12.2 LinuxX8664); on Clozure, I still get the old behaviour.