169 lines
4.8 KiB
C++
169 lines
4.8 KiB
C++
#ifndef OLLIE_KATE_PLUGIN_H
|
|
#define OLLIE_KATE_PLUGIN_H
|
|
|
|
#include <KTextEditor/Plugin>
|
|
#include <KTextEditor/ConfigPage>
|
|
#include <KTextEditor/MainWindow>
|
|
#include <KTextEditor/View>
|
|
#if QT_VERSION_MAJOR >= 6
|
|
#include <KPluginMetaData>
|
|
#endif
|
|
|
|
#include <QProcess>
|
|
#include <QPointer>
|
|
#include <QTextBrowser>
|
|
#include <QPlainTextEdit>
|
|
#include <QLabel>
|
|
#include <QAction>
|
|
#include <QEvent>
|
|
#include <QStandardPaths>
|
|
#include <KTextEditor/MovingRange>
|
|
#include <KTextEditor/Attribute>
|
|
|
|
#include "chat_renderer.h"
|
|
|
|
class QPushButton;
|
|
class OllieKateView;
|
|
class OllieGhostProvider;
|
|
|
|
class OllieKatePlugin : public KTextEditor::Plugin
|
|
{
|
|
Q_OBJECT
|
|
|
|
public:
|
|
#if QT_VERSION_MAJOR >= 6
|
|
explicit OllieKatePlugin(QObject *parent, const KPluginMetaData &data, const QVariantList &args = {});
|
|
#else
|
|
explicit OllieKatePlugin(QObject *parent, const QVariantList &args = {});
|
|
#endif
|
|
~OllieKatePlugin() override = default;
|
|
|
|
QObject *createView(KTextEditor::MainWindow *mainWindow) override;
|
|
int configPages() const override;
|
|
KTextEditor::ConfigPage *configPage(int number, QWidget *parent) override;
|
|
|
|
// Completion config accessors
|
|
QString completionBackend() const;
|
|
QString completionModel() const;
|
|
void setCompletionBackend(const QString &backend);
|
|
void setCompletionModel(const QString &model);
|
|
bool completionEnabled() const;
|
|
void setCompletionEnabled(bool enabled);
|
|
|
|
// Default session backend/model (overrides OLLIE_BACKEND / OLLIE_MODEL)
|
|
QString defaultBackend() const;
|
|
QString defaultModel() const;
|
|
void setDefaultBackend(const QString &backend);
|
|
void setDefaultModel(const QString &model);
|
|
|
|
// Diff view mode: "unified", "side-by-side", "raw"
|
|
QString diffMode() const;
|
|
void setDiffMode(const QString &mode);
|
|
|
|
private:
|
|
void loadConfig();
|
|
void saveConfig();
|
|
|
|
QString m_completionBackend;
|
|
QString m_completionModel;
|
|
bool m_completionEnabled = true;
|
|
QString m_defaultBackend;
|
|
QString m_defaultModel;
|
|
QString m_diffMode;
|
|
};
|
|
|
|
class OllieKateView : public QObject
|
|
{
|
|
Q_OBJECT
|
|
|
|
public:
|
|
explicit OllieKateView(OllieKatePlugin *plugin, KTextEditor::MainWindow *mainWindow);
|
|
~OllieKateView() override;
|
|
|
|
OllieKatePlugin *plugin() const { return m_plugin; }
|
|
|
|
protected:
|
|
bool eventFilter(QObject *obj, QEvent *event) override;
|
|
|
|
private slots:
|
|
void onChatUpdated(const QString &session_id, qlonglong offset, const QString &new_text);
|
|
void onStateChanged(const QString &session_id, const QString &new_state);
|
|
void onSessionCreated(const QString &session_id);
|
|
void onSessionKilled(const QString &session_id);
|
|
|
|
void submitPrompt();
|
|
void askAboutFile();
|
|
void explainSelection();
|
|
void newSession();
|
|
void pickSession();
|
|
void renameSession();
|
|
void refreshSessions();
|
|
|
|
private:
|
|
void ensureSession();
|
|
QString activeSessionId();
|
|
|
|
OllieKatePlugin *m_plugin;
|
|
KTextEditor::MainWindow *m_mainWindow;
|
|
QWidget *m_toolView;
|
|
QLabel *m_sessionLabel;
|
|
QLabel *m_cwdLabel;
|
|
QLabel *m_completionStatus;
|
|
QTextBrowser *m_chatView;
|
|
QPlainTextEdit *m_promptInput;
|
|
QAction *m_askFileAction;
|
|
QAction *m_explainAction;
|
|
QAction *m_newSessionAction;
|
|
QPushButton *m_stopBtn;
|
|
QPushButton *m_scrollBottomBtn;
|
|
|
|
// 9P helpers
|
|
QByteArray run9p(const QStringList &args);
|
|
void write9p(const QString &path, const QByteArray &data);
|
|
QString serverAddr();
|
|
QString agentPath();
|
|
|
|
// Streaming processes
|
|
QProcess *m_chatProc = nullptr;
|
|
QProcess *m_stateProc = nullptr;
|
|
void startChatStream();
|
|
void startStateStream();
|
|
void stopStreams();
|
|
|
|
QString m_sessionId;
|
|
qlonglong m_chatOffset = 0;
|
|
QString m_rawChat; // accumulated raw chat text
|
|
ChatRenderer *m_renderer;
|
|
QStringList m_diffBlocks; // stored diff content for viewer
|
|
|
|
void showDiffBlock(int index);
|
|
void onAnchorClicked(const QUrl &url);
|
|
|
|
QPointer<OllieGhostProvider> m_ghost;
|
|
bool m_ghostPrefix = false; // true after Meta+O, waiting for second key
|
|
|
|
void processEmojis();
|
|
|
|
QString projectBaseDir();
|
|
void switchToSession(const QString &sessionId);
|
|
void setupGhostProvider();
|
|
|
|
// --- Editor Integration ---
|
|
void setupContextMenu(KTextEditor::View *view);
|
|
void setupGitPlusPlusDiffAction();
|
|
void submitSelectionPrompt(const QString &action);
|
|
void reviewDiff();
|
|
void applyCodeBlock(int index);
|
|
void clearAnnotations();
|
|
void annotateFileReferences(const QString &chatText);
|
|
|
|
QList<ChatRenderer::ApplyBlock> m_applyBlocks;
|
|
bool m_loadingOlder = false; // guard against recursive scroll-triggered loads
|
|
|
|
// Inline annotations (MovingRanges highlighting lines the agent references)
|
|
QList<KTextEditor::MovingRange *> m_annotations;
|
|
QPointer<KTextEditor::Document> m_annotationDoc;
|
|
};
|
|
|
|
#endif // OLLIE_KATE_PLUGIN_H
|