Description
Proposal
Today, VS Code declares the resolveSupport
of CompletionClientCapabilities
as:
"resolveSupport": {
"properties": [
"documentation",
"detail",
"additionalTextEdits"
]
}
The textEdit
is not included since the range
of the textEdit
is a key information to let the client do filtering correctly.
What if we limit the scope to textEdit.newText
only? By doing this, the range is guaranteed to be available in the response of textDocument/completion
. Only the content may have an update in completionItem/resolve
.
Example
For example, when completing the constructor new String(byte[] bytes)
in Java. If we support lazy-resolve the newText
of TextEdit
, we can first return
"textEdit": {
"newText": "String()",
"range": xxx
}
in textDocument/completion
. And then give a more accurate content in completionItem/resolve
:
"textEdit": {
"newText": "String(${1:bytes})",
"range": xxx
}
Even if the item is committed before the resolve result comes, the completion result is still acceptable.
I experimented and found that VS Code already supports update the
newText
oftextEdit
during resolve. If I change the content of it duringcompletionItem/resolve
, VS Code can apply the change correctly.
More background
The completion performance is always a key metric for a Language Server. Specific to Java Language Server, we found that the textEdit
always takes a lot of time to calculate, mostly caused by the calculation of newText
part (Because it requires to append parameter names. When it comes to constructor completion, the situation becomes like a disaster because the server needs to fetch source code from different types to get the parameter names of different constructors). This is how this idea came about.