Commit 5228e657 authored by Christoph Cullmann's avatar Christoph Cullmann 🐮
Browse files

let LSP plugin use new output view

parent c82c6237
......@@ -66,7 +66,6 @@ LSPClientConfigPage::LSPClientConfigPage(QWidget *parent, LSPClientPlugin *plugi
auto ch = [this](int) {
this->changed();
};
connect(ui->comboMessagesSwitch, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, ch);
connect(ui->spinDiagnosticsSize, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, ch);
connect(ui->edtConfigPath, &KUrlRequester::textChanged, this, &LSPClientConfigPage::configUrlChanged);
connect(ui->edtConfigPath, &KUrlRequester::urlSelected, this, &LSPClientConfigPage::configUrlChanged);
......@@ -90,7 +89,6 @@ LSPClientConfigPage::LSPClientConfigPage(QWidget *parent, LSPClientPlugin *plugi
enabled = enabled && ui->chkDiagnosticsHover->isChecked();
ui->spinDiagnosticsSize->setEnabled(enabled);
enabled = ui->chkMessages->isChecked();
ui->comboMessagesSwitch->setEnabled(enabled);
};
connect(this, &LSPClientConfigPage::changed, this, h);
}
......@@ -138,7 +136,6 @@ void LSPClientConfigPage::apply()
m_plugin->m_signatureHelp = ui->chkSignatureHelp->isChecked();
m_plugin->m_messages = ui->chkMessages->isChecked();
m_plugin->m_messagesAutoSwitch = ui->comboMessagesSwitch->currentIndex();
m_plugin->m_configPath = ui->edtConfigPath->url();
......@@ -177,7 +174,6 @@ void LSPClientConfigPage::reset()
ui->chkSignatureHelp->setChecked(m_plugin->m_signatureHelp);
ui->chkMessages->setChecked(m_plugin->m_messages);
ui->comboMessagesSwitch->setCurrentIndex(m_plugin->m_messagesAutoSwitch);
ui->edtConfigPath->setUrl(m_plugin->m_configPath);
......
......@@ -34,7 +34,6 @@ static const QString CONFIG_DIAGNOSTICS_MARK{QStringLiteral("DiagnosticsMark")};
static const QString CONFIG_DIAGNOSTICS_HOVER{QStringLiteral("DiagnosticsHover")};
static const QString CONFIG_DIAGNOSTICS_SIZE{QStringLiteral("DiagnosticsSize")};
static const QString CONFIG_MESSAGES{QStringLiteral("Messages")};
static const QString CONFIG_MESSAGES_AUTO_SWITCH{QStringLiteral("MessagesAutoSwitch")};
static const QString CONFIG_SERVER_CONFIG{QStringLiteral("ServerConfiguration")};
static const QString CONFIG_SEMANTIC_HIGHLIGHTING{QStringLiteral("SemanticHighlighting")};
static const QString CONFIG_SIGNATURE_HELP{QStringLiteral("SignatureHelp")};
......@@ -104,7 +103,6 @@ void LSPClientPlugin::readConfig()
m_diagnosticsHover = config.readEntry(CONFIG_DIAGNOSTICS_HOVER, true);
m_diagnosticsSize = config.readEntry(CONFIG_DIAGNOSTICS_SIZE, 1024);
m_messages = config.readEntry(CONFIG_MESSAGES, true);
m_messagesAutoSwitch = config.readEntry(CONFIG_MESSAGES_AUTO_SWITCH, 1);
m_configPath = config.readEntry(CONFIG_SERVER_CONFIG, QUrl());
m_semanticHighlighting = config.readEntry(CONFIG_SEMANTIC_HIGHLIGHTING, false);
m_signatureHelp = config.readEntry(CONFIG_SIGNATURE_HELP, true);
......@@ -130,7 +128,6 @@ void LSPClientPlugin::writeConfig() const
config.writeEntry(CONFIG_DIAGNOSTICS_HOVER, m_diagnosticsHover);
config.writeEntry(CONFIG_DIAGNOSTICS_SIZE, m_diagnosticsSize);
config.writeEntry(CONFIG_MESSAGES, m_messages);
config.writeEntry(CONFIG_MESSAGES_AUTO_SWITCH, m_messagesAutoSwitch);
config.writeEntry(CONFIG_SERVER_CONFIG, m_configPath);
config.writeEntry(CONFIG_SEMANTIC_HIGHLIGHTING, m_semanticHighlighting);
config.writeEntry(CONFIG_SIGNATURE_HELP, m_signatureHelp);
......
......@@ -48,7 +48,6 @@ public:
bool m_diagnosticsHover = false;
unsigned m_diagnosticsSize = 0;
bool m_messages = false;
int m_messagesAutoSwitch = 0;
bool m_autoHover = false;
bool m_onTypeFormatting = false;
bool m_incrementalSync = false;
......
......@@ -289,6 +289,30 @@ private:
KTextEditor::Range range;
};
class LSPClientPluginViewImpl : public QObject, public KXMLGUIClient
{
Q_OBJECT
typedef LSPClientPluginViewImpl self_type;
KTextEditor::MainWindow *m_mainWindow;
QSharedPointer<LSPClientServerManager> m_serverManager;
QScopedPointer<class LSPClientActionView> m_actionView;
public:
LSPClientPluginViewImpl(LSPClientPlugin *plugin, KTextEditor::MainWindow *mainWin);
~LSPClientPluginViewImpl() override;
Q_SIGNALS:
/**
* Signal for outgoing message, the host application will handle them!
* Will only be handled inside the main windows of this plugin view.
* @param message outgoing message we send to the host application
*/
void message(const QVariantMap &message);
};
class LSPClientActionView : public QObject
{
Q_OBJECT
......@@ -297,7 +321,7 @@ class LSPClientActionView : public QObject
LSPClientPlugin *m_plugin;
KTextEditor::MainWindow *m_mainWindow;
KXMLGUIClient *m_client;
LSPClientPluginViewImpl *m_client;
QSharedPointer<LSPClientServerManager> m_serverManager;
QScopedPointer<LSPClientViewTracker> m_viewTracker;
QScopedPointer<LSPClientCompletion> m_completion;
......@@ -324,8 +348,6 @@ class LSPClientActionView : public QObject
QPointer<QAction> m_diagnosticsHover;
QPointer<QAction> m_diagnosticsSwitch;
QPointer<QAction> m_messages;
QPointer<KSelectAction> m_messagesAutoSwitch;
QPointer<QAction> m_messagesSwitch;
QPointer<QAction> m_closeDynamic;
QPointer<QAction> m_restartServer;
QPointer<QAction> m_restartAll;
......@@ -362,12 +384,6 @@ class LSPClientActionView : public QObject
// and marks
DocumentCollection m_diagnosticsMarks;
using MessagesWidget = QPlainTextEdit;
// messages tab
QPointer<MessagesWidget> m_messagesView;
// widget is either owned here or by tab
QScopedPointer<MessagesWidget> m_messagesViewOwn;
// views on which completions have been registered
QSet<KTextEditor::View *> m_completionViews;
......@@ -410,7 +426,10 @@ class LSPClientActionView : public QObject
};
public:
LSPClientActionView(LSPClientPlugin *plugin, KTextEditor::MainWindow *mainWin, KXMLGUIClient *client, QSharedPointer<LSPClientServerManager> serverManager)
LSPClientActionView(LSPClientPlugin *plugin,
KTextEditor::MainWindow *mainWin,
LSPClientPluginViewImpl *client,
QSharedPointer<LSPClientServerManager> serverManager)
: QObject(mainWin)
, m_plugin(plugin)
, m_mainWindow(mainWin)
......@@ -482,16 +501,6 @@ public:
m_messages = actionCollection()->addAction(QStringLiteral("lspclient_messages"), this, &self_type::displayOptionChanged);
m_messages->setText(i18n("Show messages"));
m_messages->setCheckable(true);
m_messagesAutoSwitch = new KSelectAction(i18n("Switch to messages tab upon message level"), this);
actionCollection()->addAction(QStringLiteral("lspclient_messages_auto_switch"), m_messagesAutoSwitch);
const QStringList list{i18nc("@info", "Never"),
i18nc("@info", "Error"),
i18nc("@info", "Warning"),
i18nc("@info", "Information"),
i18nc("@info", "Log")};
m_messagesAutoSwitch->setItems(list);
m_messagesSwitch = actionCollection()->addAction(QStringLiteral("lspclient_messages_switch"), this, &self_type::switchToMessages);
m_messagesSwitch->setText(i18n("Switch to messages tab"));
// server control and misc actions
m_closeDynamic = actionCollection()->addAction(QStringLiteral("lspclient_close_dynamic"), this, &self_type::closeDynamic);
......@@ -515,7 +524,6 @@ public:
menu->addAction(m_triggerRename);
menu->addSeparator();
menu->addAction(m_diagnosticsSwitch);
menu->addAction(m_messagesSwitch);
menu->addAction(m_closeDynamic);
menu->addSeparator();
menu->addAction(m_restartServer);
......@@ -536,7 +544,6 @@ public:
moreOptions->addAction(m_diagnosticsHover);
moreOptions->addSeparator();
moreOptions->addAction(m_messages);
moreOptions->addAction(m_messagesAutoSwitch);
// sync with plugin settings if updated
connect(m_plugin, &LSPClientPlugin::update, this, &self_type::configUpdated);
......@@ -566,12 +573,6 @@ public:
connect(m_diagnosticsTree, &QTreeView::clicked, this, &self_type::goToItemLocation);
connect(m_diagnosticsTree, &QTreeView::doubleClicked, this, &self_type::triggerCodeAction);
// messages tab
m_messagesView = new QPlainTextEdit();
m_messagesView->setMaximumBlockCount(100);
m_messagesView->setReadOnly(true);
m_messagesViewOwn.reset(m_messagesView);
// track position in view to sync diagnostics list
m_viewTracker.reset(LSPClientViewTracker::new_(plugin, mainWin, 0, 500));
connect(m_viewTracker.data(), &LSPClientViewTracker::newState, this, &self_type::onViewState);
......@@ -760,23 +761,13 @@ public:
m_diagnosticsHighlight->setEnabled(m_diagnostics->isChecked());
m_diagnosticsMark->setEnabled(m_diagnostics->isChecked());
m_diagnosticsHover->setEnabled(m_diagnostics->isChecked());
// messages tab should go first
int messagesIndex = m_tabWidget->indexOf(m_messagesView);
if (m_messages->isChecked() && m_messagesViewOwn) {
m_tabWidget->insertTab(0, m_messagesView, i18nc("@title:tab", "Messages"));
messagesIndex = 0;
m_messagesViewOwn.take();
} else if (!m_messages->isChecked() && !m_messagesViewOwn) {
m_messagesViewOwn.reset(m_messagesView);
m_tabWidget->removeTab(messagesIndex);
messagesIndex = -1;
}
// diagnstics tab next
int diagnosticsIndex = m_tabWidget->indexOf(m_diagnosticsTree);
// setTabEnabled may still show it ... so let's be more forceful
if (m_diagnostics->isChecked() && m_diagnosticsTreeOwn) {
m_diagnosticsTreeOwn.take();
m_tabWidget->insertTab(messagesIndex + 1, m_diagnosticsTree, i18nc("@title:tab", "Diagnostics"));
m_tabWidget->insertTab(0, m_diagnosticsTree, i18nc("@title:tab", "Diagnostics"));
} else if (!m_diagnostics->isChecked() && !m_diagnosticsTreeOwn) {
m_diagnosticsTreeOwn.reset(m_diagnosticsTree);
m_tabWidget->removeTab(diagnosticsIndex);
......@@ -818,9 +809,6 @@ public:
if (m_messages) {
m_messages->setChecked(m_plugin->m_messages);
}
if (m_messagesAutoSwitch) {
m_messagesAutoSwitch->setCurrentItem(m_plugin->m_messagesAutoSwitch);
}
displayOptionChanged();
}
......@@ -1205,7 +1193,7 @@ public:
bool tabCloseRequested(int index)
{
auto widget = m_tabWidget->widget(index);
if (widget != m_diagnosticsTree && widget != m_messagesView) {
if (widget != m_diagnosticsTree) {
if (m_markModel && widget == m_markModel->parent()) {
clearAllLocationMarks();
}
......@@ -1227,12 +1215,6 @@ public:
m_mainWindow->showToolView(m_toolView.data());
}
void switchToMessages()
{
m_tabWidget->setCurrentWidget(m_messagesView);
m_mainWindow->showToolView(m_toolView.data());
}
void closeDynamic()
{
for (int i = 0; i < m_tabWidget->count();) {
......@@ -1988,42 +1970,38 @@ public:
return nullptr;
}
void addMessage(LSPMessageType level, const QString &header, const QString &msg)
void addMessage(LSPMessageType level, const QString &category, const QString &msg)
{
if (!m_messagesView) {
// skip messaging if not enabled
if (!m_messages->isChecked()) {
return;
}
QString lvl = i18nc("@info", "Unknown");
// use generic output view
QVariantMap genericMessage;
genericMessage.insert(QStringLiteral("category"), category);
genericMessage.insert(QStringLiteral("plainText"), msg);
// translate level to the type keys
QString type;
switch (level) {
case LSPMessageType::Error:
lvl = i18nc("@info", "Error");
type = QStringLiteral("Error");
break;
case LSPMessageType::Warning:
lvl = i18nc("@info", "Warning");
type = QStringLiteral("Warning");
break;
case LSPMessageType::Info:
lvl = i18nc("@info", "Information");
type = QStringLiteral("Info");
break;
case LSPMessageType::Log:
lvl = i18nc("@info", "Log");
type = QStringLiteral("Log");
break;
}
genericMessage.insert(QStringLiteral("type"), type);
// let's consider this expert info and use ISO date
auto now = QDateTime::currentDateTime().toString(Qt::ISODate);
auto text = QStringLiteral("[%1] [%2] [%3]\n%4\n").arg(now, lvl, header, msg.trimmed());
m_messagesView->appendPlainText(text);
if (static_cast<int>(level) <= m_messagesAutoSwitch->currentItem()) {
switchToMessages();
} else {
// show arrival of new message
auto index = m_tabWidget->indexOf(m_messagesView);
if (m_tabWidget->currentIndex() != index) {
m_tabWidget->tabBar()->setTabTextColor(index, Qt::gray);
}
}
// host application will handle these message for us, including auto-show settings
Q_EMIT m_client->message(genericMessage);
}
// params type is same for show or log and is treated the same way
......@@ -2031,11 +2009,11 @@ public:
{
// determine server description
auto server = dynamic_cast<LSPClientServer *>(sender());
auto desc = i18nc("@info", "LSP Server");
auto message = params.message;
if (server) {
desc += QStringLiteral(": %1").arg(LSPClientServerManager::serverDescription(server));
message = QStringLiteral("%1\n%2").arg(LSPClientServerManager::serverDescription(server), message);
}
addMessage(params.type, desc, params.message);
addMessage(params.type, i18nc("@info", "LSP Server"), message);
}
void onShowMessage(KTextEditor::Message::MessageType level, const QString &msg)
......@@ -2431,42 +2409,30 @@ public:
}
};
class LSPClientPluginViewImpl : public QObject, public KXMLGUIClient
LSPClientPluginViewImpl::LSPClientPluginViewImpl(LSPClientPlugin *plugin, KTextEditor::MainWindow *mainWin)
: QObject(mainWin)
, m_mainWindow(mainWin)
, m_serverManager(LSPClientServerManager::new_(plugin, mainWin))
{
Q_OBJECT
typedef LSPClientPluginViewImpl self_type;
KTextEditor::MainWindow *m_mainWindow;
QSharedPointer<LSPClientServerManager> m_serverManager;
QScopedPointer<LSPClientActionView> m_actionView;
KXMLGUIClient::setComponentName(QStringLiteral("lspclient"), i18n("LSP Client"));
setXMLFile(QStringLiteral("ui.rc"));
public:
LSPClientPluginViewImpl(LSPClientPlugin *plugin, KTextEditor::MainWindow *mainWin)
: QObject(mainWin)
, m_mainWindow(mainWin)
, m_serverManager(LSPClientServerManager::new_(plugin, mainWin))
{
KXMLGUIClient::setComponentName(QStringLiteral("lspclient"), i18n("LSP Client"));
setXMLFile(QStringLiteral("ui.rc"));
// we need to do this AFTER the setComponentName above
m_actionView.reset(new LSPClientActionView(plugin, mainWin, this, m_serverManager));
// we need to do this AFTER the setComponentName above
m_actionView.reset(new LSPClientActionView(plugin, mainWin, this, m_serverManager));
m_mainWindow->guiFactory()->addClient(this);
}
m_mainWindow->guiFactory()->addClient(this);
}
~LSPClientPluginViewImpl() override
{
// minimize/avoid some surprises;
// safe construction/destruction by separate (helper) objects;
// signals are auto-disconnected when high-level "view" objects are broken down
// so it only remains to clean up lowest level here then prior to removal
m_actionView.reset();
m_serverManager.reset();
m_mainWindow->guiFactory()->removeClient(this);
}
};
LSPClientPluginViewImpl::~LSPClientPluginViewImpl()
{
// minimize/avoid some surprises;
// safe construction/destruction by separate (helper) objects;
// signals are auto-disconnected when high-level "view" objects are broken down
// so it only remains to clean up lowest level here then prior to removal
m_actionView.reset();
m_serverManager.reset();
m_mainWindow->guiFactory()->removeClient(this);
}
QObject *LSPClientPluginView::new_(LSPClientPlugin *plugin, KTextEditor::MainWindow *mainWin)
{
......
......@@ -90,6 +90,13 @@
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="chkMessages">
<property name="text">
<string>Show messages</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
......@@ -135,53 +142,6 @@
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QCheckBox" name="chkMessages">
<property name="text">
<string>Show messages</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_1">
<property name="text">
<string>Switch to messages tab upon level</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="comboMessagesSwitch">
<item>
<property name="text">
<string>Never</string>
</property>
</item>
<item>
<property name="text">
<string>Error</string>
</property>
</item>
<item>
<property name="text">
<string>Warning</string>
</property>
</item>
<item>
<property name="text">
<string>Information</string>
</property>
</item>
<item>
<property name="text">
<string>Log</string>
</property>
</item>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
......
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE gui SYSTEM "kpartgui.dtd">
<gui name="lspclient" library="lspclient" version="9" translationDomain="lspclient">
<gui name="lspclient" library="lspclient" version="10" translationDomain="lspclient">
<MenuBar>
<Menu name="LSPClient Menubar">
<text>LSP Client</text>
......@@ -13,7 +13,6 @@
<Action name="lspclient_rename"/>
<Separator/>
<Action name="lspclient_diagnostic_switch"/>
<Action name="lspclient_messages_switch"/>
<Action name="lspclient_close_dynamic"/>
<Separator/>
<Action name="lspclient_restart_server"/>
......@@ -35,7 +34,6 @@
<Action name="lspclient_diagnostics_hover"/>
<Separator/>
<Action name="lspclient_messages"/>
<Action name="lspclient_messages_auto_switch"/>
</Menu>
</Menu>
</MenuBar>
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment