Skip to content
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

Override completion inserts extra pair of () when committing with ( #7699

Open
dibarbet opened this issue Oct 26, 2024 · 3 comments
Open

Override completion inserts extra pair of () when committing with ( #7699

dibarbet opened this issue Oct 26, 2024 · 3 comments
Assignees
Milestone

Comments

@dibarbet
Copy link
Member

When committing an override completion item with (, an extra () gets inserted.

Image

@dibarbet dibarbet added this to the September2024 milestone Oct 26, 2024
@dibarbet dibarbet self-assigned this Oct 26, 2024
@dibarbet dibarbet modified the milestones: September2024, November2024 Oct 26, 2024
@dibarbet
Copy link
Member Author

dibarbet commented Oct 26, 2024

Issue appears to be that the commit character ( gets inserted and the after resolve text edit runs (which doesn't know about the commit character). The extra ) is coming from vscode brace completion. cc @genlu for ideas - looks like there was some notion of this here, but I couldn't figure out what the intention was - https://github.com/dotnet/vscode-csharp/blob/main/src/lsptoolshost/commands.ts#L137

There is some additional complexity - await completion likely wants the commit character inserted (it inserts a complex edit that ends before the commit character location - async Task DoSomethingAsync()\r\n {\r\n await - so committing with space should insert space after)

Note - ( is only a commit character if override completion starts on the method name. After just typing override for example (

Some ideas

  1. Have the textedit returned by the server include the entire word range, then use vscode's document.getWordRangeAtPosition(textEdit.start) to replace the entire word range. - probably won't work - the word range doesn't include the inserted (
  2. Call the server to re-resolve the edit based on the new document with the commit char
  3. Somehow extend the text edit to include the commit character (not sure - we don't know how the item was committed)
    a. LSP spec guarantees commit character is a single character - server could indicate the possible commit char
    b. Cannot just check if text edit text from the start exactly matches document text - the text edit might start above (for example you just type override which returns a text edit like public override <...>

Some example text edits

"newText": "public override void AbstractMethod()\r\n    {\r\n        throw new NotImplementedException();\r\n    }\r\n\r\n"
"newText": "bstractMethod()\r\n    {\r\n        throw new NotImplementedException();\r\n    }"

@genlu
Copy link
Member

genlu commented Oct 29, 2024

Hmm, in VS we disable further type char command handler to bypass things like brace completion. I have to examine commit chars for our existing complex edit items to have a better sense of the issue, but from the examples above (overrride and await completion), it seems one thing we might use to decide whether a commit char should be inserted is if it's part of the display text of a complex edit? e.g. ( is part of DoSomething() but is not part of await. This would be a very crude heuristic, maybe it would work for most cases in vscode?

@dibarbet
Copy link
Member Author

it seems one thing we might use to decide whether a commit char should be inserted is if it's part of the display text of a complex edit?

A few issues

  1. We don't decided whether or not the commit character is inserted, the LSP client does and currently has no way to not insert the commit character
  2. The display text or label on the completion item does not contain the parenthesis - it would only be DoSomething.
  3. We don't know what the display text or label is at the time we do the followup text edit (though we could add it onto the data object).

One potential idea was to check if the word at the cursor location + the next character was present inside the followup text edit text - and if so expand the range to the next character? Main issue I was worrying about is if the followup character happened to already be in the document (and wasn't used as a commit character). I haven't been able to come up with a broken scenario for that, but I'm not convinced.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants