-
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
eglot-completion-at-point deleting extra text beyond the completion boundaries #1339
Comments
Thanks for the complete issue report. Will read later.
…On Sun, Dec 24, 2023, 18:39 Matthew Tromp ***@***.***> wrote:
1. Install rust-analyzer
2. Create a new rust project. Replace main.rs with the following:
fn main() {
let v: usize = 1;
1234.1234567890}
(1234.1234567890 is a placeholder for some hypothetical method call on
some hypothetical object)
1. Enter either rust-ts-mode or rust-mode.
2. M-x eglot (with rust-analyser)
3. Place point on the 1234 line and insert v.c:
v.c1234.1234567890
1. With point still on c, press M-<tab> to get eglot completions.
Select count-ones. The result will be:
v.count_ones4567890
The completion has replaced text beyond the symbol it was operating on.
The expected behavior is
v.count_ones.1234567890
That is, the symbol currently being completed (c1234) should be replaced
with the suggested completion.
Note that if you insert v., then get completions and select one,
everything behaves as expected. That is, starting with
v.1234.1234567890
with point after v., press M-<tab>, then select count_ones, the result is
v.count_ones.1234567890
as expected.
I think the cause is code in :exit-function in eglot-completion-at-point
which tries to delete the text added by the accepted completion, which
fails when the completion actually itself net removed text rather than
adding it. Also related is #160
<#160>.
Emacs version: GNU Emacs 30.0.50 (build 1, x86_64-pc-linux-gnu, X toolkit,
cairo version 1.18.0, Xaw scroll bars) of 2023-12-24, commit
ba3d3c699e12e2b236a353aa4dbfd1937d47f080
JSONRPC dump: eglot_jsonrpc_dump.txt
<https://github.com/joaotavora/eglot/files/13762585/eglot_jsonrpc_dump.txt>
—
Reply to this email directly, view it on GitHub
<#1339>, or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAC6PQ2D3W5K4Z4DT2CQEETYLBZHJAVCNFSM6AAAAABBBWLHIGVHI2DSMVQWIX3LMV43ASLTON2WKOZSGA2TKMJYGU3DSMI>
.
You are receiving this because you are subscribed to this thread.Message
ID: ***@***.***>
|
I've reproduced the problem and fix one of many cases. This is hairy stuff, and for now we'll just have to accept that partial completions or completions inside symbols in Eglot are very quirky. I'll leave the commit message here:
|
* 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: joaotavora/eglot#1339
The commit that I think closes this issue (as closed as it will ever get) is now pushed to Emacs.git master. Note that the previous "insert only
|
The 'try-completion' completion operation, used mostly in vanilla 'completion-at-point' invoked with C-M-i is close to impossible to get right in LSP because of the arbitrary edits handled in ':exit-function'. When this operation is invoked on the table, returning the pattern argument unchanged somehow (TM) makes a sole completion show the *Completions* buffer, where selecting it will recover context necessary for `:exit-function' and call that function. It doesn't break any other cases I know, and that's good enough for now. joaotavora/eglot#1339 * lisp/progmodes/eglot.el (eglot-completion-at-point): Return pattern when 'try-completion' is invoked.
Nope, sorry. Doesn't work. Can never work as far as I can tell. I won't try anymore, but anyone else can:
|
(1234.1234567890 is a placeholder for some hypothetical method call on some hypothetical object)
v.c
:c
, pressM-<tab>
to get eglot completions. Selectcount-ones
. The result will be:The completion has replaced text beyond the symbol it was operating on. The expected behavior is
That is, the symbol currently being completed (c1234) should be replaced with the suggested completion.
Note that if you insert
v.
, then get completions and select one, everything behaves as expected. That is, starting withwith point after
v.
, pressM-<tab>
, then selectcount_ones
, the result isas expected.
I think the cause is code in :exit-function in eglot-completion-at-point which tries to delete the text added by the accepted completion, which fails when the completion actually itself net removed text rather than adding it. Also related is #160.
Emacs version: GNU Emacs 30.0.50 (build 1, x86_64-pc-linux-gnu, X toolkit, cairo version 1.18.0, Xaw scroll bars) of 2023-12-24, commit ba3d3c699e12e2b236a353aa4dbfd1937d47f080
JSONRPC dump: eglot_jsonrpc_dump.txt
The text was updated successfully, but these errors were encountered: