]> git.eshelyaron.com Git - emacs.git/commitdiff
Eglot: partial fix for middle-of-symbol completions
authorJoão Távora <joaotavora@gmail.com>
Tue, 26 Dec 2023 00:31:29 +0000 (00:31 +0000)
committerJoão Távora <joaotavora@gmail.com>
Tue, 26 Dec 2023 02:41:28 +0000 (02:41 +0000)
* 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

lisp/progmodes/eglot.el

index 8235bbe1751dc28fb1f1dc289d368727cdd9de85..d777e488c4350a99b16ea295b55af840c98fb7b9 100644 (file)
@@ -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)))