emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: scratch/backend-completion c807121fbd 1/2: Add lisp/backend-completi


From: João Távora
Subject: Re: scratch/backend-completion c807121fbd 1/2: Add lisp/backend-completion.el
Date: Tue, 29 Nov 2022 22:59:04 +0000
User-agent: Gnus/5.13 (Gnus v5.13)

Stefan Monnier <monnier@iro.umontreal.ca> writes:

>>> Maybe a good way to do that is to provide a (backend-completion-table
>>> FUNC CATEGORY &optional METADATA) where FUN is a function which handles
>>> the tryc and allc cases (maybe the `tryc` handling could even be
>>> optional, depending on how the `tryc` case is usually handled (do
>>> backends often provide something usable for `tryc`?)).  That function
>>> would then return an appropriate completion-table (function), and would
>>> make sure along the way that CATEGORY is mapped to `completion-backend`
>>> in the `completion-category-defaults`.
>>
>> I get the idea, I think.  I thought about this, but I'm not sure this
>> can be made generic enough to service the three examples I know of:
>> Eglot, SLY and the eel.el thing I've been using lately.
>
> I can't see why it wouldn't be just as general as what we have now.
>
>     (defun backend-completion-table ( tryc-function allc-function
>                                       category &optional metadata)
>       (unless (assq category completion-category-defaults)
>         (push `(,category (styles completion-backend))
>               `completion-category-defaults))
>       (lambda (string pred action)
>         (pcase action
>           (`metadata
>            `(metadata (category . ,category) . ,metadata))
>           (`(backend-completion-tryc . ,point)
>            ;; FIXME: Obey `pred`?  Pass it to `tryc`?
>            `(backend-completion-tryc . ,(funcall tryc string point)))
>           (`(backend-completion-allc . ,point)
>            (let ((all (funcall allc string point)))
>              `(backend-completion-allc . ,(seq-filter pred all))))
>           (`(boundaries . ,_) nil)
>           (t
>            (let ((all (funcall allc string (length string))))
>              (complete-with-action action all string pred))))))


OK great.  But where do you plug the current eglot functions into it.

>
>>> That `backend-completion-table` would also have the benefit that it
>>> could make sure the completion-table it returns also behaves sanely
>>> with other styles (i.e. also handle the "normal" completion table
>>> requests), whereas otherwise the temptation would be very high for users
>>> of this package to use "completion table functions" which only handle
>>> the `backend-completion-tryc/allc` requests and fail pathetically when
>>> another style is used.  Similarly `backend-completion-table` could also
>>> make sure PRED is obeyed.
>>
>> Alright.  But please, follow up with some code.  You're probably right,
>> but this whole thing is too complicated for me to understand.
>
> See above.
>
>>>>  (add-to-list 'completion-category-overrides
>>>> -             '(eglot-indirection-joy (styles . 
>>>> (eglot--lsp-backend-style))))
>>>> +             '(eglot-indirection-joy (styles . 
>>>> (backend-completion-backend-style))))
>
> Wow!  I didn't pay attention at first, but I now see you're modifying
> `completion-category-overrides` which is the user-facing variable.
> You should modify `completion-category-defaults` instead!

Yep.  I actually meant to correct that in the patch.  The reason I was
using overrides is because fido-mode nullifies
completion-category-defaults.  It shouldn't, and I added another patch
correcting that.  So yes, you're right.

>>> Any reason not to call that completion category just `eglot`?
>>
>> Yes, 'eglot' is already a different completion category, for
>> completion-at-point, with a different structure.
>> `eglot-indirection-joy' is just a product of my usual confusion with
>> this whole jungle of concepts: I just vaguely understand it's an
>> indirection so I called it accordingly for mental reference.  But feel
>> free to suggest a better name.
>
> I'm not very familiar with Eglot's code but based on a cursory check, it
> seems this is used specifically when completing an identifier for things
> like `xref`, so maybe `eglot-identifier` (and maybe `eglot` should be
> renamed to `eglot-code` since it's used to complete the actual code in
> the buffer)?

Maybe.  As I've often told you, all this completion code is hard to
grasp.  I do "get" it somewhat, and I've been working with it intensely
for a long time.  But also, I don't really get it :-) For example, I
have no solid concept of what a category or a style is, so everything
just reads like "an indirection from this thing to that other thing".
So I named this thing 'eglot-indirection' . 'eglot-code' may be logical
for someone who knows what a category means, now but sounds something
that will make absolutely no sense to me 2 weeks from now.

João



reply via email to

[Prev in Thread] Current Thread [Next in Thread]