LSP: support WorkDoneProgressOptions in server capabilities

These options indicate whether a server provides extra messages to track
the status of specific requests.

Change-Id: I3fb78f7fa7144a5a9418b32cb5b33d55b668c484
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
David Schulz
2021-02-02 07:34:15 +01:00
parent aec908180d
commit 7521334261
9 changed files with 270 additions and 68 deletions

View File

@@ -625,8 +625,13 @@ void Client::cursorPositionChanged(TextEditor::TextEditorWidget *widget)
m_dynamicCapabilities.option(DocumentHighlightsRequest::methodName));
if (!option.filterApplies(widget->textDocument()->filePath()))
return;
} else if (!m_serverCapabilities.documentHighlightProvider().value_or(false)) {
return;
} else {
Utils::optional<Utils::variant<bool, WorkDoneProgressOptions>> provider
= m_serverCapabilities.documentHighlightProvider();
if (!provider.has_value())
return;
if (Utils::holds_alternative<bool>(*provider) && !Utils::get<bool>(*provider))
return;
}
auto runningRequest = m_highlightRequests.find(uri);
@@ -1233,9 +1238,13 @@ void Client::initializeCallback(const InitializeRequest::Response &initResponse)
qCDebug(LOGLSPCLIENT) << "language server " << m_displayName << " initialized";
m_state = Initialized;
sendContent(InitializeNotification(InitializedParams()));
if (m_dynamicCapabilities.isRegistered(DocumentSymbolsRequest::methodName)
.value_or(capabilities().documentSymbolProvider().value_or(false))) {
TextEditor::IOutlineWidgetFactory::updateOutline();
Utils::optional<Utils::variant<bool, WorkDoneProgressOptions>> documentSymbolProvider
= capabilities().documentSymbolProvider();
if (documentSymbolProvider.has_value()) {
if (!Utils::holds_alternative<bool>(*documentSymbolProvider)
|| Utils::get<bool>(*documentSymbolProvider)) {
TextEditor::IOutlineWidgetFactory::updateOutline();
}
}
for (auto it = m_openedDocument.cbegin(); it != m_openedDocument.cend(); ++it)

View File

@@ -84,8 +84,13 @@ QFutureWatcher<ChangeSet> *LanguageClientFormatter::format(
&& !option.filterApplies(filePath, Utils::mimeTypeForName(m_document->mimeType()))) {
return nullptr;
}
} else if (!m_client->capabilities().documentRangeFormattingProvider().value_or(false)) {
return nullptr;
} else {
const Utils::optional<Utils::variant<bool, WorkDoneProgressOptions>> &provider
= m_client->capabilities().documentRangeFormattingProvider();
if (!provider.has_value())
return nullptr;
if (Utils::holds_alternative<bool>(*provider) && !Utils::get<bool>(*provider))
return nullptr;
}
DocumentRangeFormattingParams params;
const DocumentUri uri = DocumentUri::fromFilePath(filePath);

View File

@@ -74,7 +74,11 @@ void HoverHandler::identifyMatch(TextEditor::TextEditorWidget *editorWidget,
return;
}
bool sendMessage = m_client->capabilities().hoverProvider().value_or(false);
const Utils::optional<Utils::variant<bool, WorkDoneProgressOptions>> &provider
= m_client->capabilities().hoverProvider();
bool sendMessage = provider.has_value();
if (sendMessage && Utils::holds_alternative<bool>(*provider))
sendMessage = Utils::get<bool>(*provider);
if (Utils::optional<bool> registered = m_client->dynamicCapabilities().isRegistered(
HoverRequest::methodName)) {
sendMessage = registered.value();

View File

@@ -234,7 +234,13 @@ bool LanguageClientOutlineWidgetFactory::clientSupportsDocumentSymbols(
return !options.isValid(nullptr)
|| options.filterApplies(doc->filePath(), Utils::mimeTypeForName(doc->mimeType()));
}
return client->capabilities().documentSymbolProvider().value_or(false);
const Utils::optional<Utils::variant<bool, WorkDoneProgressOptions>> &provider
= client->capabilities().documentSymbolProvider();
if (!provider.has_value())
return false;
if (Utils::holds_alternative<bool>(*provider))
return Utils::get<bool>(*provider);
return true;
}
bool LanguageClientOutlineWidgetFactory::supportsEditor(Core::IEditor *editor) const

View File

@@ -46,7 +46,7 @@ template<typename Request>
static void sendTextDocumentPositionParamsRequest(Client *client,
const Request &request,
const DynamicCapabilities &dynamicCapabilities,
const Utils::optional<bool> &serverCapability)
const ServerCapabilities &serverCapability)
{
if (!request.isValid(nullptr))
return;
@@ -62,7 +62,11 @@ static void sendTextDocumentPositionParamsRequest(Client *client,
else
sendMessage = supportedFile;
} else {
sendMessage = serverCapability.value_or(sendMessage) && supportedFile;
const Utils::optional<Utils::variant<bool, WorkDoneProgressOptions>> &provider
= serverCapability.referencesProvider();
sendMessage = provider.has_value();
if (sendMessage && Utils::holds_alternative<bool>(*provider))
sendMessage = Utils::get<bool>(*provider);
}
if (sendMessage)
client->sendContent(request);
@@ -121,7 +125,7 @@ void SymbolSupport::findLinkAt(TextEditor::TextDocument *document,
sendTextDocumentPositionParamsRequest(m_client,
request,
m_client->dynamicCapabilities(),
m_client->capabilities().referencesProvider());
m_client->capabilities());
}
@@ -230,7 +234,7 @@ void SymbolSupport::findUsages(TextEditor::TextDocument *document, const QTextCu
sendTextDocumentPositionParamsRequest(m_client,
request,
m_client->dynamicCapabilities(),
m_client->capabilities().referencesProvider());
m_client->capabilities());
}
static bool supportsRename(Client *client,

View File

@@ -221,15 +221,19 @@ void WorkspaceLocatorFilter::prepareSearch(const QString &entry)
QMutexLocker locker(&m_mutex);
for (auto client : Utils::filtered(LanguageClientManager::clients(), &Client::reachable)) {
if (client->capabilities().workspaceSymbolProvider().value_or(false)) {
WorkspaceSymbolRequest request(params);
request.setResponseCallback(
[this, client](const WorkspaceSymbolRequest::Response &response) {
handleResponse(client, response);
});
m_pendingRequests[client] = request.id();
client->sendContent(request);
}
Utils::optional<Utils::variant<bool, WorkDoneProgressOptions>> capability
= client->capabilities().workspaceSymbolProvider();
if (!capability.has_value())
continue;
if (Utils::holds_alternative<bool>(*capability) && !Utils::get<bool>(*capability))
continue;
WorkspaceSymbolRequest request(params);
request.setResponseCallback(
[this, client](const WorkspaceSymbolRequest::Response &response) {
handleResponse(client, response);
});
m_pendingRequests[client] = request.id();
client->sendContent(request);
}
}