forked from qt-creator/qt-creator
Copilot: Add LSP plugin for Copilot
Fixes: QTCREATORBUG-27771 Change-Id: I1249b9a4492427208a70b3e21bf20ac668fc3c50 Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
@@ -100,3 +100,4 @@ add_subdirectory(qnx)
|
||||
add_subdirectory(webassembly)
|
||||
add_subdirectory(mcusupport)
|
||||
add_subdirectory(saferenderer)
|
||||
add_subdirectory(copilot)
|
||||
|
17
src/plugins/copilot/CMakeLists.txt
Normal file
17
src/plugins/copilot/CMakeLists.txt
Normal file
@@ -0,0 +1,17 @@
|
||||
add_qtc_plugin(Copilot
|
||||
SKIP_TRANSLATION
|
||||
PLUGIN_DEPENDS Core LanguageClient
|
||||
SOURCES
|
||||
authwidget.cpp authwidget.h
|
||||
copilotplugin.cpp copilotplugin.h
|
||||
copilotclient.cpp copilotclient.h
|
||||
copilotsettings.cpp copilotsettings.h
|
||||
copilotoptionspage.cpp copilotoptionspage.h
|
||||
copilotoptionspagewidget.cpp copilotoptionspagewidget.h
|
||||
documentwatcher.cpp documentwatcher.h
|
||||
requests/getcompletions.h
|
||||
requests/checkstatus.h
|
||||
requests/signout.h
|
||||
requests/signininitiate.h
|
||||
requests/signinconfirm.h
|
||||
)
|
19
src/plugins/copilot/Copilot.json.in
Normal file
19
src/plugins/copilot/Copilot.json.in
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
\"Name\" : \"Copilot\",
|
||||
\"Version\" : \"$$QTCREATOR_VERSION\",
|
||||
\"CompatVersion\" : \"$$QTCREATOR_COMPAT_VERSION\",
|
||||
\"Experimental\" : true,
|
||||
\"Vendor\" : \"The Qt Company Ltd\",
|
||||
\"Copyright\" : \"(C) $$QTCREATOR_COPYRIGHT_YEAR The Qt Company Ltd\",
|
||||
\"License\" : [ \"Commercial Usage\",
|
||||
\"\",
|
||||
\"Licensees holding valid Qt Commercial licenses may use this plugin in accordance with the Qt 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.\",
|
||||
\"\",
|
||||
\"GNU General Public License Usage\",
|
||||
\"\",
|
||||
\"Alternatively, this plugin 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 plugin. 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.\"
|
||||
],
|
||||
\"Description\" : \"Copilot support\",
|
||||
\"Url\" : \"http://www.qt.io\",
|
||||
$$dependencyList
|
||||
}
|
163
src/plugins/copilot/authwidget.cpp
Normal file
163
src/plugins/copilot/authwidget.cpp
Normal file
@@ -0,0 +1,163 @@
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "authwidget.h"
|
||||
|
||||
#include "copilotclient.h"
|
||||
#include "copilottr.h"
|
||||
|
||||
#include <utils/layoutbuilder.h>
|
||||
#include <utils/stringutils.h>
|
||||
|
||||
#include <languageclient/languageclientmanager.h>
|
||||
|
||||
#include <QDesktopServices>
|
||||
#include <QMessageBox>
|
||||
|
||||
using namespace LanguageClient;
|
||||
|
||||
namespace Copilot {
|
||||
|
||||
bool isCopilotClient(Client *client)
|
||||
{
|
||||
return dynamic_cast<Internal::CopilotClient *>(client) != nullptr;
|
||||
}
|
||||
|
||||
Internal::CopilotClient *coPilotClient(Client *client)
|
||||
{
|
||||
return static_cast<Internal::CopilotClient *>(client);
|
||||
}
|
||||
|
||||
Internal::CopilotClient *findClient()
|
||||
{
|
||||
return Internal::CopilotClient::instance();
|
||||
}
|
||||
|
||||
AuthWidget::AuthWidget(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
using namespace Utils::Layouting;
|
||||
|
||||
m_button = new QPushButton();
|
||||
m_progressIndicator = new Utils::ProgressIndicator(Utils::ProgressIndicatorSize::Small);
|
||||
m_statusLabel = new QLabel();
|
||||
|
||||
// clang-format off
|
||||
Column {
|
||||
Row {
|
||||
m_button, m_progressIndicator, st
|
||||
},
|
||||
m_statusLabel
|
||||
}.attachTo(this);
|
||||
// clang-format on
|
||||
|
||||
setState("Checking status ...", true);
|
||||
|
||||
connect(LanguageClientManager::instance(),
|
||||
&LanguageClientManager::clientAdded,
|
||||
this,
|
||||
&AuthWidget::onClientAdded);
|
||||
|
||||
connect(m_button, &QPushButton::clicked, this, [this]() {
|
||||
if (m_status == Status::SignedIn)
|
||||
signOut();
|
||||
else if (m_status == Status::SignedOut)
|
||||
signIn();
|
||||
});
|
||||
|
||||
auto client = findClient();
|
||||
|
||||
if (client)
|
||||
checkStatus(client);
|
||||
}
|
||||
|
||||
void AuthWidget::setState(const QString &buttonText, bool working)
|
||||
{
|
||||
m_button->setText(buttonText);
|
||||
m_progressIndicator->setVisible(working);
|
||||
m_statusLabel->setVisible(!m_statusLabel->text().isEmpty());
|
||||
m_button->setEnabled(!working);
|
||||
}
|
||||
|
||||
void AuthWidget::onClientAdded(LanguageClient::Client *client)
|
||||
{
|
||||
if (isCopilotClient(client)) {
|
||||
checkStatus(coPilotClient(client));
|
||||
}
|
||||
}
|
||||
|
||||
void AuthWidget::checkStatus(Internal::CopilotClient *client)
|
||||
{
|
||||
client->requestCheckStatus(false, [this](const CheckStatusRequest::Response &response) {
|
||||
if (response.error()) {
|
||||
setState("failed: " + response.error()->message(), false);
|
||||
return;
|
||||
}
|
||||
const CheckStatusResponse result = *response.result();
|
||||
|
||||
if (result.user().isEmpty()) {
|
||||
setState("Sign in", false);
|
||||
m_status = Status::SignedOut;
|
||||
return;
|
||||
}
|
||||
|
||||
setState("Sign out " + result.user(), false);
|
||||
m_status = Status::SignedIn;
|
||||
});
|
||||
}
|
||||
|
||||
void AuthWidget::signIn()
|
||||
{
|
||||
qCritical() << "Not implemented";
|
||||
auto client = findClient();
|
||||
QTC_ASSERT(client, return);
|
||||
|
||||
setState("Signing in ...", true);
|
||||
|
||||
client->requestSignInInitiate([this, client](const SignInInitiateRequest::Response &response) {
|
||||
QTC_ASSERT(!response.error(), return);
|
||||
|
||||
Utils::setClipboardAndSelection(response.result()->userCode());
|
||||
|
||||
QDesktopServices::openUrl(QUrl(response.result()->verificationUri()));
|
||||
|
||||
m_statusLabel->setText(Tr::tr("A browser window will open, enter the code %1 when "
|
||||
"asked.\nThe code has been copied to your clipboard.")
|
||||
.arg(response.result()->userCode()));
|
||||
m_statusLabel->setVisible(true);
|
||||
|
||||
client->requestSignInConfirm(response.result()->userCode(),
|
||||
[this](const SignInConfirmRequest::Response &response) {
|
||||
m_statusLabel->setText("");
|
||||
|
||||
if (response.error()) {
|
||||
QMessageBox::critical(this,
|
||||
Tr::tr("Login failed"),
|
||||
Tr::tr(
|
||||
"The login request failed: ")
|
||||
+ response.error()->message());
|
||||
setState("Sign in", false);
|
||||
return;
|
||||
}
|
||||
|
||||
setState("Sign Out " + response.result()->user(), false);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void AuthWidget::signOut()
|
||||
{
|
||||
auto client = findClient();
|
||||
QTC_ASSERT(client, return);
|
||||
|
||||
setState("Signing out ...", true);
|
||||
|
||||
client->requestSignOut([this, client](const SignOutRequest::Response &response) {
|
||||
QTC_ASSERT(!response.error(), return);
|
||||
QTC_ASSERT(response.result()->status() == "NotSignedIn", return);
|
||||
|
||||
checkStatus(client);
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace Copilot
|
44
src/plugins/copilot/authwidget.h
Normal file
44
src/plugins/copilot/authwidget.h
Normal file
@@ -0,0 +1,44 @@
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "copilotclient.h"
|
||||
|
||||
#include <utils/progressindicator.h>
|
||||
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
#include <QWidget>
|
||||
|
||||
namespace LanguageClient {
|
||||
class Client;
|
||||
}
|
||||
|
||||
namespace Copilot {
|
||||
|
||||
class AuthWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
enum class Status { SignedIn, SignedOut, Unknown };
|
||||
|
||||
public:
|
||||
explicit AuthWidget(QWidget *parent = nullptr);
|
||||
|
||||
private:
|
||||
void onClientAdded(LanguageClient::Client *client);
|
||||
void setState(const QString &buttonText, bool working);
|
||||
void checkStatus(Internal::CopilotClient *client);
|
||||
|
||||
void signIn();
|
||||
void signOut();
|
||||
|
||||
private:
|
||||
Status m_status = Status::Unknown;
|
||||
QPushButton *m_button = nullptr;
|
||||
QLabel *m_statusLabel = nullptr;
|
||||
Utils::ProgressIndicator *m_progressIndicator = nullptr;
|
||||
};
|
||||
|
||||
} // namespace Copilot
|
30
src/plugins/copilot/copilot.qbs
Normal file
30
src/plugins/copilot/copilot.qbs
Normal file
@@ -0,0 +1,30 @@
|
||||
import qbs 1.0
|
||||
|
||||
QtcPlugin {
|
||||
name: "Copilot"
|
||||
|
||||
Depends { name: "Core" }
|
||||
Depends { name: "Qt"; submodules: ["widgets", "xml", "network"] }
|
||||
|
||||
files: [
|
||||
"authwidget.cpp",
|
||||
"authwidget.h",
|
||||
"copilotplugin.cpp",
|
||||
"copilotplugin.h",
|
||||
"copilotclient.cpp",
|
||||
"copilotclient.h",
|
||||
"copilotsettings.cpp",
|
||||
"copilotsettings.h",
|
||||
"copilotoptionspage.cpp",
|
||||
"copilotoptionspage.h",
|
||||
"copilotoptionspagewidget.cpp",
|
||||
"copilotoptionspagewidget.h",
|
||||
"documentwatcher.cpp",
|
||||
"documentwatcher.h",
|
||||
"requests/getcompletions.h",
|
||||
"requests/checkstatus.h",
|
||||
"requests/signout.h",
|
||||
"requests/signininitiate.h",
|
||||
"requests/signinconfirm.h",
|
||||
]
|
||||
}
|
133
src/plugins/copilot/copilotclient.cpp
Normal file
133
src/plugins/copilot/copilotclient.cpp
Normal file
@@ -0,0 +1,133 @@
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "copilotclient.h"
|
||||
|
||||
#include "copilotsettings.h"
|
||||
#include "documentwatcher.h"
|
||||
|
||||
#include <languageclient/languageclientinterface.h>
|
||||
#include <languageclient/languageclientmanager.h>
|
||||
#include <languageclient/languageclientsettings.h>
|
||||
|
||||
#include <coreplugin/editormanager/editormanager.h>
|
||||
|
||||
#include <utils/filepath.h>
|
||||
|
||||
using namespace Utils;
|
||||
|
||||
namespace Copilot::Internal {
|
||||
|
||||
static LanguageClient::BaseClientInterface *clientInterface()
|
||||
{
|
||||
const FilePath nodePath = CopilotSettings::instance().nodeJsPath.filePath();
|
||||
const FilePath distPath = CopilotSettings::instance().distPath.filePath();
|
||||
|
||||
CommandLine cmd{nodePath, {distPath.toFSPathString()}};
|
||||
|
||||
const auto interface = new LanguageClient::StdIOClientInterface;
|
||||
interface->setCommandLine(cmd);
|
||||
return interface;
|
||||
}
|
||||
|
||||
static CopilotClient *currentInstance = nullptr;
|
||||
|
||||
CopilotClient *CopilotClient::instance()
|
||||
{
|
||||
return currentInstance;
|
||||
}
|
||||
|
||||
CopilotClient::CopilotClient()
|
||||
: LanguageClient::Client(clientInterface())
|
||||
{
|
||||
setName("Copilot");
|
||||
LanguageClient::LanguageFilter langFilter;
|
||||
|
||||
langFilter.filePattern = {"*"};
|
||||
|
||||
setSupportedLanguage(langFilter);
|
||||
start();
|
||||
|
||||
connect(Core::EditorManager::instance(),
|
||||
&Core::EditorManager::documentOpened,
|
||||
this,
|
||||
[this](Core::IDocument *document) {
|
||||
TextEditor::TextDocument *textDocument = qobject_cast<TextEditor::TextDocument *>(
|
||||
document);
|
||||
if (!textDocument)
|
||||
return;
|
||||
|
||||
openDocument(textDocument);
|
||||
|
||||
m_documentWatchers.emplace(textDocument->filePath(),
|
||||
std::make_unique<DocumentWatcher>(this, textDocument));
|
||||
});
|
||||
|
||||
connect(Core::EditorManager::instance(),
|
||||
&Core::EditorManager::documentClosed,
|
||||
this,
|
||||
[this](Core::IDocument *document) {
|
||||
auto textDocument = qobject_cast<TextEditor::TextDocument *>(document);
|
||||
if (!textDocument)
|
||||
return;
|
||||
|
||||
closeDocument(textDocument);
|
||||
m_documentWatchers.erase(textDocument->filePath());
|
||||
});
|
||||
|
||||
currentInstance = this;
|
||||
}
|
||||
|
||||
void CopilotClient::requestCompletion(
|
||||
const Utils::FilePath &path,
|
||||
int version,
|
||||
LanguageServerProtocol::Position position,
|
||||
std::function<void(const GetCompletionRequest::Response &response)> callback)
|
||||
{
|
||||
GetCompletionRequest request{
|
||||
{LanguageServerProtocol::TextDocumentIdentifier(hostPathToServerUri(path)),
|
||||
version,
|
||||
position}};
|
||||
request.setResponseCallback(callback);
|
||||
|
||||
sendMessage(request);
|
||||
}
|
||||
|
||||
void CopilotClient::requestCheckStatus(
|
||||
bool localChecksOnly, std::function<void(const CheckStatusRequest::Response &response)> callback)
|
||||
{
|
||||
CheckStatusRequest request{localChecksOnly};
|
||||
request.setResponseCallback(callback);
|
||||
|
||||
sendMessage(request);
|
||||
}
|
||||
|
||||
void CopilotClient::requestSignOut(
|
||||
std::function<void(const SignOutRequest::Response &response)> callback)
|
||||
{
|
||||
SignOutRequest request;
|
||||
request.setResponseCallback(callback);
|
||||
|
||||
sendMessage(request);
|
||||
}
|
||||
|
||||
void CopilotClient::requestSignInInitiate(
|
||||
std::function<void(const SignInInitiateRequest::Response &response)> callback)
|
||||
{
|
||||
SignInInitiateRequest request;
|
||||
request.setResponseCallback(callback);
|
||||
|
||||
sendMessage(request);
|
||||
}
|
||||
|
||||
void CopilotClient::requestSignInConfirm(
|
||||
const QString &userCode,
|
||||
std::function<void(const SignInConfirmRequest::Response &response)> callback)
|
||||
{
|
||||
SignInConfirmRequest request(userCode);
|
||||
request.setResponseCallback(callback);
|
||||
|
||||
sendMessage(request);
|
||||
}
|
||||
|
||||
} // namespace Copilot::Internal
|
53
src/plugins/copilot/copilotclient.h
Normal file
53
src/plugins/copilot/copilotclient.h
Normal file
@@ -0,0 +1,53 @@
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "requests/checkstatus.h"
|
||||
#include "requests/getcompletions.h"
|
||||
#include "requests/signinconfirm.h"
|
||||
#include "requests/signininitiate.h"
|
||||
#include "requests/signout.h"
|
||||
|
||||
#include <languageclient/client.h>
|
||||
|
||||
#include <utils/filepath.h>
|
||||
|
||||
#include <QHash>
|
||||
#include <QTemporaryDir>
|
||||
|
||||
namespace Copilot::Internal {
|
||||
|
||||
class DocumentWatcher;
|
||||
|
||||
class CopilotClient : public LanguageClient::Client
|
||||
{
|
||||
public:
|
||||
explicit CopilotClient();
|
||||
|
||||
static CopilotClient *instance();
|
||||
|
||||
void requestCompletion(
|
||||
const Utils::FilePath &path,
|
||||
int version,
|
||||
LanguageServerProtocol::Position position,
|
||||
std::function<void(const GetCompletionRequest::Response &response)> callback);
|
||||
|
||||
void requestCheckStatus(
|
||||
bool localChecksOnly,
|
||||
std::function<void(const CheckStatusRequest::Response &response)> callback);
|
||||
|
||||
void requestSignOut(std::function<void(const SignOutRequest::Response &response)> callback);
|
||||
|
||||
void requestSignInInitiate(
|
||||
std::function<void(const SignInInitiateRequest::Response &response)> callback);
|
||||
|
||||
void requestSignInConfirm(
|
||||
const QString &userCode,
|
||||
std::function<void(const SignInConfirmRequest::Response &response)> callback);
|
||||
|
||||
private:
|
||||
std::map<Utils::FilePath, std::unique_ptr<DocumentWatcher>> m_documentWatchers;
|
||||
};
|
||||
|
||||
} // namespace Copilot::Internal
|
46
src/plugins/copilot/copilotoptionspage.cpp
Normal file
46
src/plugins/copilot/copilotoptionspage.cpp
Normal file
@@ -0,0 +1,46 @@
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "copilotoptionspage.h"
|
||||
|
||||
#include "copilotoptionspagewidget.h"
|
||||
#include "copilotsettings.h"
|
||||
|
||||
#include <coreplugin/icore.h>
|
||||
|
||||
namespace Copilot {
|
||||
|
||||
CopilotOptionsPage::CopilotOptionsPage()
|
||||
{
|
||||
setId("Copilot.General");
|
||||
setDisplayName("Copilot");
|
||||
setCategory("ZY.Copilot");
|
||||
setDisplayCategory("Copilot");
|
||||
|
||||
setCategoryIconPath(":/languageclient/images/settingscategory_languageclient.png");
|
||||
}
|
||||
|
||||
CopilotOptionsPage::~CopilotOptionsPage() {}
|
||||
|
||||
void CopilotOptionsPage::init() {}
|
||||
|
||||
QWidget *CopilotOptionsPage::widget()
|
||||
{
|
||||
return new CopilotOptionsPageWidget();
|
||||
}
|
||||
|
||||
void CopilotOptionsPage::apply()
|
||||
{
|
||||
CopilotSettings::instance().apply();
|
||||
CopilotSettings::instance().writeSettings(Core::ICore::settings());
|
||||
}
|
||||
|
||||
void CopilotOptionsPage::finish() {}
|
||||
|
||||
CopilotOptionsPage &CopilotOptionsPage::instance()
|
||||
{
|
||||
static CopilotOptionsPage settingsPage;
|
||||
return settingsPage;
|
||||
}
|
||||
|
||||
} // namespace Copilot
|
25
src/plugins/copilot/copilotoptionspage.h
Normal file
25
src/plugins/copilot/copilotoptionspage.h
Normal file
@@ -0,0 +1,25 @@
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <coreplugin/dialogs/ioptionspage.h>
|
||||
|
||||
namespace Copilot {
|
||||
|
||||
class CopilotOptionsPage : public Core::IOptionsPage
|
||||
{
|
||||
public:
|
||||
CopilotOptionsPage();
|
||||
~CopilotOptionsPage() override;
|
||||
|
||||
static CopilotOptionsPage &instance();
|
||||
|
||||
void init();
|
||||
|
||||
QWidget *widget() override;
|
||||
void apply() override;
|
||||
void finish() override;
|
||||
};
|
||||
|
||||
} // namespace Copilot
|
36
src/plugins/copilot/copilotoptionspagewidget.cpp
Normal file
36
src/plugins/copilot/copilotoptionspagewidget.cpp
Normal file
@@ -0,0 +1,36 @@
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "copilotoptionspagewidget.h"
|
||||
|
||||
#include "authwidget.h"
|
||||
#include "copilotsettings.h"
|
||||
|
||||
#include <utils/layoutbuilder.h>
|
||||
#include <utils/pathchooser.h>
|
||||
|
||||
using namespace Utils;
|
||||
using namespace LanguageClient;
|
||||
|
||||
namespace Copilot {
|
||||
|
||||
CopilotOptionsPageWidget::CopilotOptionsPageWidget(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
using namespace Layouting;
|
||||
|
||||
auto authWdgt = new AuthWidget();
|
||||
|
||||
// clang-format off
|
||||
Column {
|
||||
authWdgt, br,
|
||||
CopilotSettings::instance().nodeJsPath, br,
|
||||
CopilotSettings::instance().distPath, br,
|
||||
st
|
||||
}.attachTo(this);
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
CopilotOptionsPageWidget::~CopilotOptionsPageWidget() = default;
|
||||
|
||||
} // namespace Copilot
|
16
src/plugins/copilot/copilotoptionspagewidget.h
Normal file
16
src/plugins/copilot/copilotoptionspagewidget.h
Normal file
@@ -0,0 +1,16 @@
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
namespace Copilot {
|
||||
class CopilotOptionsPageWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CopilotOptionsPageWidget(QWidget *parent = nullptr);
|
||||
~CopilotOptionsPageWidget() override;
|
||||
};
|
||||
} // namespace Copilot
|
37
src/plugins/copilot/copilotplugin.cpp
Normal file
37
src/plugins/copilot/copilotplugin.cpp
Normal file
@@ -0,0 +1,37 @@
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "copilotplugin.h"
|
||||
|
||||
#include "copilotclient.h"
|
||||
#include "copilotoptionspage.h"
|
||||
#include "copilotsettings.h"
|
||||
|
||||
#include <coreplugin/icore.h>
|
||||
|
||||
using namespace Utils;
|
||||
|
||||
namespace Copilot {
|
||||
namespace Internal {
|
||||
|
||||
void CopilotPlugin::initialize()
|
||||
{
|
||||
CopilotSettings::instance().readSettings(Core::ICore::settings());
|
||||
|
||||
m_client = new CopilotClient();
|
||||
|
||||
connect(&CopilotSettings::instance(), &CopilotSettings::applied, this, [this]() {
|
||||
if (m_client)
|
||||
m_client->shutdown();
|
||||
m_client = nullptr;
|
||||
m_client = new CopilotClient();
|
||||
});
|
||||
}
|
||||
|
||||
void CopilotPlugin::extensionsInitialized()
|
||||
{
|
||||
CopilotOptionsPage::instance().init();
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Copilot
|
30
src/plugins/copilot/copilotplugin.h
Normal file
30
src/plugins/copilot/copilotplugin.h
Normal file
@@ -0,0 +1,30 @@
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "copilotclient.h"
|
||||
|
||||
#include <extensionsystem/iplugin.h>
|
||||
|
||||
namespace Copilot {
|
||||
namespace Internal {
|
||||
|
||||
class CopilotPlugin : public ExtensionSystem::IPlugin
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "Copilot.json")
|
||||
|
||||
public:
|
||||
CopilotPlugin() {}
|
||||
~CopilotPlugin() override {}
|
||||
|
||||
void initialize() override;
|
||||
void extensionsInitialized() override;
|
||||
|
||||
private:
|
||||
CopilotClient *m_client;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Copilot
|
65
src/plugins/copilot/copilotsettings.cpp
Normal file
65
src/plugins/copilot/copilotsettings.cpp
Normal file
@@ -0,0 +1,65 @@
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "copilotsettings.h"
|
||||
#include "copilottr.h"
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/environment.h>
|
||||
|
||||
using namespace Utils;
|
||||
|
||||
namespace Copilot {
|
||||
|
||||
CopilotSettings &CopilotSettings::instance()
|
||||
{
|
||||
static CopilotSettings settings;
|
||||
return settings;
|
||||
}
|
||||
|
||||
CopilotSettings::CopilotSettings()
|
||||
{
|
||||
setAutoApply(false);
|
||||
|
||||
const FilePath nodeFromPath = FilePath("node").searchInPath();
|
||||
|
||||
const FilePaths searchDirs
|
||||
= {FilePath::fromUserInput("~/.vim/pack/github/start/copilot.vim/copilot/dist/agent.js"),
|
||||
FilePath::fromUserInput(
|
||||
"~/.config/nvim/pack/github/start/copilot.vim/copilot/dist/agent.js"),
|
||||
FilePath::fromUserInput(
|
||||
"~/vimfiles/pack/github/start/copilot.vim/copilot/dist/agent.js"),
|
||||
FilePath::fromUserInput(
|
||||
"~/AppData/Local/nvim/pack/github/start/copilot.vim/copilot/dist/agent.js")};
|
||||
|
||||
const FilePath distFromVim = Utils::findOrDefault(searchDirs, [](const FilePath &fp) {
|
||||
return fp.exists();
|
||||
});
|
||||
|
||||
nodeJsPath.setExpectedKind(PathChooser::ExistingCommand);
|
||||
nodeJsPath.setDefaultFilePath(nodeFromPath);
|
||||
nodeJsPath.setSettingsKey("Copilot.NodeJsPath");
|
||||
nodeJsPath.setDisplayStyle(StringAspect::PathChooserDisplay);
|
||||
nodeJsPath.setLabelText(Tr::tr("Node.js path:"));
|
||||
nodeJsPath.setHistoryCompleter("Copilot.NodePath.History");
|
||||
nodeJsPath.setDisplayName(Tr::tr("Node.js Path"));
|
||||
nodeJsPath.setToolTip(
|
||||
Tr::tr("Select path to node.js executable. See https://nodejs.org/de/download/"
|
||||
"for installation instructions."));
|
||||
|
||||
distPath.setExpectedKind(PathChooser::File);
|
||||
distPath.setDefaultFilePath(distFromVim);
|
||||
distPath.setSettingsKey("Copilot.DistPath");
|
||||
distPath.setDisplayStyle(StringAspect::PathChooserDisplay);
|
||||
distPath.setLabelText(Tr::tr("Path to agent.js:"));
|
||||
distPath.setToolTip(Tr::tr(
|
||||
"Select path to agent.js in copilot neovim plugin. See "
|
||||
"https://github.com/github/copilot.vim#getting-started for installation instructions."));
|
||||
distPath.setHistoryCompleter("Copilot.DistPath.History");
|
||||
distPath.setDisplayName(Tr::tr("Agent.js path"));
|
||||
|
||||
registerAspect(&nodeJsPath);
|
||||
registerAspect(&distPath);
|
||||
}
|
||||
|
||||
} // namespace Copilot
|
21
src/plugins/copilot/copilotsettings.h
Normal file
21
src/plugins/copilot/copilotsettings.h
Normal file
@@ -0,0 +1,21 @@
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <utils/aspects.h>
|
||||
|
||||
namespace Copilot {
|
||||
|
||||
class CopilotSettings : public Utils::AspectContainer
|
||||
{
|
||||
public:
|
||||
CopilotSettings();
|
||||
|
||||
static CopilotSettings &instance();
|
||||
|
||||
Utils::StringAspect nodeJsPath;
|
||||
Utils::StringAspect distPath;
|
||||
};
|
||||
|
||||
} // namespace Copilot
|
15
src/plugins/copilot/copilottr.h
Normal file
15
src/plugins/copilot/copilottr.h
Normal file
@@ -0,0 +1,15 @@
|
||||
// Copyright (C) 2022 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QCoreApplication>
|
||||
|
||||
namespace Copilot {
|
||||
|
||||
struct Tr
|
||||
{
|
||||
Q_DECLARE_TR_FUNCTIONS(::Copilot)
|
||||
};
|
||||
|
||||
} // namespace Copilot
|
92
src/plugins/copilot/documentwatcher.cpp
Normal file
92
src/plugins/copilot/documentwatcher.cpp
Normal file
@@ -0,0 +1,92 @@
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "documentwatcher.h"
|
||||
|
||||
#include <coreplugin/editormanager/editormanager.h>
|
||||
|
||||
#include <texteditor/texteditor.h>
|
||||
|
||||
#include <QJsonDocument>
|
||||
|
||||
using namespace LanguageServerProtocol;
|
||||
using namespace TextEditor;
|
||||
|
||||
namespace Copilot::Internal {
|
||||
|
||||
DocumentWatcher::DocumentWatcher(CopilotClient *client, TextDocument *textDocument)
|
||||
: m_client(client)
|
||||
, m_textDocument(textDocument)
|
||||
{
|
||||
m_lastContentSize = m_textDocument->document()->characterCount(); //toPlainText().size();
|
||||
m_debounceTimer.setInterval(500);
|
||||
m_debounceTimer.setSingleShot(true);
|
||||
|
||||
connect(textDocument, &TextDocument::contentsChanged, this, [this]() {
|
||||
if (!m_isEditing) {
|
||||
const int newSize = m_textDocument->document()->characterCount();
|
||||
if (m_lastContentSize < newSize) {
|
||||
m_debounceTimer.start();
|
||||
}
|
||||
m_lastContentSize = newSize;
|
||||
}
|
||||
});
|
||||
|
||||
connect(&m_debounceTimer, &QTimer::timeout, this, [this]() { getSuggestion(); });
|
||||
}
|
||||
|
||||
void DocumentWatcher::getSuggestion()
|
||||
{
|
||||
auto editor = Core::EditorManager::instance()->activateEditorForDocument(m_textDocument);
|
||||
auto textEditorWidget = qobject_cast<TextEditor::TextEditorWidget *>(editor->widget());
|
||||
if (!editor || !textEditorWidget)
|
||||
return;
|
||||
|
||||
auto cursor = textEditorWidget->multiTextCursor();
|
||||
if (cursor.hasMultipleCursors() || cursor.hasSelection())
|
||||
return;
|
||||
|
||||
const int currentCursorPos = cursor.cursors().first().position();
|
||||
|
||||
m_client->requestCompletion(
|
||||
m_textDocument->filePath(),
|
||||
m_client->documentVersion(m_textDocument->filePath()),
|
||||
Position(editor->currentLine() - 1, editor->currentColumn() - 1),
|
||||
[this, textEditorWidget, currentCursorPos](const GetCompletionRequest::Response &response) {
|
||||
if (response.error()) {
|
||||
qDebug() << "ERROR:" << *response.error();
|
||||
return;
|
||||
}
|
||||
|
||||
const std::optional<GetCompletionResponse> result = response.result();
|
||||
QTC_ASSERT(result, return);
|
||||
|
||||
const auto list = result->completions().toList();
|
||||
|
||||
if (list.isEmpty())
|
||||
return;
|
||||
|
||||
auto cursor = textEditorWidget->multiTextCursor();
|
||||
if (cursor.hasMultipleCursors() || cursor.hasSelection())
|
||||
return;
|
||||
if (cursor.cursors().first().position() != currentCursorPos)
|
||||
return;
|
||||
|
||||
const auto firstCompletion = list.first();
|
||||
const QString content = firstCompletion.text().mid(
|
||||
firstCompletion.position().character());
|
||||
|
||||
m_isEditing = true;
|
||||
textEditorWidget->insertSuggestion(content);
|
||||
m_isEditing = false;
|
||||
/*
|
||||
m_isEditing = true;
|
||||
const auto &block = m_textDocument->document()->findBlockByLineNumber(
|
||||
firstCompletion.position().line());
|
||||
m_textDocument->insertSuggestion(content, block);
|
||||
m_isEditing = false;
|
||||
*/
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace Copilot::Internal
|
31
src/plugins/copilot/documentwatcher.h
Normal file
31
src/plugins/copilot/documentwatcher.h
Normal file
@@ -0,0 +1,31 @@
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "copilotclient.h"
|
||||
|
||||
#include <texteditor/textdocument.h>
|
||||
|
||||
#include <QTimer>
|
||||
|
||||
namespace Copilot::Internal {
|
||||
|
||||
class DocumentWatcher : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit DocumentWatcher(CopilotClient *client, TextEditor::TextDocument *textDocument);
|
||||
|
||||
void getSuggestion();
|
||||
|
||||
private:
|
||||
CopilotClient *m_client;
|
||||
TextEditor::TextDocument *m_textDocument;
|
||||
|
||||
QTimer m_debounceTimer;
|
||||
bool m_isEditing = false;
|
||||
int m_lastContentSize = 0;
|
||||
};
|
||||
|
||||
} // namespace Copilot::Internal
|
54
src/plugins/copilot/requests/checkstatus.h
Normal file
54
src/plugins/copilot/requests/checkstatus.h
Normal file
@@ -0,0 +1,54 @@
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <languageserverprotocol/jsonrpcmessages.h>
|
||||
#include <languageserverprotocol/lsptypes.h>
|
||||
|
||||
namespace Copilot {
|
||||
|
||||
class CheckStatusParams : public LanguageServerProtocol::JsonObject
|
||||
{
|
||||
static constexpr char16_t optionsKey[] = u"options";
|
||||
static constexpr char16_t localChecksOnlyKey[] = u"options";
|
||||
|
||||
public:
|
||||
using JsonObject::JsonObject;
|
||||
|
||||
CheckStatusParams(bool localChecksOnly = false) { setLocalChecksOnly(localChecksOnly); }
|
||||
|
||||
void setLocalChecksOnly(bool localChecksOnly)
|
||||
{
|
||||
QJsonObject options;
|
||||
options.insert(localChecksOnlyKey, localChecksOnly);
|
||||
setOptions(options);
|
||||
}
|
||||
|
||||
void setOptions(QJsonObject options) { insert(optionsKey, options); }
|
||||
};
|
||||
|
||||
class CheckStatusResponse : public LanguageServerProtocol::JsonObject
|
||||
{
|
||||
static constexpr char16_t userKey[] = u"user";
|
||||
static constexpr char16_t statusKey[] = u"status";
|
||||
|
||||
public:
|
||||
using JsonObject::JsonObject;
|
||||
|
||||
QString status() const { return typedValue<QString>(statusKey); }
|
||||
QString user() const { return typedValue<QString>(userKey); }
|
||||
};
|
||||
|
||||
class CheckStatusRequest
|
||||
: public LanguageServerProtocol::Request<CheckStatusResponse, std::nullptr_t, CheckStatusParams>
|
||||
{
|
||||
public:
|
||||
explicit CheckStatusRequest(const CheckStatusParams ¶ms)
|
||||
: Request(methodName, params)
|
||||
{}
|
||||
using Request::Request;
|
||||
constexpr static const char methodName[] = "checkStatus";
|
||||
};
|
||||
|
||||
} // namespace Copilot
|
120
src/plugins/copilot/requests/getcompletions.h
Normal file
120
src/plugins/copilot/requests/getcompletions.h
Normal file
@@ -0,0 +1,120 @@
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <languageserverprotocol/jsonkeys.h>
|
||||
#include <languageserverprotocol/jsonrpcmessages.h>
|
||||
#include <languageserverprotocol/lsptypes.h>
|
||||
|
||||
namespace Copilot {
|
||||
|
||||
class Completion : public LanguageServerProtocol::JsonObject
|
||||
{
|
||||
static constexpr char16_t displayTextKey[] = u"displayText";
|
||||
static constexpr char16_t uuidKey[] = u"uuid";
|
||||
|
||||
public:
|
||||
using JsonObject::JsonObject;
|
||||
|
||||
QString displayText() const { return typedValue<QString>(displayTextKey); }
|
||||
LanguageServerProtocol::Position position() const
|
||||
{
|
||||
return typedValue<LanguageServerProtocol::Position>(LanguageServerProtocol::positionKey);
|
||||
}
|
||||
LanguageServerProtocol::Range range() const
|
||||
{
|
||||
return typedValue<LanguageServerProtocol::Range>(LanguageServerProtocol::rangeKey);
|
||||
}
|
||||
QString text() const { return typedValue<QString>(LanguageServerProtocol::textKey); }
|
||||
QString uuid() const { return typedValue<QString>(uuidKey); }
|
||||
|
||||
bool isValid() const override
|
||||
{
|
||||
return contains(LanguageServerProtocol::textKey)
|
||||
&& contains(LanguageServerProtocol::rangeKey)
|
||||
&& contains(LanguageServerProtocol::positionKey);
|
||||
}
|
||||
};
|
||||
|
||||
class GetCompletionParams : public LanguageServerProtocol::JsonObject
|
||||
{
|
||||
public:
|
||||
static constexpr char16_t docKey[] = u"doc";
|
||||
|
||||
GetCompletionParams();
|
||||
GetCompletionParams(const LanguageServerProtocol::TextDocumentIdentifier &document,
|
||||
int version,
|
||||
const LanguageServerProtocol::Position &position)
|
||||
{
|
||||
setTextDocument(document);
|
||||
setVersion(version);
|
||||
setPosition(position);
|
||||
}
|
||||
using JsonObject::JsonObject;
|
||||
|
||||
// The text document.
|
||||
LanguageServerProtocol::TextDocumentIdentifier textDocument() const
|
||||
{
|
||||
return typedValue<LanguageServerProtocol::TextDocumentIdentifier>(docKey);
|
||||
}
|
||||
void setTextDocument(const LanguageServerProtocol::TextDocumentIdentifier &id)
|
||||
{
|
||||
insert(docKey, id);
|
||||
}
|
||||
|
||||
// The position inside the text document.
|
||||
LanguageServerProtocol::Position position() const
|
||||
{
|
||||
return LanguageServerProtocol::fromJsonValue<LanguageServerProtocol::Position>(
|
||||
value(docKey).toObject().value(LanguageServerProtocol::positionKey));
|
||||
}
|
||||
void setPosition(const LanguageServerProtocol::Position &position)
|
||||
{
|
||||
QJsonObject result = value(docKey).toObject();
|
||||
result[LanguageServerProtocol::positionKey] = (QJsonObject) position;
|
||||
insert(docKey, result);
|
||||
}
|
||||
|
||||
// The version
|
||||
int version() const { return typedValue<int>(LanguageServerProtocol::versionKey); }
|
||||
void setVersion(int version)
|
||||
{
|
||||
QJsonObject result = value(docKey).toObject();
|
||||
result[LanguageServerProtocol::versionKey] = version;
|
||||
insert(docKey, result);
|
||||
}
|
||||
|
||||
bool isValid() const override
|
||||
{
|
||||
return contains(docKey)
|
||||
&& value(docKey).toObject().contains(LanguageServerProtocol::positionKey)
|
||||
&& value(docKey).toObject().contains(LanguageServerProtocol::versionKey);
|
||||
}
|
||||
};
|
||||
|
||||
class GetCompletionResponse : public LanguageServerProtocol::JsonObject
|
||||
{
|
||||
static constexpr char16_t completionKey[] = u"completions";
|
||||
|
||||
public:
|
||||
using JsonObject::JsonObject;
|
||||
|
||||
LanguageServerProtocol::LanguageClientArray<Completion> completions() const
|
||||
{
|
||||
return clientArray<Completion>(completionKey);
|
||||
}
|
||||
};
|
||||
|
||||
class GetCompletionRequest
|
||||
: public LanguageServerProtocol::Request<GetCompletionResponse, std::nullptr_t, GetCompletionParams>
|
||||
{
|
||||
public:
|
||||
explicit GetCompletionRequest(const GetCompletionParams ¶ms)
|
||||
: Request(methodName, params)
|
||||
{}
|
||||
using Request::Request;
|
||||
constexpr static const char methodName[] = "getCompletionsCycling";
|
||||
};
|
||||
|
||||
} // namespace Copilot
|
36
src/plugins/copilot/requests/signinconfirm.h
Normal file
36
src/plugins/copilot/requests/signinconfirm.h
Normal file
@@ -0,0 +1,36 @@
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "checkstatus.h"
|
||||
|
||||
#include <languageserverprotocol/jsonrpcmessages.h>
|
||||
#include <languageserverprotocol/lsptypes.h>
|
||||
|
||||
namespace Copilot {
|
||||
|
||||
class SignInConfirmParams : public LanguageServerProtocol::JsonObject
|
||||
{
|
||||
static constexpr char16_t userCodeKey[] = u"userCode";
|
||||
|
||||
public:
|
||||
using JsonObject::JsonObject;
|
||||
|
||||
SignInConfirmParams(const QString &userCode) { setUserCode(userCode); }
|
||||
|
||||
void setUserCode(const QString &userCode) { insert(userCodeKey, userCode); }
|
||||
};
|
||||
|
||||
class SignInConfirmRequest
|
||||
: public LanguageServerProtocol::Request<CheckStatusResponse, std::nullptr_t, SignInConfirmParams>
|
||||
{
|
||||
public:
|
||||
explicit SignInConfirmRequest(const QString &userCode)
|
||||
: Request(methodName, {userCode})
|
||||
{}
|
||||
using Request::Request;
|
||||
constexpr static const char methodName[] = "signInConfirm";
|
||||
};
|
||||
|
||||
} // namespace Copilot
|
43
src/plugins/copilot/requests/signininitiate.h
Normal file
43
src/plugins/copilot/requests/signininitiate.h
Normal file
@@ -0,0 +1,43 @@
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||
|
||||
#pragma once
|
||||
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <languageserverprotocol/jsonrpcmessages.h>
|
||||
#include <languageserverprotocol/lsptypes.h>
|
||||
|
||||
namespace Copilot {
|
||||
|
||||
using SignInInitiateParams = LanguageServerProtocol::JsonObject;
|
||||
|
||||
class SignInInitiateResponse : public LanguageServerProtocol::JsonObject
|
||||
{
|
||||
static constexpr char16_t verificationUriKey[] = u"verificationUri";
|
||||
static constexpr char16_t userCodeKey[] = u"userCode";
|
||||
|
||||
public:
|
||||
using JsonObject::JsonObject;
|
||||
|
||||
public:
|
||||
QString verificationUri() const { return typedValue<QString>(verificationUriKey); }
|
||||
QString userCode() const { return typedValue<QString>(userCodeKey); }
|
||||
};
|
||||
|
||||
class SignInInitiateRequest : public LanguageServerProtocol::Request<SignInInitiateResponse,
|
||||
std::nullptr_t,
|
||||
SignInInitiateParams>
|
||||
{
|
||||
public:
|
||||
explicit SignInInitiateRequest()
|
||||
: Request(methodName, {})
|
||||
{}
|
||||
using Request::Request;
|
||||
constexpr static const char methodName[] = "signInInitiate";
|
||||
};
|
||||
|
||||
} // namespace Copilot
|
26
src/plugins/copilot/requests/signout.h
Normal file
26
src/plugins/copilot/requests/signout.h
Normal file
@@ -0,0 +1,26 @@
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "checkstatus.h"
|
||||
|
||||
#include <languageserverprotocol/jsonrpcmessages.h>
|
||||
#include <languageserverprotocol/lsptypes.h>
|
||||
|
||||
namespace Copilot {
|
||||
|
||||
using SignOutParams = LanguageServerProtocol::JsonObject;
|
||||
|
||||
class SignOutRequest
|
||||
: public LanguageServerProtocol::Request<CheckStatusResponse, std::nullptr_t, SignOutParams>
|
||||
{
|
||||
public:
|
||||
explicit SignOutRequest()
|
||||
: Request(methodName, {})
|
||||
{}
|
||||
using Request::Request;
|
||||
constexpr static const char methodName[] = "signOut";
|
||||
};
|
||||
|
||||
} // namespace Copilot
|
@@ -85,5 +85,6 @@ Project {
|
||||
"vcsbase/vcsbase.qbs",
|
||||
"webassembly/webassembly.qbs",
|
||||
"welcome/welcome.qbs"
|
||||
"copilot/copilot.qbs"
|
||||
].concat(project.additionalPlugins)
|
||||
}
|
||||
|
Reference in New Issue
Block a user