Make qmlls semantic highlighting optional

Qmlls semantic highlighting in QtC occasionally flickers on editing the
document. Since this might be disturbing to some users, we should be
able to toggle its switch so that they can enable/disable it. By
default, it is disabled.

Add an option in the qml language server preferences to
switch highlighter module.

Add a check in highlighter() to test if there is actually semantic
highlighting request. Otherwise, it is invoked on the initialization of
the language client unconditionally which wouldn't respect the settings.

Task-number: QTCREATORBUG-31215
Change-Id: I1d7df44071053993839860087fb0ab6ede61e145
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
This commit is contained in:
Semih Yavuz
2024-10-28 16:51:52 +01:00
parent db5a39311f
commit a6b2cb67db
6 changed files with 49 additions and 2 deletions

View File

@@ -418,6 +418,8 @@ void SemanticTokenSupport::highlight(const Utils::FilePath &filePath, bool force
TextDocument *doc = TextDocument::textDocumentForFilePath(filePath);
if (!doc || LanguageClientManager::clientForDocument(doc) != m_client)
return;
if (supportedSemanticRequests(doc).testFlag(SemanticRequestType::None))
return;
SyntaxHighlighter *highlighter = doc->syntaxHighlighter();
if (!highlighter)
return;

View File

@@ -734,7 +734,7 @@ void QmlJSEditorDocumentPrivate::setSourcesWithCapabilities(
setSemanticWarningSource(QmllsStatus::Source::Qmlls);
else
setSemanticWarningSource(QmllsStatus::Source::EmbeddedCodeModel);
if (cap.semanticTokensProvider())
if (cap.semanticTokensProvider() && settings().enableQmllsSemanticHighlighting())
setSemanticHighlightSource(QmllsStatus::Source::Qmlls);
else
setSemanticHighlightSource(QmllsStatus::Source::EmbeddedCodeModel);
@@ -765,8 +765,14 @@ void QmlJSEditorDocumentPrivate::settingsChanged()
return;
FilePath newQmlls = qmllsForFile(q->filePath(), ModelManagerInterface::instance());
if (m_qmllsStatus.qmllsPath == newQmlls)
if (m_qmllsStatus.qmllsPath == newQmlls) {
if (QmllsClient *client = QmllsClient::clientForQmlls(newQmlls)) {
client->updateQmllsSemanticHighlightingCapability();
setSourcesWithCapabilities(client->capabilities());
client->activateDocument(q);
}
return;
}
using namespace LanguageClient;
m_qmllsStatus.qmllsPath = newQmlls;
@@ -788,6 +794,7 @@ void QmlJSEditorDocumentPrivate::settingsChanged()
if (client == oldClient)
shouldActivate = true;
}
client->updateQmllsSemanticHighlightingCapability();
switch (client->state()) {
case Client::State::Uninitialized:
case Client::State::InitializeRequested:

View File

@@ -61,6 +61,7 @@ const char USE_GLOBAL_SETTINGS[] = "QmlJSEditor.UseGlobalSettings";
const char USE_QMLLS[] = "QmlJSEditor.UseQmlls";
const char USE_LATEST_QMLLS[] = "QmlJSEditor.UseLatestQmlls";
const char IGNORE_MINIMUM_QMLLS_VERSION[] = "QmlJSEditor.IgnoreMinimumQmllsVersion";
const char USE_QMLLS_SEMANTIC_HIGHLIGHTING[] = "QmlJSEditor.EnableQmllsSemanticHighlighting";
const char DISABLE_BUILTIN_CODEMODEL[] = "QmlJSEditor.DisableBuiltinCodemodel";
const char GENERATE_QMLLS_INI_FILES[] = "QmlJSEditor.GenerateQmllsIniFiles";
const char UIQML_OPEN_MODE[] = "QmlJSEditor.openUiQmlMode";
@@ -150,6 +151,7 @@ void QmllsSettingsManager::checkForChanges()
&& m_useLatestQmlls == newSettings.useLatestQmlls()
&& m_disableBuiltinCodemodel == newSettings.disableBuiltinCodemodel()
&& m_generateQmllsIniFiles == newSettings.generateQmllsIniFiles()
&& m_enableQmllsSemanticHighlighting == newSettings.enableQmllsSemanticHighlighting()
&& newLatest == m_latestQmlls)
return;
qCDebug(qmllsLog) << "qmlls settings changed:" << newSettings.useQmlls()
@@ -160,6 +162,7 @@ void QmllsSettingsManager::checkForChanges()
m_useQmlls = newSettings.useQmlls();
m_useLatestQmlls = newSettings.useLatestQmlls();
m_disableBuiltinCodemodel = newSettings.disableBuiltinCodemodel();
m_enableQmllsSemanticHighlighting = newSettings.enableQmllsSemanticHighlighting();
m_generateQmllsIniFiles = newSettings.generateQmllsIniFiles();
}
emit settingsChanged();
@@ -263,6 +266,10 @@ QmlJsEditingSettings::QmlJsEditingSettings()
Tr::tr("Allow versions below Qt %1")
.arg(QmlJsEditingSettings::mininumQmllsVersion.toString()));
enableQmllsSemanticHighlighting.setSettingsKey(group, USE_QMLLS_SEMANTIC_HIGHLIGHTING);
enableQmllsSemanticHighlighting.setLabelText(
Tr::tr("Enable semantic highlighting (experimental)"));
useCustomFormatCommand.setSettingsKey(group, CUSTOM_COMMAND);
useCustomFormatCommand.setLabelText(
Tr::tr("Use custom command instead of built-in formatter"));
@@ -296,6 +303,7 @@ QmlJsEditingSettings::QmlJsEditingSettings()
disableBuiltinCodemodel.setEnabler(&useQmlls);
generateQmllsIniFiles.setEnabler(&useQmlls);
ignoreMinimumQmllsVersion.setEnabler(&useQmlls);
enableQmllsSemanticHighlighting.setEnabler(&useQmlls);
formatCommand.setEnabler(&useCustomFormatCommand);
formatCommandOptions.setEnabler(&useCustomFormatCommand);
}
@@ -422,6 +430,7 @@ public:
s.useQmlls,
s.ignoreMinimumQmllsVersion,
s.disableBuiltinCodemodel,
s.enableQmllsSemanticHighlighting,
s.useLatestQmlls,
s.generateQmllsIniFiles
},

