reformat in uvosstyle

This commit is contained in:
2023-11-02 21:40:24 +01:00
parent c73f72f8c2
commit fc0ca71b4d
4 changed files with 225 additions and 225 deletions

View File

@ -26,218 +26,219 @@
K_PLUGIN_FACTORY_WITH_JSON(KateAiPluginFactory, "kateai.json", registerPlugin<KateAiPlugin>();)
KateAiPlugin::KateAiPlugin(QObject *parent, const QList<QVariant> &)
: KTextEditor::Plugin(parent), m_serverUrl(QStringLiteral("ws://localhost:8642"))
: KTextEditor::Plugin(parent), m_serverUrl(QStringLiteral("ws://localhost:8642"))
{
connect(&m_webSocket, &QWebSocket::connected, this, &KateAiPlugin::onConnected);
readConfig();
connect(&m_webSocket, &QWebSocket::connected, this, &KateAiPlugin::onConnected);
readConfig();
}
void KateAiPlugin::onConnected()
{
qDebug()<<__func__<<m_webSocket.isValid();
qDebug()<<__func__<<m_webSocket.isValid();
}
KateAiPlugin::~KateAiPlugin() = default;
void KateAiPlugin::reconnect()
{
m_webSocket.close();
m_webSocket.open(m_serverUrl);
m_webSocket.close();
m_webSocket.open(m_serverUrl);
}
QObject *KateAiPlugin::createView(KTextEditor::MainWindow *mainWindow)
{
auto view = new KateAiPluginView(this, mainWindow, &m_webSocket);
connect(view, &KateAiPluginView::reconnect, this, &KateAiPlugin::reconnect);
return view;
auto view = new KateAiPluginView(this, mainWindow, &m_webSocket);
connect(view, &KateAiPluginView::reconnect, this, &KateAiPlugin::reconnect);
return view;
}
KTextEditor::ConfigPage *KateAiPlugin::configPage(int number, QWidget *parent)
{
if (number != 0)
return nullptr;
if (number != 0)
return nullptr;
return new KateAiConfigPage(parent, this);
return new KateAiConfigPage(parent, this);
}
void KateAiPlugin::readConfig()
{
KConfigGroup config(KSharedConfig::openConfig(), "Ai");
m_serverUrl = QUrl(config.readEntry("Url", "ws://localhost:8642"));
reconnect();
KConfigGroup config(KSharedConfig::openConfig(), "Ai");
m_serverUrl = QUrl(config.readEntry("Url", "ws://localhost:8642"));
reconnect();
}
KateAiPluginView::KateAiPluginView(KateAiPlugin *plugin, KTextEditor::MainWindow *mainwindow, QPointer<QWebSocket> webSocket, bool instruct)
: QObject(plugin)
, m_mainWindow(mainwindow)
, m_webSocket(webSocket)
, m_useInstruct(instruct)
KateAiPluginView::KateAiPluginView(KateAiPlugin *plugin, KTextEditor::MainWindow *mainwindow,
QPointer<QWebSocket> webSocket, bool instruct)
: QObject(plugin)
, m_mainWindow(mainwindow)
, m_webSocket(webSocket)
, m_useInstruct(instruct)
{
KXMLGUIClient::setComponentName(QStringLiteral("kateaiplugin"), QStringLiteral("Git Blame"));
setXMLFile(QStringLiteral("ui.rc"));
QAction *generateAction = actionCollection()->addAction(QStringLiteral("ai_generate"));
generateAction->setText(QStringLiteral("Generate text using AI"));
actionCollection()->setDefaultShortcut(generateAction, QKeySequence(Qt::CTRL | Qt::ALT | Qt::Key_A));
m_mainWindow->guiFactory()->addClient(this);
KXMLGUIClient::setComponentName(QStringLiteral("kateaiplugin"), QStringLiteral("Git Blame"));
setXMLFile(QStringLiteral("ui.rc"));
QAction *generateAction = actionCollection()->addAction(QStringLiteral("ai_generate"));
generateAction->setText(QStringLiteral("Generate text using AI"));
actionCollection()->setDefaultShortcut(generateAction, QKeySequence(Qt::CTRL | Qt::ALT | Qt::Key_A));
m_mainWindow->guiFactory()->addClient(this);
connect(generateAction, &QAction::triggered, this, &KateAiPluginView::generate);
connect(m_webSocket, &QWebSocket::textMessageReceived, this, &KateAiPluginView::socketMessage);
connect(generateAction, &QAction::triggered, this, &KateAiPluginView::generate);
connect(m_webSocket, &QWebSocket::textMessageReceived, this, &KateAiPluginView::socketMessage);
}
QPointer<KTextEditor::Document> KateAiPluginView::activeDocument() const
{
KTextEditor::View *view = m_mainWindow->activeView();
if(view && view->document())
return view->document();
return nullptr;
KTextEditor::View *view = m_mainWindow->activeView();
if(view && view->document())
return view->document();
return nullptr;
}
KTextEditor::Cursor KateAiPluginView::getCurrentCursor() const
{
KTextEditor::View *view = m_mainWindow->activeView();
if(view)
return view->cursorPosition();
return KTextEditor::Cursor();
KTextEditor::View *view = m_mainWindow->activeView();
if(view)
return view->cursorPosition();
return KTextEditor::Cursor();
}
void KateAiPluginView::socketMessage(const QString& message)
{
QJsonDocument jsonDocument = QJsonDocument::fromJson(message.toUtf8());
QJsonValue idVal = jsonDocument[QStringLiteral("request_id")];
if(!idVal.isDouble())
{
qDebug()<<"Got invalid response on socket";
return;
}
int id = idVal.toInt();
QJsonDocument jsonDocument = QJsonDocument::fromJson(message.toUtf8());
QJsonValue idVal = jsonDocument[QStringLiteral("request_id")];
if(!idVal.isDouble())
{
qDebug()<<"Got invalid response on socket";
return;
}
int id = idVal.toInt();
QHash<int, Request>::iterator it = m_requests.find(id);
if(it != m_requests.end())
{
QJsonValue responseValue = jsonDocument[QStringLiteral("response")];
if(!responseValue.isString())
{
qDebug()<<"Got invalid response on socket";
return;
}
if(it.value().document)
it.value().document->insertText(it.value().cursor, responseValue.toString());
m_requests.erase(it);
}
QHash<int, Request>::iterator it = m_requests.find(id);
if(it != m_requests.end())
{
QJsonValue responseValue = jsonDocument[QStringLiteral("response")];
if(!responseValue.isString())
{
qDebug()<<"Got invalid response on socket";
return;
}
if(it.value().document)
it.value().document->insertText(it.value().cursor, responseValue.toString());
m_requests.erase(it);
}
}
QStringList KateAiPluginView::getIncludePaths(const QString& text)
{
QStringList lines = text.split(U'\n');
QStringList paths;
QStringList lines = text.split(U'\n');
QStringList paths;
for(const QString& line : lines)
{
if(line.trimmed().startsWith(QStringLiteral("#include")))
{
int start = line.indexOf(U'<');
int end;
if(start != -1)
{
end = line.indexOf(U'>', start+1);
if(end == -1)
continue;
}
else
{
start = line.indexOf(U'"');
if(start == -1)
continue;
for(const QString& line : lines)
{
if(line.trimmed().startsWith(QStringLiteral("#include")))
{
int start = line.indexOf(U'<');
int end;
if(start != -1)
{
end = line.indexOf(U'>', start+1);
if(end == -1)
continue;
}
else
{
start = line.indexOf(U'"');
if(start == -1)
continue;
end = line.indexOf(U'"', start+1);
if(end == -1)
continue;
}
paths.push_back(line.mid(start+1, (end-(start+1))).trimmed());
}
}
return paths;
end = line.indexOf(U'"', start+1);
if(end == -1)
continue;
}
paths.push_back(line.mid(start+1, (end-(start+1))).trimmed());
}
}
return paths;
}
QString KateAiPluginView::assembleContext(QPointer<KTextEditor::Document> document, const KTextEditor::Cursor& cursor)
{
QString mime = document->mimeType();
QString context;
QString baseText;
QString mime = document->mimeType();
QString context;
QString baseText;
if(!m_useInstruct)
baseText = document->text(KTextEditor::Range(KTextEditor::Cursor(0, 0), cursor));
else
baseText = document->text();
if(mime == QStringLiteral("text/x-c++src") || mime == QStringLiteral("text/x-csrc"))
{
QFileInfo documentFileInfo(document->url().path());
QString directory = documentFileInfo.absolutePath();
QStringList paths = getIncludePaths(baseText);
qDebug()<<__func__<<"Directory:"<<directory<<"Paths:"<<paths;
if(!m_useInstruct)
baseText = document->text(KTextEditor::Range(KTextEditor::Cursor(0, 0), cursor));
else
baseText = document->text();
if(mime == QStringLiteral("text/x-c++src") || mime == QStringLiteral("text/x-csrc"))
{
QFileInfo documentFileInfo(document->url().path());
QString directory = documentFileInfo.absolutePath();
QStringList paths = getIncludePaths(baseText);
qDebug()<<__func__<<"Directory:"<<directory<<"Paths:"<<paths;
for(QString& path : paths)
{
path = directory + QDir::separator() + path;
qDebug()<<path;
QFile file(path);
if(!file.isOpen())
continue;
QByteArray fileData = file.readAll();
QString fileText = QString::fromUtf8(fileData);
context.append(fileText);
}
}
for(QString& path : paths)
{
path = directory + QDir::separator() + path;
qDebug()<<path;
QFile file(path);
if(!file.isOpen())
continue;
QByteArray fileData = file.readAll();
QString fileText = QString::fromUtf8(fileData);
context.append(fileText);
}
}
context.append(baseText);
context.append(baseText);
return context;
return context;
}
void KateAiPluginView::generate()
{
qDebug()<<activeDocument()->mimeType();
if(m_webSocket && m_webSocket->isValid())
{
KTextEditor::Cursor cursor = getCurrentCursor();
QPointer<KTextEditor::Document> document = activeDocument();
QString text = assembleContext(document, cursor);
int id = QRandomGenerator::global()->bounded(0, std::numeric_limits<int>::max());
qDebug()<<activeDocument()->mimeType();
if(m_webSocket && m_webSocket->isValid())
{
KTextEditor::Cursor cursor = getCurrentCursor();
QPointer<KTextEditor::Document> document = activeDocument();
QString text = assembleContext(document, cursor);
int id = QRandomGenerator::global()->bounded(0, std::numeric_limits<int>::max());
QJsonObject json;
json[QStringLiteral("action")] = QStringLiteral("infer");
json[QStringLiteral("request_id")] = id;
json[QStringLiteral("text")] = text;
json[QStringLiteral("max_new_tokens")] = 50;
json[QStringLiteral("stream")] = false;
QJsonObject json;
json[QStringLiteral("action")] = QStringLiteral("infer");
json[QStringLiteral("request_id")] = id;
json[QStringLiteral("text")] = text;
json[QStringLiteral("max_new_tokens")] = 50;
json[QStringLiteral("stream")] = false;
QJsonDocument jsonDocument(json);
QString requestText = QString::fromUtf8(jsonDocument.toJson(QJsonDocument::JsonFormat::Compact));
qDebug()<<__func__<<' '<<requestText;
m_webSocket->sendTextMessage(requestText);
m_requests.insert(id, {cursor, document});
}
else
{
QMessageBox box;
box.setText(i18n("The AI server is not connected."));
box.setInformativeText(i18n("would you like to try and reconnect?"));
box.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
box.setDefaultButton(QMessageBox::Yes);
int ret = box.exec();
if(ret == QMessageBox::Yes)
reconnect();
}
QJsonDocument jsonDocument(json);
QString requestText = QString::fromUtf8(jsonDocument.toJson(QJsonDocument::JsonFormat::Compact));
qDebug()<<__func__<<' '<<requestText;
m_webSocket->sendTextMessage(requestText);
m_requests.insert(id, {cursor, document});
}
else
{
QMessageBox box;
box.setText(i18n("The AI server is not connected."));
box.setInformativeText(i18n("would you like to try and reconnect?"));
box.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
box.setDefaultButton(QMessageBox::Yes);
int ret = box.exec();
if(ret == QMessageBox::Yes)
reconnect();
}
}
KateAiPluginView::~KateAiPluginView()
{
m_mainWindow->guiFactory()->removeClient(this);
m_mainWindow->guiFactory()->removeClient(this);
}
void KateAiPluginView::setInstruct(bool instruct)
{
m_useInstruct = instruct;
m_useInstruct = instruct;
}
#include "kateai.moc"

