summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFilippo Cucchetto <filippocucchetto@gmail.com>2019-11-05 12:33:42 +0100
committerFilippo Cucchetto <filippocucchetto@gmail.com>2019-11-11 11:15:57 +0000
commita5044727900b3db78746ae17f72d20da1fd3a8ca (patch)
tree8003ba913b98b2662ef766afe3bf233c4500ee7d
parentb94688035e659d52f9565c0755f8eb029db345a0 (diff)
downloadqt-creator-a5044727900b3db78746ae17f72d20da1fd3a8ca.tar.gz
Nim: Add support for goto field under cursor
Change-Id: Ic0cce41d2c3d8dc9bcc9ccd07c3943fd0b2659f9 Reviewed-by: hjk <hjk@qt.io>
-rw-r--r--src/plugins/nim/CMakeLists.txt1
-rw-r--r--src/plugins/nim/editor/nimcompletionassistprovider.cpp14
-rw-r--r--src/plugins/nim/editor/nimeditorfactory.cpp9
-rw-r--r--src/plugins/nim/editor/nimtexteditorwidget.cpp109
-rw-r--r--src/plugins/nim/editor/nimtexteditorwidget.h49
-rw-r--r--src/plugins/nim/nim.pro2
-rw-r--r--src/plugins/nim/nim.qbs1
-rw-r--r--src/plugins/nim/suggest/client.cpp38
-rw-r--r--src/plugins/nim/suggest/client.h17
-rw-r--r--src/plugins/nim/suggest/clientrequests.cpp6
-rw-r--r--src/plugins/nim/suggest/clientrequests.h26
-rw-r--r--src/plugins/nim/suggest/nimsuggest.cpp9
-rw-r--r--src/plugins/nim/suggest/nimsuggest.h7
13 files changed, 237 insertions, 51 deletions
diff --git a/src/plugins/nim/CMakeLists.txt b/src/plugins/nim/CMakeLists.txt
index 2601c60288..bee1b4ffbe 100644
--- a/src/plugins/nim/CMakeLists.txt
+++ b/src/plugins/nim/CMakeLists.txt
@@ -5,6 +5,7 @@ add_qtc_plugin(Nim
editor/nimeditorfactory.cpp editor/nimeditorfactory.h
editor/nimhighlighter.cpp editor/nimhighlighter.h
editor/nimindenter.cpp editor/nimindenter.h
+ editor/nimtexteditorwidget.cpp editor/nimtexteditorwidget.h
nim.qrc
nimconstants.h
nimplugin.cpp nimplugin.h
diff --git a/src/plugins/nim/editor/nimcompletionassistprovider.cpp b/src/plugins/nim/editor/nimcompletionassistprovider.cpp
index 9fcf30c4b0..9a808ff9d5 100644
--- a/src/plugins/nim/editor/nimcompletionassistprovider.cpp
+++ b/src/plugins/nim/editor/nimcompletionassistprovider.cpp
@@ -119,12 +119,12 @@ private:
std::unique_ptr<QTemporaryFile> dirtyFile = writeDirtyFile(interface);
QTC_ASSERT(dirtyFile, return);
- std::shared_ptr<Suggest::SugRequest> request = sendRequest(interface,
+ std::shared_ptr<Suggest::NimSuggestClientRequest> request = sendRequest(interface,
suggest,
dirtyFile->fileName(),
pos);
QTC_ASSERT(request, return);
- connect(request.get(), &Suggest::SugRequest::finished, this,
+ connect(request.get(), &Suggest::NimSuggestClientRequest::finished, this,
&NimCompletionAssistProcessor::onRequestFinished);
m_pos = pos;
@@ -162,10 +162,10 @@ private:
return Nim::Suggest::NimSuggestCache::instance().get(filename);
}
- static std::shared_ptr<Suggest::SugRequest> sendRequest(const AssistInterface *interface,
- Suggest::NimSuggest *suggest,
- QString dirtyFile,
- int pos)
+ static std::shared_ptr<Suggest::NimSuggestClientRequest> sendRequest(const AssistInterface *interface,
+ Suggest::NimSuggest *suggest,
+ QString dirtyFile,
+ int pos)
{
int line = 0, column = 0;
Utils::Text::convertPosition(interface->textDocument(), pos, &line, &column);
@@ -256,7 +256,7 @@ private:
bool m_running = false;
int m_pos = -1;
std::weak_ptr<Suggest::NimSuggest> m_suggest;
- std::shared_ptr<Suggest::SugRequest> m_request;
+ std::shared_ptr<Suggest::NimSuggestClientRequest> m_request;
std::unique_ptr<QTemporaryFile> m_dirtyFile;
const TextEditor::AssistInterface *m_interface = nullptr;
};
diff --git a/src/plugins/nim/editor/nimeditorfactory.cpp b/src/plugins/nim/editor/nimeditorfactory.cpp
index c6f4f17dff..48a3631162 100644
--- a/src/plugins/nim/editor/nimeditorfactory.cpp
+++ b/src/plugins/nim/editor/nimeditorfactory.cpp
@@ -30,6 +30,7 @@
#include "../nimconstants.h"
#include "../nimplugin.h"
+#include "nimtexteditorwidget.h"
#include <texteditor/texteditoractionhandler.h>
#include <texteditor/texteditorconstants.h>
@@ -50,12 +51,10 @@ NimEditorFactory::NimEditorFactory()
setEditorActionHandlers(TextEditorActionHandler::Format
| TextEditorActionHandler::UnCommentSelection
- | TextEditorActionHandler::UnCollapseAll);
-
+ | TextEditorActionHandler::UnCollapseAll
+ | TextEditorActionHandler::FollowSymbolUnderCursor);
setEditorWidgetCreator([]{
- auto result = new TextEditorWidget();
- result->setLanguageSettingsId(Nim::Constants::C_NIMLANGUAGE_ID);
- return result;
+ return new NimTextEditorWidget();
});
setDocumentCreator([]() {
return new TextDocument(Constants::C_NIMEDITOR_ID);
diff --git a/src/plugins/nim/editor/nimtexteditorwidget.cpp b/src/plugins/nim/editor/nimtexteditorwidget.cpp
new file mode 100644
index 0000000000..56d8dfacb2
--- /dev/null
+++ b/src/plugins/nim/editor/nimtexteditorwidget.cpp
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) Filippo Cucchetto <filippocucchetto@gmail.com>
+** Contact: http://www.qt.io/licensing
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "nimtexteditorwidget.h"
+#include "nimconstants.h"
+#include "suggest/nimsuggestcache.h"
+#include "suggest/nimsuggest.h"
+
+#include <texteditor/textdocument.h>
+#include <texteditor/codeassist/assistinterface.h>
+#include <utils/qtcassert.h>
+#include <utils/textutils.h>
+
+#include <QTextStream>
+#include <QTemporaryFile>
+#include <QTextDocument>
+
+using namespace Nim;
+using namespace Suggest;
+
+namespace {
+
+std::unique_ptr<QTemporaryFile> writeDirtyFile(const TextEditor::TextDocument *doc)
+{
+ auto result = std::make_unique<QTemporaryFile>("qtcnim.XXXXXX.nim");
+ QTC_ASSERT(result->open(), return nullptr);
+ QTextStream stream(result.get());
+ stream << doc->plainText();
+ result->close();
+ return result;
+}
+
+}
+
+NimTextEditorWidget::NimTextEditorWidget(QWidget *parent)
+ : TextEditorWidget(parent)
+{
+ setLanguageSettingsId(Nim::Constants::C_NIMLANGUAGE_ID);
+}
+
+void NimTextEditorWidget::findLinkAt(const QTextCursor &c, Utils::ProcessLinkCallback &&processLinkCallback, bool /*resolveTarget*/, bool /*inNextSplit*/)
+{
+ const Utils::FilePath &path = textDocument()->filePath();
+
+ NimSuggest *suggest = NimSuggestCache::instance().get(path);
+ if (!suggest)
+ return processLinkCallback(Utils::Link());
+
+ std::unique_ptr<QTemporaryFile> dirtyFile = writeDirtyFile(textDocument());
+
+ int line = 0, column = 0;
+ Utils::Text::convertPosition(document(), c.position(), &line, &column);
+
+ std::shared_ptr<NimSuggestClientRequest> request = suggest->def(path.toString(),
+ line,
+ column - 1,
+ dirtyFile->fileName());
+
+ if (!request)
+ return processLinkCallback(Utils::Link());
+
+ if (m_request) {
+ QObject::disconnect(m_request.get());
+ m_request = nullptr;
+ }
+
+ if (m_callback)
+ m_callback(Utils::Link());
+
+ m_dirtyFile = std::move(dirtyFile);
+ m_callback = std::move(processLinkCallback);
+ m_request = std::move(request);
+
+ QObject::connect(m_request.get(), &NimSuggestClientRequest::finished, this, &NimTextEditorWidget::onFindLinkFinished);
+}
+
+void NimTextEditorWidget::onFindLinkFinished()
+{
+ QTC_ASSERT(m_request.get() == this->sender(), return);
+ if (m_request->lines().empty()) {
+ m_callback(Utils::Link());
+ return;
+ }
+
+ const Line &line = m_request->lines().front();
+ m_callback(Utils::Link{line.abs_path, line.row, line.column});
+}
diff --git a/src/plugins/nim/editor/nimtexteditorwidget.h b/src/plugins/nim/editor/nimtexteditorwidget.h
new file mode 100644
index 0000000000..8cbc207ebc
--- /dev/null
+++ b/src/plugins/nim/editor/nimtexteditorwidget.h
@@ -0,0 +1,49 @@
+/****************************************************************************
+**
+** Copyright (C) Filippo Cucchetto <filippocucchetto@gmail.com>
+** Contact: http://www.qt.io/licensing
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <texteditor/texteditor.h>
+
+namespace Nim {
+namespace Suggest { class NimSuggestClientRequest; }
+
+class NimTextEditorWidget : public TextEditor::TextEditorWidget
+{
+public:
+ NimTextEditorWidget(QWidget* parent = nullptr);
+
+protected:
+ void findLinkAt(const QTextCursor &, Utils::ProcessLinkCallback &&processLinkCallback, bool resolveTarget, bool inNextSplit);
+
+private:
+ void onFindLinkFinished();
+
+ std::shared_ptr<Nim::Suggest::NimSuggestClientRequest> m_request;
+ Utils::ProcessLinkCallback m_callback;
+ std::unique_ptr<QTemporaryFile> m_dirtyFile;
+};
+
+}
diff --git a/src/plugins/nim/nim.pro b/src/plugins/nim/nim.pro
index 46869353fb..7a49e8f48e 100644
--- a/src/plugins/nim/nim.pro
+++ b/src/plugins/nim/nim.pro
@@ -14,6 +14,7 @@ HEADERS += \
editor/nimcompletionassistprovider.h \
editor/nimhighlighter.h \
editor/nimindenter.h \
+ editor/nimtexteditorwidget.h \
project/nimblebuildconfiguration.h \
project/nimblebuildstep.h \
project/nimblebuildstepwidget.h \
@@ -53,6 +54,7 @@ SOURCES += \
editor/nimcompletionassistprovider.cpp \
editor/nimhighlighter.cpp \
editor/nimindenter.cpp \
+ editor/nimtexteditorwidget.cpp \
project/nimblebuildconfiguration.cpp \
project/nimblebuildstep.cpp \
project/nimbletaskstep.cpp \
diff --git a/src/plugins/nim/nim.qbs b/src/plugins/nim/nim.qbs
index 383999f377..bc9ce4d731 100644
--- a/src/plugins/nim/nim.qbs
+++ b/src/plugins/nim/nim.qbs
@@ -28,6 +28,7 @@ QtcPlugin {
"nimeditorfactory.h", "nimeditorfactory.cpp",
"nimhighlighter.h", "nimhighlighter.cpp",
"nimindenter.h", "nimindenter.cpp",
+ "nimtexteditorwidget.h", "nimtexteditorwidget.cpp",
"nimcompletionassistprovider.h", "nimcompletionassistprovider.cpp"
]
}
diff --git a/src/plugins/nim/suggest/client.cpp b/src/plugins/nim/suggest/client.cpp
index 519bd43925..4c3323cfe7 100644
--- a/src/plugins/nim/suggest/client.cpp
+++ b/src/plugins/nim/suggest/client.cpp
@@ -53,22 +53,38 @@ bool NimSuggestClient::disconnectFromServer()
return true;
}
-std::shared_ptr<SugRequest> NimSuggestClient::sug(const QString &nimFile,
- int line, int column,
- const QString &dirtyFile)
+std::shared_ptr<NimSuggestClientRequest> NimSuggestClient::sug(const QString &nimFile,
+ int line, int column,
+ const QString &dirtyFile)
+{
+ return sendRequest(QLatin1String("sug"), nimFile, line, column, dirtyFile);
+}
+
+std::shared_ptr<NimSuggestClientRequest> NimSuggestClient::def(const QString &nimFile,
+ int line, int column,
+ const QString &dirtyFile)
+{
+ return sendRequest(QLatin1String("def"), nimFile, line, column, dirtyFile);
+}
+
+std::shared_ptr<NimSuggestClientRequest> NimSuggestClient::sendRequest(const QString& type,
+ const QString &nimFile,
+ int line, int column,
+ const QString &dirtyFile)
{
if (!m_socket.isOpen())
return nullptr;
- auto result = std::make_shared<SugRequest>(m_lastMessageId++);
+ auto result = std::make_shared<NimSuggestClientRequest>(m_lastMessageId++);
m_requests.emplace(result->id(), result);
- QByteArray body = QString(R"((call %1 sug ("%2" %3 %4 "%5"))\n)")
- .arg(result->id())
- .arg(nimFile)
- .arg(line).arg(column)
- .arg(dirtyFile)
- .toUtf8();
+ QByteArray body = QString(R"((call %1 %2 ("%3" %4 %5 "%6"))\n)")
+ .arg(result->id())
+ .arg(type)
+ .arg(nimFile)
+ .arg(line).arg(column)
+ .arg(dirtyFile)
+ .toUtf8();
QByteArray length = QString::number(body.size(), 16).rightJustified(6, '0').toUtf8();
QByteArray message = length + body;
@@ -135,7 +151,7 @@ void NimSuggestClient::parsePayload(const char *payload, std::size_t size)
if (it == m_requests.end())
return;
- auto req = std::dynamic_pointer_cast<SugRequest>((*it).second.lock());
+ auto req = std::dynamic_pointer_cast<NimSuggestClientRequest>((*it).second.lock());
if (!req)
return;
diff --git a/src/plugins/nim/suggest/client.h b/src/plugins/nim/suggest/client.h
index 7aeaa826d9..1e61cf3e10 100644
--- a/src/plugins/nim/suggest/client.h
+++ b/src/plugins/nim/suggest/client.h
@@ -49,15 +49,24 @@ public:
bool disconnectFromServer();
- std::shared_ptr<SugRequest> sug(const QString &nimFile,
- int line, int column,
- const QString &dirtyFile);
+ std::shared_ptr<NimSuggestClientRequest> sug(const QString &nimFile,
+ int line, int column,
+ const QString &dirtyFile);
+
+ std::shared_ptr<NimSuggestClientRequest> def(const QString &nimFile,
+ int line, int column,
+ const QString &dirtyFile);
signals:
void connected();
void disconnected();
private:
+ std::shared_ptr<NimSuggestClientRequest> sendRequest(const QString &type,
+ const QString &nimFile,
+ int line, int column,
+ const QString &dirtyFile);
+
void clear();
void onDisconnectedFromServer();
void onReadyRead();
@@ -65,7 +74,7 @@ private:
QTcpSocket m_socket;
quint16 m_port;
- std::unordered_map<quint64, std::weak_ptr<BaseNimSuggestClientRequest>> m_requests;
+ std::unordered_map<quint64, std::weak_ptr<NimSuggestClientRequest>> m_requests;
std::vector<QString> m_lines;
std::vector<char> m_readBuffer;
quint64 m_lastMessageId = 0;
diff --git a/src/plugins/nim/suggest/clientrequests.cpp b/src/plugins/nim/suggest/clientrequests.cpp
index c14d5f2bd2..4b1429a204 100644
--- a/src/plugins/nim/suggest/clientrequests.cpp
+++ b/src/plugins/nim/suggest/clientrequests.cpp
@@ -47,14 +47,10 @@ bool Line::fromString(Line::SymbolKind &type, const std::string &str)
return result;
}
-BaseNimSuggestClientRequest::BaseNimSuggestClientRequest(quint64 id)
+NimSuggestClientRequest::NimSuggestClientRequest(quint64 id)
: m_id(id)
{}
-quint64 BaseNimSuggestClientRequest::id() const
-{
- return m_id;
-}
} // namespace Suggest
} // namespace Nim
diff --git a/src/plugins/nim/suggest/clientrequests.h b/src/plugins/nim/suggest/clientrequests.h
index fccddb6b3d..39c6719929 100644
--- a/src/plugins/nim/suggest/clientrequests.h
+++ b/src/plugins/nim/suggest/clientrequests.h
@@ -93,26 +93,17 @@ public:
QString doc;
};
-class BaseNimSuggestClientRequest : public QObject
+class NimSuggestClientRequest : public QObject
{
Q_OBJECT
public:
- BaseNimSuggestClientRequest(quint64 id);
+ NimSuggestClientRequest(quint64 id);
- quint64 id() const;
-
-signals:
- void finished();
-
-private:
- const quint64 m_id;
-};
-
-class SugRequest : public BaseNimSuggestClientRequest
-{
-public:
- using BaseNimSuggestClientRequest::BaseNimSuggestClientRequest;
+ quint64 id() const
+ {
+ return m_id;
+ }
std::vector<Line> &lines()
{
@@ -124,14 +115,19 @@ public:
return m_lines;
}
+signals:
+ void finished();
+
private:
friend class NimSuggestClient;
+
void setFinished(std::vector<Line> lines)
{
m_lines = std::move(lines);
emit finished();
}
+ const quint64 m_id;
std::vector<Line> m_lines;
};
diff --git a/src/plugins/nim/suggest/nimsuggest.cpp b/src/plugins/nim/suggest/nimsuggest.cpp
index c06db62abf..e51efea054 100644
--- a/src/plugins/nim/suggest/nimsuggest.cpp
+++ b/src/plugins/nim/suggest/nimsuggest.cpp
@@ -76,12 +76,17 @@ bool NimSuggest::isReady() const
return m_ready;
}
-std::shared_ptr<SugRequest> NimSuggest::sug(const QString &filename, int line, int column,
- const QString &dirtyFilename)
+std::shared_ptr<NimSuggestClientRequest> NimSuggest::sug(const QString &filename, int line, int column,
+ const QString &dirtyFilename)
{
return m_ready ? m_client.sug(filename, line, column, dirtyFilename) : nullptr;
}
+std::shared_ptr<NimSuggestClientRequest> NimSuggest::def(const QString &filename, int line, int column, const QString &dirtyFilename)
+{
+ return m_ready ? m_client.def(filename, line, column, dirtyFilename) : nullptr;
+}
+
void NimSuggest::restart()
{
disconnectClient();
diff --git a/src/plugins/nim/suggest/nimsuggest.h b/src/plugins/nim/suggest/nimsuggest.h
index 981c63b628..5043455cec 100644
--- a/src/plugins/nim/suggest/nimsuggest.h
+++ b/src/plugins/nim/suggest/nimsuggest.h
@@ -46,8 +46,11 @@ public:
bool isReady() const;
- std::shared_ptr<SugRequest> sug(const QString &filename, int line, int column,
- const QString &dirtyFilename);
+ std::shared_ptr<NimSuggestClientRequest> sug(const QString &filename, int line, int column,
+ const QString &dirtyFilename);
+
+ std::shared_ptr<NimSuggestClientRequest> def(const QString &filename, int line, int column,
+ const QString &dirtyFilename);
signals:
void readyChanged(bool ready);