LanguageClient: add workspace configuration project settings

Change-Id: I9876773550f3dc566dec05b78f818ca49c930da1
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
David Schulz
2023-08-22 15:28:19 +02:00
parent 2adebd0eb4
commit 2b72ba66ce
5 changed files with 116 additions and 1 deletions

View File

@@ -116,6 +116,13 @@ void LanguageClient::LanguageClientManager::addClient(Client *client)
for (QList<Client *> &clients : managerInstance->m_clientsForSetting) for (QList<Client *> &clients : managerInstance->m_clientsForSetting)
QTC_CHECK(clients.removeAll(client) == 0); QTC_CHECK(clients.removeAll(client) == 0);
}); });
ProjectExplorer::Project *project = client->project();
if (!project)
project = ProjectExplorer::ProjectManager::startupProject();
if (project)
client->updateConfiguration(ProjectSettings(project).workspaceConfiguration());
emit managerInstance->clientAdded(client); emit managerInstance->clientAdded(client);
} }
@@ -390,6 +397,16 @@ const BaseSettings *LanguageClientManager::settingForClient(Client *client)
return nullptr; return nullptr;
} }
void LanguageClientManager::updateWorkspaceConfiguration(const ProjectExplorer::Project *project,
const QJsonValue &json)
{
for (Client *client : managerInstance->m_clients) {
ProjectExplorer::Project *clientProject = client->project();
if (!clientProject || clientProject == project)
client->updateConfiguration(json);
}
}
Client *LanguageClientManager::clientForDocument(TextEditor::TextDocument *document) Client *LanguageClientManager::clientForDocument(TextEditor::TextDocument *document)
{ {
QTC_ASSERT(managerInstance, return nullptr); QTC_ASSERT(managerInstance, return nullptr);

View File

@@ -60,6 +60,9 @@ public:
static void enableClientSettings(const QString &settingsId, bool enable = true); static void enableClientSettings(const QString &settingsId, bool enable = true);
static QList<Client *> clientsForSetting(const BaseSettings *setting); static QList<Client *> clientsForSetting(const BaseSettings *setting);
static const BaseSettings *settingForClient(Client *setting); static const BaseSettings *settingForClient(Client *setting);
static void updateWorkspaceConfiguration(const ProjectExplorer::Project *project,
const QJsonValue &json);
static Client *clientForDocument(TextEditor::TextDocument *document); static Client *clientForDocument(TextEditor::TextDocument *document);
static Client *clientForFilePath(const Utils::FilePath &filePath); static Client *clientForFilePath(const Utils::FilePath &filePath);
static const QList<Client *> clientsForProject(const ProjectExplorer::Project *project); static const QList<Client *> clientsForProject(const ProjectExplorer::Project *project);

View File

@@ -5,11 +5,14 @@
#include "client.h" #include "client.h"
#include "languageclientmanager.h" #include "languageclientmanager.h"
#include "languageclientsettings.h"
#include "languageclienttr.h" #include "languageclienttr.h"
#include <coreplugin/actionmanager/actioncontainer.h> #include <coreplugin/actionmanager/actioncontainer.h>
#include <coreplugin/actionmanager/actionmanager.h> #include <coreplugin/actionmanager/actionmanager.h>
#include <projectexplorer/projectpanelfactory.h>
#include <QAction> #include <QAction>
#include <QMenu> #include <QMenu>
@@ -37,6 +40,13 @@ void LanguageClientPlugin::initialize()
{ {
using namespace Core; using namespace Core;
auto panelFactory = new ProjectExplorer::ProjectPanelFactory;
panelFactory->setPriority(35);
panelFactory->setDisplayName(Tr::tr("Language Server"));
panelFactory->setCreateWidgetFunction(
[](ProjectExplorer::Project *project) { return new ProjectSettingsWidget(project); });
ProjectExplorer::ProjectPanelFactory::registerFactory(panelFactory);
LanguageClientManager::init(); LanguageClientManager::init();
LanguageClientSettings::registerClientType({Constants::LANGUAGECLIENT_STDIO_SETTINGS_ID, LanguageClientSettings::registerClientType({Constants::LANGUAGECLIENT_STDIO_SETTINGS_ID,
Tr::tr("Generic StdIO Language Server"), Tr::tr("Generic StdIO Language Server"),

View File

@@ -36,6 +36,7 @@
#include <QDialogButtonBox> #include <QDialogButtonBox>
#include <QDir> #include <QDir>
#include <QFileInfo> #include <QFileInfo>
#include <QGroupBox>
#include <QHeaderView> #include <QHeaderView>
#include <QJsonDocument> #include <QJsonDocument>
#include <QLabel> #include <QLabel>
@@ -1042,7 +1043,6 @@ TextEditor::BaseTextEditor *jsonEditor()
TextEditorWidget *widget = textEditor->editorWidget(); TextEditorWidget *widget = textEditor->editorWidget();
widget->configureGenericHighlighter(Utils::mimeTypeForName("application/json")); widget->configureGenericHighlighter(Utils::mimeTypeForName("application/json"));
widget->setLineNumbersVisible(false); widget->setLineNumbersVisible(false);
widget->setMarksVisible(false);
widget->setRevisionsVisible(false); widget->setRevisionsVisible(false);
widget->setCodeFoldingSupported(false); widget->setCodeFoldingSupported(false);
QObject::connect(document, &TextDocument::contentsChanged, widget, [document](){ QObject::connect(document, &TextDocument::contentsChanged, widget, [document](){
@@ -1073,4 +1073,63 @@ TextEditor::BaseTextEditor *jsonEditor()
return textEditor; return textEditor;
} }
constexpr const char projectSettingsId[] = "LanguageClient.ProjectSettings";
ProjectSettings::ProjectSettings(ProjectExplorer::Project *project)
: m_project(project)
{
m_json = m_project->namedSettings(projectSettingsId).toByteArray();
}
QJsonValue ProjectSettings::workspaceConfiguration() const
{
const auto doc = QJsonDocument::fromJson(m_json);
if (doc.isObject())
return doc.object();
if (doc.isArray())
return doc.array();
return {};
}
QByteArray ProjectSettings::json() const
{
return m_json;
}
void ProjectSettings::setJson(const QByteArray &json)
{
const QJsonValue oldConfig = workspaceConfiguration();
m_json = json;
m_project->setNamedSettings(projectSettingsId, m_json);
const QJsonValue newConfig = workspaceConfiguration();
if (oldConfig != newConfig)
LanguageClientManager::updateWorkspaceConfiguration(m_project, newConfig);
}
ProjectSettingsWidget::ProjectSettingsWidget(ProjectExplorer::Project *project)
: m_settings(project)
{
setUseGlobalSettingsCheckBoxVisible(false);
setGlobalSettingsId(Constants::LANGUAGECLIENT_SETTINGS_PAGE);
setExpanding(true);
TextEditor::BaseTextEditor *editor = jsonEditor();
editor->document()->setContents(m_settings.json());
auto layout = new QVBoxLayout;
setLayout(layout);
auto group = new QGroupBox(Tr::tr("Language Server Workspace Configuration"));
group->setLayout(new QVBoxLayout);
group->layout()->addWidget(new QLabel(Tr::tr(
"Additional json configuration sent to all running language servers for this project.\n"
"See the documentation of the specific language server for valid settings.")));
group->layout()->addWidget(editor->widget());
layout->addWidget(group);
connect(editor->editorWidget()->textDocument(),
&TextEditor::TextDocument::contentsChanged,
this,
[=]() { m_settings.setJson(editor->document()->contents()); });
}
} // namespace LanguageClient } // namespace LanguageClient

View File

@@ -7,6 +7,8 @@
#include <coreplugin/dialogs/ioptionspage.h> #include <coreplugin/dialogs/ioptionspage.h>
#include <projectexplorer/projectsettingswidget.h>
#include <QAbstractItemModel> #include <QAbstractItemModel>
#include <QCoreApplication> #include <QCoreApplication>
#include <QJsonObject> #include <QJsonObject>
@@ -191,6 +193,30 @@ private:
QLineEdit *m_arguments = nullptr; QLineEdit *m_arguments = nullptr;
}; };
class ProjectSettings
{
public:
explicit ProjectSettings(ProjectExplorer::Project *project);
QJsonValue workspaceConfiguration() const;
QByteArray json() const;
void setJson(const QByteArray &json);
private:
ProjectExplorer::Project *m_project = nullptr;
QByteArray m_json;
};
class ProjectSettingsWidget : public ProjectExplorer::ProjectSettingsWidget
{
public:
explicit ProjectSettingsWidget(ProjectExplorer::Project *project);
private:
ProjectSettings m_settings;
};
LANGUAGECLIENT_EXPORT TextEditor::BaseTextEditor *jsonEditor(); LANGUAGECLIENT_EXPORT TextEditor::BaseTextEditor *jsonEditor();
} // namespace LanguageClient } // namespace LanguageClient