Weird handling of brackets in assignment

Hi, I get some weird bracket behavior on lines where I assign variables in emacs using eglot.

When I have something like the following:

let var = func();

With the cursor right in front of "func", typing an opening paren, I would expect to get an opening paren, followed by a closing paren handled by auto pair from my editor i.e. "()func()".

But what I get instead is a paren on the end of the line:

let var = (func());

I have tracked it to the lsp (works like normal when it is off), and it seems to be due to a onTypeFormatting event.

Is this expected behavior? It seems like a strange thing to manage with an lsp and interacts poorly with other paren handling, sometimes resulting in two closing parens to a single opening one.


1 Like

Personally, I prefer editors to insert only valid code when that's feasible. I don't think there's anything you could put within the left parentheses of ()func() which is valid Rust. It doesn't support c-style casts.

OTOH, you could intend to insert an operator. I could see where that would be annoying for that case. In vscode you can use Ctrl+Z to undo the automatically-inserted code when it doesn't match desired.

I guess there are mainly two cases where this is somewhat annoying, one of which is emacs specific.
Firstly ()func() would temporarily occur if I wanted to change func() into something like (a + b) * func().
The other is when using electric-pair-mode, marking the function and surrounding it with parens yields (func())) with the extra paren added by the lsp.

I don't know if this is something that is possible to turn of. I find it odd to have the lsp handle parenthesis pairing to begin with.

After digging some more into this I've found that this is an issue with the eglot version bundled with emacs 29.1

By updating to a newer version of eglot the problem goes away.

1 Like

I had the same problem even after upgrading emacs and eglot to latest. I can confirm the root cause is indeed onTypeFormatting. On my side, the eglot log buffer shows this:

[jsonrpc] e[17:16:16.575] --> textDocument/onTypeFormatting[20] {"jsonrpc":"2.0","id":20,"method":"textDocument/onTypeFormatting","params":{"textDocument":{"uri":"*****/"},"options":{"tabSize":2,"insertSpaces":true,"insertFinalNewline":true,"trimFinalNewlines":true},"position":{"line":323,"character":19},"ch":"("}}
[jsonrpc] e[17:16:16.579]   <-- textDocument/onTypeFormatting[20] {"jsonrpc":"2.0","id":20,"result":[{"range":{"start":{"line":323,"character":23},"end":{"line":323,"character":23}},"newText":")"}]}

In case someone else encounters this in the future, here is my solution:
add :documentOnTypeFormattingProvider to eglot-ignored-server-capabilities. You can M-x customize-variable ENTER eglot-ignored-server-capabilities ENTER and then choose the type formatting checkbox and finally C-x C-s to add this to your ~/.emacs.