From: João Távora Date: Tue, 26 Dec 2023 00:31:29 +0000 (+0000) Subject: Eglot: partial fix for middle-of-symbol completions X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=a6ef458e3831001b0acad57cf8fa75b77a4aff3f;p=emacs.git Eglot: partial fix for middle-of-symbol completions * 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.c1234.1234567890 } the server wants to edit the line to read, after C-M-i and selecting "count_ones" v.count_ones.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 --- diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el index 8235bbe1751..d777e488c43 100644 --- a/lisp/progmodes/eglot.el +++ b/lisp/progmodes/eglot.el @@ -3031,6 +3031,7 @@ for which LSP on-type-formatting should be requested." (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 @@ -3213,9 +3214,10 @@ for which LSP on-type-formatting should be requested." ;; 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)))