View File

@@ -34,6 +34,7 @@ public:
Utils::BoolAspect useQmlls{this};
Utils::BoolAspect useLatestQmlls{this};
Utils::BoolAspect ignoreMinimumQmllsVersion{this};
Utils::BoolAspect enableQmllsSemanticHighlighting{this};
Utils::BoolAspect disableBuiltinCodemodel{this};
Utils::BoolAspect generateQmllsIniFiles{this};
Utils::SelectionAspect uiQmlOpenMode{this};
@@ -67,6 +68,7 @@ private:
bool m_useLatestQmlls = false;
bool m_disableBuiltinCodemodel = false;
bool m_generateQmllsIniFiles = false;
bool m_enableQmllsSemanticHighlighting = false;
Utils::FilePath m_latestQmlls;
};

View File

@@ -5,6 +5,7 @@
#include "qmljseditorconstants.h"
#include "qmljseditortr.h"
#include "qmljseditorsettings.h"
#include <languageclient/languageclientinterface.h>
#include <languageclient/languageclientmanager.h>
@@ -82,6 +83,30 @@ QMap<QString, int> QmllsClient::semanticTokenTypesMap()
return result;
}
void QmllsClient::updateQmllsSemanticHighlightingCapability()
{
const QString methodName = QStringLiteral("textDocument/semanticTokens");
if (!QmlJSEditor::Internal::settings().enableQmllsSemanticHighlighting()) {
LanguageServerProtocol::Unregistration unregister;
unregister.setMethod(methodName);
unregister.setId({});
this->unregisterCapabilities({unregister});
} else {
const LanguageServerProtocol::ServerCapabilities &caps = this->capabilities();
const std::optional<LanguageServerProtocol::SemanticTokensOptions> &options
= caps.semanticTokensProvider();
if (options) {
LanguageServerProtocol::Registration registeration;
registeration.setMethod(methodName);
registeration.setId({});
registeration.setRegisterOptions({*options});
this->registerCapabilities({registeration});
} else {
qCWarning(qmllsLog) << "qmlls does not support semantic highlighting";
}
}
}
QmllsClient::QmllsClient(StdIOClientInterface *interface)
: Client(interface)
{
@@ -162,6 +187,7 @@ QmllsClient::~QmllsClient()
void QmllsClient::startImpl()
{
updateQmllsSemanticHighlightingCapability();
Client::startImpl();
}

View File

@@ -55,6 +55,7 @@ public:
void startImpl() override;
static QmllsClient *clientForQmlls(const Utils::FilePath &qmlls);
void updateQmllsSemanticHighlightingCapability();
private:
static QMap<QString, int> semanticTokenTypesMap();
};