[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Eglot cannot work with default completion-in-region?
|
From: |
Spencer Baugh |
|
Subject: |
Eglot cannot work with default completion-in-region? |
|
Date: |
Fri, 26 Jan 2024 15:38:29 -0500 |
|
User-agent: |
Gnus/5.13 (Gnus v5.13) |
Hi,
The recent commit d376462c7183752bf44b9bd20bf5020fe7eaf75a prompted by
issue https://github.com/joaotavora/eglot/issues/1339 says:
>I declare it impossible to make C-M-i use of 'try-completion' behave
>sanely with LSP in its current state. YMMV. Use a completion tooltip,
>like Company.
So completion from Eglot, which is built into Emacs, is broken out of
the box? It has a hard dependency on using company-mode or similar
third-party packages?
If this is the case, perhaps Eglot should make it more clear that it
cannot be used without also installing and using company-mode or some
other package. Perhaps it should abort rather than running if the user
is using the default completion-in-region.
Alternatively, as someone who uses default completion-in-region and
would like to use Eglot, is there some way to make the common case
behave correctly?
I guess the issue is that in the LSP protocol, there's a difference
between the "sortText" and "filterText" which are used for displaying
completions and letting the user choose them, and the
"insertText"/"textEdit" which are used for inserting them.
So Eglot has this somewhat hacky code which runs in :exit-function to
delete the completion after completion-in-region inserts it, and insert
a different string instead:
(cond (textEdit
;; Revert buffer back to state when the edit
;; was obtained from server. If a `proxy'
;; "bar" was obtained from a buffer with
;; "foo.b", the LSP edit applies to that
;; state, _not_ the current "foo.bar".
(delete-region orig-pos (point))
(insert (substring bounds-string (- orig-pos (car bounds))))
(eglot--dbind ((TextEdit) range newText) textEdit
(pcase-let ((`(,beg . ,end)
(eglot-range-region range)))
(delete-region beg end)
(goto-char beg)
(funcall (or snippet-fn #'insert) newText))))
(snippet-fn
;; A snippet should be inserted, but using plain
;; `insertText'. This requires us to delete the
;; whole completion, since `insertText' is the full
;; completion's text.
(delete-region (- (point) (length proxy)) (point))
(funcall snippet-fn (or insertText label))))
This is code which is often broken, especially with default
completion-in-region.
However, the common case is that sortText==insertText/textEdit. In that
case, this code is not necessary, and Eglot doesn't need an
:exit-function at all.
Can Eglot detect this and avoid this somewhat hacky code in that case?
It should be a performance improvement and simplification anyway for all
completion frameworks.
(BTW, besides the issue with default completion-in-region, I also ran
into this while trying to write an OCaml-specific wrapper for
eglot-completion-at-point function which adds some additional
completions to those returned from the LSP. But if those completions
are chosen, then the Eglot exit-function breaks when it tries to look up
the insertText/textEdit. My LSP doesn't use textEdit at all, though, so
this is another unnecessary breakage)
- Eglot cannot work with default completion-in-region?,
Spencer Baugh <=
- Re: Eglot cannot work with default completion-in-region?, João Távora, 2024/01/27
- Re: Eglot cannot work with default completion-in-region?, sbaugh, 2024/01/28
- Re: Eglot cannot work with default completion-in-region?, Daniel Mendler, 2024/01/28
- Re: Eglot cannot work with default completion-in-region?, João Távora, 2024/01/28
- Re: Eglot cannot work with default completion-in-region?, Spencer Baugh, 2024/01/29
- Re: Eglot cannot work with default completion-in-region?, João Távora, 2024/01/29
- Re: Eglot cannot work with default completion-in-region?, JD Smith, 2024/01/29
- Re: Eglot cannot work with default completion-in-region?, João Távora, 2024/01/29