* lisp/progmodes/eglot.el (eglot-completion-at-point): Fix
completion reversion in :exit-function.
In a rust-ts-mode buffer such as this main.rs file
fn main() {
let v: usize = 1;
v.c<cursor-here>1234.
1234567890
}
the server wants to edit the line to read, after C-M-i and selecting
"count_ones"
v.count_ones<cursor-here>.
1234567890
But it couldn't apply the edit to the correct initial state because
that state wasn't correctly restored. This commit fixes that.
However, if the initial state is
v.count_on1234.
1234567890
then completion still fails, because the 'try-completion' call in
eglot-completion-at-point will just return complete to "count_ones"
and Emacs doesn't consider this a completion "exit", so it'll
completely ignore the exit function.
I think 'try-completion' (and 'test-completion') simply can't be used
here (for one, they obey styles, and styles are off-limits in LSP),
but I'll leave that for another commit.
Github-reference: https://github.com/joaotavora/eglot/issues/1339
(let* ((server (eglot--current-server-or-lose))
(bounds (or (bounds-of-thing-at-point 'symbol)
(cons (point) (point))))
+ (bounds-string (buffer-substring (car bounds) (cdr bounds)))
(sort-completions
(lambda (completions)
(cl-sort completions
;; 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'
+ ;; "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)))