forked from qt-creator/qt-creator
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:
@@ -418,6 +418,8 @@ void SemanticTokenSupport::highlight(const Utils::FilePath &filePath, bool force
|
|||||||
TextDocument *doc = TextDocument::textDocumentForFilePath(filePath);
|
TextDocument *doc = TextDocument::textDocumentForFilePath(filePath);
|
||||||
if (!doc || LanguageClientManager::clientForDocument(doc) != m_client)
|
if (!doc || LanguageClientManager::clientForDocument(doc) != m_client)
|
||||||
return;
|
return;
|
||||||
|
if (supportedSemanticRequests(doc).testFlag(SemanticRequestType::None))
|
||||||
|
return;
|
||||||
SyntaxHighlighter *highlighter = doc->syntaxHighlighter();
|
SyntaxHighlighter *highlighter = doc->syntaxHighlighter();
|
||||||
if (!highlighter)
|
if (!highlighter)
|
||||||
return;
|
return;
|
||||||
|
@@ -734,7 +734,7 @@ void QmlJSEditorDocumentPrivate::setSourcesWithCapabilities(
|
|||||||
setSemanticWarningSource(QmllsStatus::Source::Qmlls);
|
setSemanticWarningSource(QmllsStatus::Source::Qmlls);
|
||||||
else
|
else
|
||||||
setSemanticWarningSource(QmllsStatus::Source::EmbeddedCodeModel);
|
setSemanticWarningSource(QmllsStatus::Source::EmbeddedCodeModel);
|
||||||
if (cap.semanticTokensProvider())
|
if (cap.semanticTokensProvider() && settings().enableQmllsSemanticHighlighting())
|
||||||
setSemanticHighlightSource(QmllsStatus::Source::Qmlls);
|
setSemanticHighlightSource(QmllsStatus::Source::Qmlls);
|
||||||
else
|
else
|
||||||
setSemanticHighlightSource(QmllsStatus::Source::EmbeddedCodeModel);
|
setSemanticHighlightSource(QmllsStatus::Source::EmbeddedCodeModel);
|
||||||
@@ -765,8 +765,14 @@ void QmlJSEditorDocumentPrivate::settingsChanged()
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
FilePath newQmlls = qmllsForFile(q->filePath(), ModelManagerInterface::instance());
|
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;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
using namespace LanguageClient;
|
using namespace LanguageClient;
|
||||||
m_qmllsStatus.qmllsPath = newQmlls;
|
m_qmllsStatus.qmllsPath = newQmlls;
|
||||||
@@ -788,6 +794,7 @@ void QmlJSEditorDocumentPrivate::settingsChanged()
|
|||||||
if (client == oldClient)
|
if (client == oldClient)
|
||||||
shouldActivate = true;
|
shouldActivate = true;
|
||||||
}
|
}
|
||||||
|
client->updateQmllsSemanticHighlightingCapability();
|
||||||
switch (client->state()) {
|
switch (client->state()) {
|
||||||
case Client::State::Uninitialized:
|
case Client::State::Uninitialized:
|
||||||
case Client::State::InitializeRequested:
|
case Client::State::InitializeRequested:
|
||||||
|
@@ -61,6 +61,7 @@ const char USE_GLOBAL_SETTINGS[] = "QmlJSEditor.UseGlobalSettings";
|
|||||||
const char USE_QMLLS[] = "QmlJSEditor.UseQmlls";
|
const char USE_QMLLS[] = "QmlJSEditor.UseQmlls";
|
||||||
const char USE_LATEST_QMLLS[] = "QmlJSEditor.UseLatestQmlls";
|
const char USE_LATEST_QMLLS[] = "QmlJSEditor.UseLatestQmlls";
|
||||||
const char IGNORE_MINIMUM_QMLLS_VERSION[] = "QmlJSEditor.IgnoreMinimumQmllsVersion";
|
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 DISABLE_BUILTIN_CODEMODEL[] = "QmlJSEditor.DisableBuiltinCodemodel";
|
||||||
const char GENERATE_QMLLS_INI_FILES[] = "QmlJSEditor.GenerateQmllsIniFiles";
|
const char GENERATE_QMLLS_INI_FILES[] = "QmlJSEditor.GenerateQmllsIniFiles";
|
||||||
const char UIQML_OPEN_MODE[] = "QmlJSEditor.openUiQmlMode";
|
const char UIQML_OPEN_MODE[] = "QmlJSEditor.openUiQmlMode";
|
||||||
@@ -150,6 +151,7 @@ void QmllsSettingsManager::checkForChanges()
|
|||||||
&& m_useLatestQmlls == newSettings.useLatestQmlls()
|
&& m_useLatestQmlls == newSettings.useLatestQmlls()
|
||||||
&& m_disableBuiltinCodemodel == newSettings.disableBuiltinCodemodel()
|
&& m_disableBuiltinCodemodel == newSettings.disableBuiltinCodemodel()
|
||||||
&& m_generateQmllsIniFiles == newSettings.generateQmllsIniFiles()
|
&& m_generateQmllsIniFiles == newSettings.generateQmllsIniFiles()
|
||||||
|
&& m_enableQmllsSemanticHighlighting == newSettings.enableQmllsSemanticHighlighting()
|
||||||
&& newLatest == m_latestQmlls)
|
&& newLatest == m_latestQmlls)
|
||||||
return;
|
return;
|
||||||
qCDebug(qmllsLog) << "qmlls settings changed:" << newSettings.useQmlls()
|
qCDebug(qmllsLog) << "qmlls settings changed:" << newSettings.useQmlls()
|
||||||
@@ -160,6 +162,7 @@ void QmllsSettingsManager::checkForChanges()
|
|||||||
m_useQmlls = newSettings.useQmlls();
|
m_useQmlls = newSettings.useQmlls();
|
||||||
m_useLatestQmlls = newSettings.useLatestQmlls();
|
m_useLatestQmlls = newSettings.useLatestQmlls();
|
||||||
m_disableBuiltinCodemodel = newSettings.disableBuiltinCodemodel();
|
m_disableBuiltinCodemodel = newSettings.disableBuiltinCodemodel();
|
||||||
|
m_enableQmllsSemanticHighlighting = newSettings.enableQmllsSemanticHighlighting();
|
||||||
m_generateQmllsIniFiles = newSettings.generateQmllsIniFiles();
|
m_generateQmllsIniFiles = newSettings.generateQmllsIniFiles();
|
||||||
}
|
}
|
||||||
emit settingsChanged();
|
emit settingsChanged();
|
||||||
@@ -263,6 +266,10 @@ QmlJsEditingSettings::QmlJsEditingSettings()
|
|||||||
Tr::tr("Allow versions below Qt %1")
|
Tr::tr("Allow versions below Qt %1")
|
||||||
.arg(QmlJsEditingSettings::mininumQmllsVersion.toString()));
|
.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.setSettingsKey(group, CUSTOM_COMMAND);
|
||||||
useCustomFormatCommand.setLabelText(
|
useCustomFormatCommand.setLabelText(
|
||||||
Tr::tr("Use custom command instead of built-in formatter"));
|
Tr::tr("Use custom command instead of built-in formatter"));
|
||||||
@@ -296,6 +303,7 @@ QmlJsEditingSettings::QmlJsEditingSettings()
|
|||||||
disableBuiltinCodemodel.setEnabler(&useQmlls);
|
disableBuiltinCodemodel.setEnabler(&useQmlls);
|
||||||
generateQmllsIniFiles.setEnabler(&useQmlls);
|
generateQmllsIniFiles.setEnabler(&useQmlls);
|
||||||
ignoreMinimumQmllsVersion.setEnabler(&useQmlls);
|
ignoreMinimumQmllsVersion.setEnabler(&useQmlls);
|
||||||
|
enableQmllsSemanticHighlighting.setEnabler(&useQmlls);
|
||||||
formatCommand.setEnabler(&useCustomFormatCommand);
|
formatCommand.setEnabler(&useCustomFormatCommand);
|
||||||
formatCommandOptions.setEnabler(&useCustomFormatCommand);
|
formatCommandOptions.setEnabler(&useCustomFormatCommand);
|
||||||
}
|
}
|
||||||
@@ -422,6 +430,7 @@ public:
|
|||||||
s.useQmlls,
|
s.useQmlls,
|
||||||
s.ignoreMinimumQmllsVersion,
|
s.ignoreMinimumQmllsVersion,
|
||||||
s.disableBuiltinCodemodel,
|
s.disableBuiltinCodemodel,
|
||||||
|
s.enableQmllsSemanticHighlighting,
|
||||||
s.useLatestQmlls,
|
s.useLatestQmlls,
|
||||||
s.generateQmllsIniFiles
|
s.generateQmllsIniFiles
|
||||||
},
|
},
|
||||||
|
@@ -34,6 +34,7 @@ public:
|
|||||||
Utils::BoolAspect useQmlls{this};
|
Utils::BoolAspect useQmlls{this};
|
||||||
Utils::BoolAspect useLatestQmlls{this};
|
Utils::BoolAspect useLatestQmlls{this};
|
||||||
Utils::BoolAspect ignoreMinimumQmllsVersion{this};
|
Utils::BoolAspect ignoreMinimumQmllsVersion{this};
|
||||||
|
Utils::BoolAspect enableQmllsSemanticHighlighting{this};
|
||||||
Utils::BoolAspect disableBuiltinCodemodel{this};
|
Utils::BoolAspect disableBuiltinCodemodel{this};
|
||||||
Utils::BoolAspect generateQmllsIniFiles{this};
|
Utils::BoolAspect generateQmllsIniFiles{this};
|
||||||
Utils::SelectionAspect uiQmlOpenMode{this};
|
Utils::SelectionAspect uiQmlOpenMode{this};
|
||||||
@@ -67,6 +68,7 @@ private:
|
|||||||
bool m_useLatestQmlls = false;
|
bool m_useLatestQmlls = false;
|
||||||
bool m_disableBuiltinCodemodel = false;
|
bool m_disableBuiltinCodemodel = false;
|
||||||
bool m_generateQmllsIniFiles = false;
|
bool m_generateQmllsIniFiles = false;
|
||||||
|
bool m_enableQmllsSemanticHighlighting = false;
|
||||||
Utils::FilePath m_latestQmlls;
|
Utils::FilePath m_latestQmlls;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#include "qmljseditorconstants.h"
|
#include "qmljseditorconstants.h"
|
||||||
#include "qmljseditortr.h"
|
#include "qmljseditortr.h"
|
||||||
|
#include "qmljseditorsettings.h"
|
||||||
|
|
||||||
#include <languageclient/languageclientinterface.h>
|
#include <languageclient/languageclientinterface.h>
|
||||||
#include <languageclient/languageclientmanager.h>
|
#include <languageclient/languageclientmanager.h>
|
||||||
@@ -82,6 +83,30 @@ QMap<QString, int> QmllsClient::semanticTokenTypesMap()
|
|||||||
return result;
|
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)
|
QmllsClient::QmllsClient(StdIOClientInterface *interface)
|
||||||
: Client(interface)
|
: Client(interface)
|
||||||
{
|
{
|
||||||
@@ -162,6 +187,7 @@ QmllsClient::~QmllsClient()
|
|||||||
|
|
||||||
void QmllsClient::startImpl()
|
void QmllsClient::startImpl()
|
||||||
{
|
{
|
||||||
|
updateQmllsSemanticHighlightingCapability();
|
||||||
Client::startImpl();
|
Client::startImpl();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -55,6 +55,7 @@ public:
|
|||||||
|
|
||||||
void startImpl() override;
|
void startImpl() override;
|
||||||
static QmllsClient *clientForQmlls(const Utils::FilePath &qmlls);
|
static QmllsClient *clientForQmlls(const Utils::FilePath &qmlls);
|
||||||
|
void updateQmllsSemanticHighlightingCapability();
|
||||||
private:
|
private:
|
||||||
static QMap<QString, int> semanticTokenTypesMap();
|
static QMap<QString, int> semanticTokenTypesMap();
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user