diff options
author | Filippo Cucchetto <filippocucchetto@gmail.com> | 2019-11-05 12:33:42 +0100 |
---|---|---|
committer | Filippo Cucchetto <filippocucchetto@gmail.com> | 2019-11-11 11:15:57 +0000 |
commit | a5044727900b3db78746ae17f72d20da1fd3a8ca (patch) | |
tree | 8003ba913b98b2662ef766afe3bf233c4500ee7d | |
parent | b94688035e659d52f9565c0755f8eb029db345a0 (diff) | |
download | qt-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.txt | 1 | ||||
-rw-r--r-- | src/plugins/nim/editor/nimcompletionassistprovider.cpp | 14 | ||||
-rw-r--r-- | src/plugins/nim/editor/nimeditorfactory.cpp | 9 | ||||
-rw-r--r-- | src/plugins/nim/editor/nimtexteditorwidget.cpp | 109 | ||||
-rw-r--r-- | src/plugins/nim/editor/nimtexteditorwidget.h | 49 | ||||
-rw-r--r-- | src/plugins/nim/nim.pro | 2 | ||||
-rw-r--r-- | src/plugins/nim/nim.qbs | 1 | ||||
-rw-r--r-- | src/plugins/nim/suggest/client.cpp | 38 | ||||
-rw-r--r-- | src/plugins/nim/suggest/client.h | 17 | ||||
-rw-r--r-- | src/plugins/nim/suggest/clientrequests.cpp | 6 | ||||
-rw-r--r-- | src/plugins/nim/suggest/clientrequests.h | 26 | ||||
-rw-r--r-- | src/plugins/nim/suggest/nimsuggest.cpp | 9 | ||||
-rw-r--r-- | src/plugins/nim/suggest/nimsuggest.h | 7 |
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); |