all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* Eglot cannot work with default completion-in-region?
@ 2024-01-26 20:38 Spencer Baugh
  2024-01-27 14:45 ` João Távora
  0 siblings, 1 reply; 9+ messages in thread
From: Spencer Baugh @ 2024-01-26 20:38 UTC (permalink / raw)
  To: emacs-devel; +Cc: joaotavora


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)




^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2024-01-30  0:32 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-01-26 20:38 Eglot cannot work with default completion-in-region? Spencer Baugh
2024-01-27 14:45 ` João Távora
2024-01-27 15:37   ` sbaugh
2024-01-28 10:23     ` Daniel Mendler via Emacs development discussions.
2024-01-28 14:09     ` João Távora
2024-01-29 21:14       ` Spencer Baugh
2024-01-29 22:21         ` João Távora
2024-01-29 22:51           ` JD Smith
2024-01-30  0:32             ` João Távora

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.