View File

@ -15,62 +15,61 @@
class KateAiPlugin : public KTextEditor::Plugin
{
Q_OBJECT
Q_OBJECT
private:
QWebSocket m_webSocket;
QUrl m_serverUrl;
QWebSocket m_webSocket;
QUrl m_serverUrl;
private:
void onConnected();
void onConnected();
int configPages() const override
{
return 1;
}
int configPages() const override
{
return 1;
}
KTextEditor::ConfigPage *configPage(int number = 0, QWidget *parent = nullptr) override;
KTextEditor::ConfigPage *configPage(int number = 0, QWidget *parent = nullptr) override;
public:
explicit KateAiPlugin(QObject *parent = nullptr, const QList<QVariant> & = QList<QVariant>());
~KateAiPlugin() override;
explicit KateAiPlugin(QObject *parent = nullptr, const QList<QVariant> & = QList<QVariant>());
~KateAiPlugin() override;
QObject *createView(KTextEditor::MainWindow *mainWindow) override;
QObject *createView(KTextEditor::MainWindow *mainWindow) override;
void readConfig();
void reconnect();
Q_SIGNAL void instructChanged();
void readConfig();
void reconnect();
Q_SIGNAL void instructChanged();
};
class KateAiPluginView : public QObject, public KXMLGUIClient
{
Q_OBJECT
Q_OBJECT
private:
struct Request
{
KTextEditor::Cursor cursor;
QPointer<KTextEditor::Document> document;
};
KTextEditor::MainWindow *m_mainWindow;
QPointer<QWebSocket> m_webSocket;
QHash<int, Request> m_requests;
bool m_useInstruct = false;
struct Request
{
KTextEditor::Cursor cursor;
QPointer<KTextEditor::Document> document;
};
KTextEditor::MainWindow *m_mainWindow;
QPointer<QWebSocket> m_webSocket;
QHash<int, Request> m_requests;
bool m_useInstruct = false;
private:
void generate();
void socketMessage(const QString& message);
static QStringList getIncludePaths(const QString& text);
QString assembleContext(QPointer<KTextEditor::Document> document, const KTextEditor::Cursor& cursor);
QPointer<KTextEditor::Document> activeDocument() const;
KTextEditor::Cursor getCurrentCursor() const;
void generate();
void socketMessage(const QString& message);
static QStringList getIncludePaths(const QString& text);
QString assembleContext(QPointer<KTextEditor::Document> document, const KTextEditor::Cursor& cursor);
QPointer<KTextEditor::Document> activeDocument() const;
KTextEditor::Cursor getCurrentCursor() const;
public:
KateAiPluginView(KateAiPlugin *plugin, KTextEditor::MainWindow *mainwindow, QPointer<QWebSocket> webSocket, bool instruct = false);
~KateAiPluginView() override;
void setInstruct(bool instruct);
KateAiPluginView(KateAiPlugin *plugin, KTextEditor::MainWindow *mainwindow, QPointer<QWebSocket> webSocket,
bool instruct = false);
~KateAiPluginView() override;
void setInstruct(bool instruct);
Q_SIGNAL void reconnect();
Q_SIGNAL void reconnect();
};

