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

completion request should include textEdit according to protocol #465

Closed
puremourning opened this issue Nov 25, 2017 · 3 comments · Fixed by #1298
Closed

completion request should include textEdit according to protocol #465

puremourning opened this issue Nov 25, 2017 · 3 comments · Fixed by #1298

Comments

@puremourning
Copy link
Contributor

puremourning commented Nov 25, 2017

The current version of the protocol contains the following text:

However, properties that are needed for the inital sorting and filtering, like sortText, filterText, insertText, and textEdit must be provided in the textDocument/completion request and must not be changed during resolve.

However jdt.ls returns only insertText in the original response, but then adds a textEdit after a resolve. This is a strict violation of the protocol and in editors that can't handle the resolve request properly, requires either that we resolve every completion item (the use of textEdit is not optional, insertion text alone doesn't work for things like imports).

Is it possible to include the textEdit in the initial response?

@puremourning
Copy link
Contributor Author

Log of an example:

2017-11-25 22:33:21,023 - DEBUG - Pre-resolve: {u'insertText': u'getClass', u'sortText': u'999999035', u'kind': 3, u'detail': u'Object', u'label': u'getClass() : Class<?>', u'data': {u'name': u'getClass', u'pid': u'75', u'uri': u'file:/Users/ben/.vim/bundle/YouCompleteMe/third_party/ycmd/ycmd/tests/java/testdata/simple_eclipse_project/src/com/youcompleteme/Test.java', u'decl_signature': u'Ljava.lang.Object;', u'signature': u'()Ljava.lang.Class<*>;', u'rid': u'0'}}
2017-11-25 22:33:21,023 - DEBUG - TX: Sending message: b'Content-Length: 477\r\n\r\n{"id": "78", "jsonrpc": "2.0", "method": "completionItem/resolve", "params": {"data": {"decl_signature": "Ljava.lang.Object;", "name": "getClass", "pid": "75", "rid": "0", "signature": "()Ljava.lang.Class<*>;", "uri": "file:/Users/ben/.vim/bundle/YouCompleteMe/third_party/ycmd/ycmd/tests/java/testdata/simple_eclipse_project/src/com/youcompleteme/Test.java"}, "detail": "Object", "insertText": "getClass", "kind": 3, "label": "getClass() : Class<?>", "sortText": "999999035"}}'
2017-11-25 22:33:21,024 - DEBUG - RX: Received message: b'{"jsonrpc":"2.0","method":"window/logMessage","params":{"type":3,"message":"25-Nov-2017 22:33:10 \\u003e\\u003e document/resolveCompletionItem"}}'
2017-11-25 22:33:21,027 - DEBUG - RX: Received message: b'{"jsonrpc":"2.0","id":"78","result":{"label":"getClass() : Class\\u003c?\\u003e","kind":3,"detail":"Object","documentation":" Returns the runtime class of this Object. The returned Class object is the object that is locked by static synchronized methods of the represented class. \\nThe actual result type is Class\\u003c? extends |X|\\u003e where |X| is the erasure of the static type of the expression on which getClass is called. For example, no cast is required in this code fragment:\\n\\n Number n \\u003d 0; \\n Class\\u003c? extends Number\\u003e c \\u003d n.getClass(); \\n\\n * Returns:\\n   - The Class object that represents the runtime class of this object.\\n * @jls\\n   - 15.8.2 Class Literals","sortText":"999999035","insertText":"getClass","insertTextFormat":1,"textEdit":{"range":{"start":{"line":12,"character":9},"end":{"line":12,"character":9}},"newText":"getClass"}}}'
2017-11-25 22:33:21,032 - DEBUG - Post-resolve: {u'insertText': u'getClass', u'sortText': u'999999035', u'kind': 3, u'documentation': u' Returns the runtime class of this Object. The returned Class object is the object that is locked by static synchronized methods of the represented class. \nThe actual result type is Class<? extends |X|> where |X| is the erasure of the static type of the expression on which getClass is called. For example, no cast is required in this code fragment:\n\n Number n = 0; \n Class<? extends Number> c = n.getClass(); \n\n * Returns:\n   - The Class object that represents the runtime class of this object.\n * @jls\n   - 15.8.2 Class Literals', u'detail': u'Object', u'label': u'getClass() : Class<?>', u'textEdit': {u'newText': u'getClass', u'range': {u'start': {u'line': 12, u'character': 9}, u'end': {u'line': 12, u'character': 9}}}, u'insertTextFormat': 1}

@gorkem
Copy link
Contributor

gorkem commented Nov 26, 2017

textEdit is a more precise completion text that requires additional computation. We actually calculate things like auto-imports on resolve. I do not think it will be good to do that computation for every completion item. We can potentially remove insertText if it is confusing the clients. As you have pointed insertText is not enough for some completions and probably something of a left over before the days that textEdit was introduced to the protocol.

@fbricon
Copy link
Contributor

fbricon commented Nov 26, 2017

We used to generate the textedits during the textDocument/completion call, but it was very slow and didn't scale for large result sets.
I wish the protocol was updated to allow textedits to be computed on resolve, as per

If computing full completion items is expensive, servers can additionally provide a handler for the completion item resolve request ('completionItem/resolve')

For now, I think we could try to return a much smaller resultset instead (eg. max 10), with the isIncomplete flag set to true, but fully resolved (textedits wise).

@aeschli, @egamma WDYT?

fbricon added a commit to fbricon/eclipse.jdt.ls that referenced this issue Dec 16, 2019
TextEdits need to be computed during the completion call, but this can be extremely slow
when a large number of results is returned. This PR tries to mitigate the issue by returning
a partial result list and marking the results as incomplete. Smaller payload means computing
Textedits is now more affordable.
Hopefully the UX should be improved as well since completion queries will return faster too.
The number of completion results is configurable with the java.completion.maxResults preference
(defaults to 50).
Setting 0 will disable the limit and return all results. Be aware the performance will be very
negatively impacted as textEdits for all results will be computed eagerly (can be thousands of results).

Fixes eclipse-jdtls#465

Signed-off-by: Fred Bricon <[email protected]>
fbricon added a commit to fbricon/eclipse.jdt.ls that referenced this issue Dec 16, 2019
TextEdits need to be computed during the completion call, but this can be extremely slow
when a large number of results is returned. This change tries to mitigate the issue by returning
a partial result list and marking the results as incomplete. Smaller payload means computing
Textedits is now more affordable.
Hopefully the UX should be improved as well since completion queries will return faster too.
The number of completion results is configurable with the java.completion.maxResults preference
(defaults to 50).
Setting 0 will disable the limit and return all results. Be aware the performance will be very
negatively impacted as textEdits for all results will be computed eagerly (can be thousands of results).

Fixes eclipse-jdtls#465

Signed-off-by: Fred Bricon <[email protected]>
fbricon added a commit that referenced this issue Dec 17, 2019
TextEdits need to be computed during the completion call, but this can be extremely slow
when a large number of results is returned. This change tries to mitigate the issue by returning
a partial result list and marking the results as incomplete. Smaller payload means computing
Textedits is now more affordable.
Hopefully the UX should be improved as well since completion queries will return faster too.
The number of completion results is configurable with the java.completion.maxResults preference
(defaults to 50).
Setting 0 will disable the limit and return all results. Be aware the performance will be very
negatively impacted as textEdits for all results will be computed eagerly (can be thousands of results).

Fixes #465

Signed-off-by: Fred Bricon <[email protected]>
@fbricon fbricon added this to the Mid December 2019 milestone Dec 19, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants