Commit 55092319 authored by Waqar Ahmed's avatar Waqar Ahmed
Browse files

Implement gotosymboldialog



This is a dialog like quick-open, command bar etc. It allows you to jump
to any symbol within the workspace(your project). This is basically a UI
for the `workspace/symbol` LSP request.
Signed-off-by: Waqar Ahmed's avatarWaqar Ahmed <waqar.17a@gmail.com>
parent e0520558
......@@ -45,6 +45,10 @@ target_sources(
lspsemantichighlighting.cpp
semantic_tokens_legend.cpp
lsptooltip.cpp
gotosymboldialog.cpp
${CMAKE_SOURCE_DIR}/shared/quickdialog.cpp # hud dialog
plugin.qrc
${UI_SOURCES}
)
......
#include "gotosymboldialog.h"
#include "lspclientserver.h"
#include <KTextEditor/MainWindow>
#include <KTextEditor/View>
#include <QStandardItemModel>
static constexpr int SymbolInfoRole = Qt::UserRole + 1;
GotoSymbolHUDDialog::GotoSymbolHUDDialog(KTextEditor::MainWindow *mainWindow, QSharedPointer<LSPClientServer> server)
: QuickDialog(nullptr, mainWindow->window())
, model(new QStandardItemModel(this))
, mainWindow(mainWindow)
, server(std::move(server))
{
m_treeView.setModel(model);
connect(&m_lineEdit, &QLineEdit::textChanged, this, &GotoSymbolHUDDialog::slotTextChanged);
}
void GotoSymbolHUDDialog::slotReturnPressed()
{
auto symbol = m_treeView.currentIndex().data(SymbolInfoRole).value<LSPSymbolInformation>();
if (!symbol.url.isValid() || symbol.url.isEmpty()) {
return;
}
auto v = mainWindow->openUrl(symbol.url);
if (v) {
v->setCursorPosition(symbol.range.start());
}
close();
}
void GotoSymbolHUDDialog::openDialog()
{
updateViewGeometry();
setFocus();
exec();
}
QIcon GotoSymbolHUDDialog::iconForSymbolKind(LSPSymbolKind kind) const
{
switch (kind) {
case LSPSymbolKind::File:
case LSPSymbolKind::Module:
case LSPSymbolKind::Namespace:
case LSPSymbolKind::Package:
return m_icon_pkg;
case LSPSymbolKind::Class:
case LSPSymbolKind::Interface:
return m_icon_class;
case LSPSymbolKind::Enum:
return m_icon_typedef;
case LSPSymbolKind::Method:
case LSPSymbolKind::Function:
case LSPSymbolKind::Constructor:
return m_icon_function;
// all others considered/assumed Variable
case LSPSymbolKind::Variable:
case LSPSymbolKind::Constant:
case LSPSymbolKind::String:
case LSPSymbolKind::Number:
case LSPSymbolKind::Property:
case LSPSymbolKind::Field:
default:
return m_icon_var;
}
}
void GotoSymbolHUDDialog::slotTextChanged(const QString &text)
{
/**
* empty text can lead to return *all* symbols of the workspace, which may choke the dialog
* so we ignore it
*
* Also, at least 2 characters must be there to start getting symbols from the server
*/
if (!server || text.isEmpty() || text.length() < 2) {
return;
}
auto hh = [this](const std::vector<LSPSymbolInformation> &symbols) {
model->clear();
for (const auto &sym : symbols) {
auto item = new QStandardItem(iconForSymbolKind(sym.kind), sym.name);
item->setData(QVariant::fromValue(sym), SymbolInfoRole);
model->appendRow(item);
}
};
server->workspaceSymbol(text, this, hh);
}
#ifndef LSPGOTOSYMBOLDIALOG_H
#define LSPGOTOSYMBOLDIALOG_H
#include <quickdialog.h>
#include "lspclientprotocol.h"
class QStandardItemModel;
class LSPClientServer;
namespace KTextEditor
{
class MainWindow;
}
class GotoSymbolHUDDialog : public QuickDialog
{
public:
GotoSymbolHUDDialog(KTextEditor::MainWindow *mainWindow, QSharedPointer<LSPClientServer> server);
void openDialog();
protected Q_SLOTS:
void slotReturnPressed() override final;
private:
void slotTextChanged(const QString &text);
QIcon iconForSymbolKind(LSPSymbolKind kind) const;
QStandardItemModel *model = nullptr;
KTextEditor::MainWindow *mainWindow;
QSharedPointer<LSPClientServer> server;
const QIcon m_icon_pkg = QIcon::fromTheme(QStringLiteral("code-block"));
const QIcon m_icon_class = QIcon::fromTheme(QStringLiteral("code-class"));
const QIcon m_icon_typedef = QIcon::fromTheme(QStringLiteral("code-typedef"));
const QIcon m_icon_function = QIcon::fromTheme(QStringLiteral("code-function"));
const QIcon m_icon_var = QIcon::fromTheme(QStringLiteral("code-variable"));
};
#endif
......@@ -5,6 +5,7 @@
*/
#include "lspclientpluginview.h"
#include "gotosymboldialog.h"
#include "lspclientcompletion.h"
#include "lspclienthover.h"
#include "lspclientplugin.h"
......@@ -581,6 +582,9 @@ public:
m_restartAll = actionCollection()->addAction(QStringLiteral("lspclient_restart_all"), this, &self_type::restartAll);
m_restartAll->setText(i18n("Restart All LSP Servers"));
auto act = actionCollection()->addAction(QStringLiteral("lspclient_goto_workspace_symbol"), this, &self_type::gotoWorkSpaceSymbol);
act->setShortcut(Qt::ALT | Qt::CTRL | Qt::Key_P);
// popup menu
auto menu = new KActionMenu(i18n("LSP Client"), this);
actionCollection()->addAction(QStringLiteral("popup_lspclient"), menu);
......@@ -1957,6 +1961,17 @@ public:
server->clangdSwitchSourceHeader(document->url(), this, h);
}
void gotoWorkSpaceSymbol()
{
KTextEditor::View *activeView = m_mainWindow->activeView();
auto server = m_serverManager->findServer(activeView);
if (!server) {
return;
}
GotoSymbolHUDDialog dialog(m_mainWindow, server);
dialog.openDialog();
}
static QStandardItem *getItem(const QStandardItemModel &model, const QUrl &url)
{
auto l = model.findItems(url.toLocalFile());
......
......@@ -194,6 +194,7 @@ struct LSPSymbolInformation {
LSPSymbolTag tags;
QList<LSPSymbolInformation> children;
};
Q_DECLARE_METATYPE(LSPSymbolInformation)
enum class LSPCompletionItemKind {
Text = 1,
......
......@@ -19,6 +19,7 @@
#include <QJsonObject>
#include <QTime>
#include <QtEndian>
#include <iostream>
#include <utility>
// good/bad old school; allows easier concatenate
......
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