View File

@ -9,57 +9,57 @@
#include <qlabel.h>
KateAiConfigPage::KateAiConfigPage(QWidget *parent, KateAiPlugin *plugin)
: KTextEditor::ConfigPage(parent)
, m_plugin(plugin)
: KTextEditor::ConfigPage(parent)
, m_plugin(plugin)
{
QVBoxLayout* layout = new QVBoxLayout(this);
layout->setContentsMargins(0, 0, 0, 0);
QVBoxLayout* layout = new QVBoxLayout(this);
layout->setContentsMargins(0, 0, 0, 0);
QHBoxLayout* lineLayout = new QHBoxLayout(this);
QLabel* lineEditLabel = new QLabel(i18n("Url for the WebSockets ExLlama Ai server:"), this);
lineEditLabel->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
lineLayout->addWidget(lineEditLabel);
lineLayout->addWidget(&lineUrl);
layout->addLayout(lineLayout);
QHBoxLayout* lineLayout = new QHBoxLayout(this);
QLabel* lineEditLabel = new QLabel(i18n("Url for the WebSockets ExLlama Ai server:"), this);
lineEditLabel->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
lineLayout->addWidget(lineEditLabel);
lineLayout->addWidget(&lineUrl);
layout->addLayout(lineLayout);
btnCompletion.setText(i18n("Use the Ai to generate a completion"));
btnInstruct.setText(i18n("Use the Ai to insert a response to a instruction"));
layout->addWidget(&btnCompletion);
layout->addWidget(&btnInstruct);
layout->addStretch();
btnCompletion.setText(i18n("Use the Ai to generate a completion"));
btnInstruct.setText(i18n("Use the Ai to insert a response to a instruction"));
layout->addWidget(&btnCompletion);
layout->addWidget(&btnInstruct);
layout->addStretch();
reset();
reset();
}
QString KateAiConfigPage::name() const
{
return i18n("Ai");
return i18n("Ai");
}
QString KateAiConfigPage::fullName() const
{
return i18n("Ai Settings");
return i18n("Ai Settings");
}
QIcon KateAiConfigPage::icon() const
{
return QIcon::fromTheme(QStringLiteral("text-x-generic"));
return QIcon::fromTheme(QStringLiteral("text-x-generic"));
}
void KateAiConfigPage::apply()
{
KConfigGroup config(KSharedConfig::openConfig(), "Ai");
config.writeEntry("Url", lineUrl.text());
config.writeEntry("Instruct", btnInstruct.isChecked());
KConfigGroup config(KSharedConfig::openConfig(), "Ai");
config.writeEntry("Url", lineUrl.text());
config.writeEntry("Instruct", btnInstruct.isChecked());
config.sync();
m_plugin->readConfig();
config.sync();
m_plugin->readConfig();
}
void KateAiConfigPage::reset()
{
KConfigGroup config(KSharedConfig::openConfig(), "Ai");
lineUrl.setText(config.readEntry("Url", "ws://localhost:8642"));
btnInstruct.setChecked(config.readEntry("Instruct", false));
btnCompletion.setChecked(!btnInstruct.isChecked());
KConfigGroup config(KSharedConfig::openConfig(), "Ai");
lineUrl.setText(config.readEntry("Url", "ws://localhost:8642"));
btnInstruct.setChecked(config.readEntry("Instruct", false));
btnCompletion.setChecked(!btnInstruct.isChecked());
}

View File

@ -8,26 +8,26 @@
class KateAiConfigPage : public KTextEditor::ConfigPage
{
Q_OBJECT
Q_OBJECT
private:
QLineEdit lineUrl;
QRadioButton btnCompletion;
QRadioButton btnInstruct;
KateAiPlugin* m_plugin;
QLineEdit lineUrl;
QRadioButton btnCompletion;
QRadioButton btnInstruct;
KateAiPlugin* m_plugin;
public:
explicit KateAiConfigPage(QWidget *parent = nullptr, KateAiPlugin *plugin = nullptr);
~KateAiConfigPage() override
{
}
explicit KateAiConfigPage(QWidget *parent = nullptr, KateAiPlugin *plugin = nullptr);
~KateAiConfigPage() override
{
}
QString name() const override;
QString fullName() const override;
QIcon icon() const override;
QString name() const override;
QString fullName() const override;
QIcon icon() const override;
void apply() override;
void reset() override;
void defaults() override
{
}
void apply() override;
void reset() override;
void defaults() override
{
}
};