-
Notifications
You must be signed in to change notification settings - Fork 201
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Issue with textEdit for non-prefix completion candidates #366
Comments
This is the problematic part of eglot-completion-at-point: (cond (textEdit
;; Undo (yes, undo) the newly inserted completion.
;; If before completion the buffer was "foo.b" and
;; now is "foo.bar", `proxy' will be "bar". We
;; want to delete only "ar" (`proxy' minus the
;; symbol whose bounds we've calculated before)
;; (github#160).
(delete-region (+ (- (point) (length proxy))
(if bounds (- (cdr bounds) (car bounds)) 0))
(point)) It seems to assume that the original item can only be increased with the proxy. But in case of this issue, "lor" is replaced with "1", so delete-region deletes more than it should. If we want to undo, why can't we use emacs' undo functionality? I'm totally unfamiliar with the undo mechanism, but the following patch seems to work. But I admit I tested it only slightly. diff --git a/eglot.el b/eglot.el
index a33f204..c576e91 100644
--- a/eglot.el
+++ b/eglot.el
@@ -2097,9 +2097,7 @@ is not active."
;; want to delete only "ar" (`proxy' minus the
;; symbol whose bounds we've calculated before)
;; (github#160).
- (delete-region (+ (- (point) (length proxy))
- (if bounds (- (cdr bounds) (car bounds)) 0))
- (point))
+ (primitive-undo 1 buffer-undo-list)
(eglot--dbind ((TextEdit) range newText) textEdit
(pcase-let ((`(,beg . ,end) (eglot--range-region range)))
(delete-region beg end) For a complete patch, eglot-completion-at-point should temporary enable undo if it's disabled in the buffer, which probably complicates the patch, and I'm not even know how to that. |
Good question. Maybe we can. Let's page @monnier here, hopefully the issue context is enough to explain what's going on. |
It should be as easy has temporarily binding |
> For a complete patch, eglot-completion-at-point should temporary enable
> undo if it's disabled in the buffer, which probably complicates the patch,
> and I'm not even know how to that.
It should be as easy has temporarily binding `buffer-undo-list` to some
non-`t` value in some context. But I think we could just assume it's always
on, why should it not be so?
See `atomic-change-group` how to do it:
(let ((handle (prepare-change-group)))
(activate-change-group handle)
...
(then-either
(accept-change-group ,handle)
(cancel-change-group ,handle)))
The `activate-change-group` is the one that enables undo if needed, and
the `accept/cancel-change-group` are the ones that disable it (again,
when needed).
Stefan
|
Stefan, thank you. So we should call activate-change-group early on in eglot-completion-at-point, and call cancel-change-group in the exit-function. But, if I understand correctly, we must call accept-change-group when the completion is unsuccessful. But how do we know when it is unsuccessful? We are not notified when there's no match. (It is independent, but Eglot won't be able to complete "\ref{lorem ip", because (bounds-of-thing-at-point 'symbol) returns "ip" and not "lorem ip".) |
I welcome an undo-based solution here, but if I read @monnier correctly, we have to be sure to match
We don't, I think. We just |
> So we should call activate-change-group early on in eglot-completion-at-point
I welcome an undo-based solution here, but if I read @monnier correctly, we
have to be sure to match `activate-change-group` to an `accept-change-group`
or `cancel-change-group`.
That's right.
|
(Maybe this should be a new issue, but let me add a (not so) quick side-remark. There are indeed a few places where one might want the completion text to include spaces, including cases unrelated to fuzzy completion. But even worse is the following situation: if you follow AUCTeX labeling scheme, you will get labels like |
So I know where to put |
I've just reread this old, but long discussion and I wonder whether a simple server-side modification would settle the issue.
digestif could send
That is by changing the :label field, the editor completes to the "Lorem ipsum" string instead of "1", but keeps the textEdit to "1". In this example, this approach is even increases the user-friendliness: the user stated to partially write the name of a \section, so the editor gives a list of possible section names instead of a list of \label ids. I haven't tested this. nevertheless, what do you think, @astoff? |
@nemethf Thanks for the suggestion! I made this change to my server, and it's much more functional indeed. Also, I can't reproduce the situation originally described in this issue, so I'll close it. |
If I start with the following LaTeX file, with the cursor at the first
}
,and do
company-complete
, then I expect to get\ref{1}
on line 1. Instead, I end up with the following:Now, the response of the completion request from my server is
which looks correct to me. (I'm using the Digestif TeX server, but this shouldn't matter.)
If I modify my server so it doesn't send the textEdit entry, then Eglot has the correct behaviour. That's quite clever indeed, but it seems better to provide a textEdit, since it's the only explict way to convey that "lor" is the completion prefix.
The text was updated successfully, but these errors were encountered: