kate: config page improvements, status bar dedup, default backend/model

- Add Default Backend / Default Model config for chat sessions
  (overrides OLLIE_BACKEND / OLLIE_MODEL env vars)
- Pass configured backend/model to CreateSession D-Bus call
- Move "Completion enabled on startup" checkbox below text fields
- Deduplicate status bar indicator when multiple views exist
- Make install target depend on build
- Remove Escape-to-dismiss (conflicts with Kate popups)
This commit is contained in:
Levi Neely 2026-07-14 14:53:13 +02:00
parent b67e82dca0
commit 18402a2be7
3 changed files with 102 additions and 9 deletions

View File

@ -24,7 +24,7 @@ kf5:
# --- KF6 Install (default) ---
install:
install: build
@echo "=== Installing ollie-kde (KF6) ==="
# Binaries
install -m755 $(BUILD_DIR)/ollie-tray /usr/bin/

View File

@ -18,6 +18,7 @@
#include <QFileInfo>
#include <QInputDialog>
#include <QScrollBar>
#include <QCheckBox>
#include <QFormLayout>
#include <QMainWindow>
#include <QStatusBar>
@ -71,25 +72,49 @@ KTextEditor::ConfigPage *OllieKatePlugin::configPage(int number, QWidget *parent
: KTextEditor::ConfigPage(parent), m_plugin(plugin)
{
auto *layout = new QFormLayout(this);
// Default session backend/model
m_defaultBackendEdit = new QLineEdit(this);
m_defaultBackendEdit->setPlaceholderText(QStringLiteral("(use OLLIE_BACKEND)"));
m_defaultModelEdit = new QLineEdit(this);
m_defaultModelEdit->setPlaceholderText(QStringLiteral("(use OLLIE_MODEL)"));
layout->addRow(QStringLiteral("Default backend:"), m_defaultBackendEdit);
layout->addRow(QStringLiteral("Default model:"), m_defaultModelEdit);
auto *defaultNote = new QLabel(
QStringLiteral("Override OLLIE_BACKEND / OLLIE_MODEL for chat sessions."),
this);
defaultNote->setWordWrap(true);
defaultNote->setStyleSheet(QStringLiteral("color: gray;"));
layout->addRow(defaultNote);
// Completion backend/model
m_backendEdit = new QLineEdit(this);
m_backendEdit->setPlaceholderText(QStringLiteral("(use server default)"));
m_backendEdit->setPlaceholderText(QStringLiteral("(use OLLIE_COMPLETE_BACKEND)"));
m_modelEdit = new QLineEdit(this);
m_modelEdit->setPlaceholderText(QStringLiteral("(use server default)"));
m_modelEdit->setPlaceholderText(QStringLiteral("(use OLLIE_COMPLETE_MODEL)"));
layout->addRow(QStringLiteral("Completion backend:"), m_backendEdit);
layout->addRow(QStringLiteral("Completion model:"), m_modelEdit);
auto *note = new QLabel(
QStringLiteral("Leave blank to use the server's OLLIE_COMPLETE_BACKEND / OLLIE_COMPLETE_MODEL."),
QStringLiteral("Override OLLIE_COMPLETE_BACKEND / OLLIE_COMPLETE_MODEL for ghost text."),
this);
note->setWordWrap(true);
note->setStyleSheet(QStringLiteral("color: gray;"));
layout->addRow(note);
m_enabledCheck = new QCheckBox(QStringLiteral("Completion enabled on startup"), this);
layout->addRow(m_enabledCheck);
reset();
connect(m_enabledCheck, &QCheckBox::toggled, this, &ConfigPage::changed);
connect(m_backendEdit, &QLineEdit::textChanged, this, &ConfigPage::changed);
connect(m_modelEdit, &QLineEdit::textChanged, this, &ConfigPage::changed);
connect(m_defaultBackendEdit, &QLineEdit::textChanged, this, &ConfigPage::changed);
connect(m_defaultModelEdit, &QLineEdit::textChanged, this, &ConfigPage::changed);
}
QString name() const override { return QStringLiteral("Ollie"); }
@ -97,22 +122,34 @@ KTextEditor::ConfigPage *OllieKatePlugin::configPage(int number, QWidget *parent
QIcon icon() const override { return QIcon::fromTheme(QStringLiteral("system-run")); }
void apply() override {
m_plugin->setDefaultBackend(m_defaultBackendEdit->text().trimmed());
m_plugin->setDefaultModel(m_defaultModelEdit->text().trimmed());
m_plugin->setCompletionBackend(m_backendEdit->text().trimmed());
m_plugin->setCompletionModel(m_modelEdit->text().trimmed());
m_plugin->setCompletionEnabled(m_enabledCheck->isChecked());
}
void reset() override {
m_defaultBackendEdit->setText(m_plugin->defaultBackend());
m_defaultModelEdit->setText(m_plugin->defaultModel());
m_backendEdit->setText(m_plugin->completionBackend());
m_modelEdit->setText(m_plugin->completionModel());
m_enabledCheck->setChecked(m_plugin->completionEnabled());
}
void defaults() override {
m_defaultBackendEdit->clear();
m_defaultModelEdit->clear();
m_backendEdit->clear();
m_modelEdit->clear();
m_enabledCheck->setChecked(true);
}
private:
OllieKatePlugin *m_plugin;
QLineEdit *m_defaultBackendEdit;
QLineEdit *m_defaultModelEdit;
QLineEdit *m_backendEdit;
QLineEdit *m_modelEdit;
QCheckBox *m_enabledCheck;
};
return new OllieConfigPage(this, parent);
@ -133,11 +170,37 @@ void OllieKatePlugin::setCompletionModel(const QString &model)
saveConfig();
}
bool OllieKatePlugin::completionEnabled() const { return m_completionEnabled; }
void OllieKatePlugin::setCompletionEnabled(bool enabled)
{
m_completionEnabled = enabled;
saveConfig();
}
QString OllieKatePlugin::defaultBackend() const { return m_defaultBackend; }
QString OllieKatePlugin::defaultModel() const { return m_defaultModel; }
void OllieKatePlugin::setDefaultBackend(const QString &backend)
{
m_defaultBackend = backend;
saveConfig();
}
void OllieKatePlugin::setDefaultModel(const QString &model)
{
m_defaultModel = model;
saveConfig();
}
void OllieKatePlugin::loadConfig()
{
KConfigGroup grp(KSharedConfig::openConfig(), QStringLiteral("Ollie"));
m_completionBackend = grp.readEntry("CompletionBackend", QString());
m_completionModel = grp.readEntry("CompletionModel", QString());
m_completionEnabled = grp.readEntry("CompletionEnabled", true);
m_defaultBackend = grp.readEntry("DefaultBackend", QString());
m_defaultModel = grp.readEntry("DefaultModel", QString());
}
void OllieKatePlugin::saveConfig()
@ -145,6 +208,9 @@ void OllieKatePlugin::saveConfig()
KConfigGroup grp(KSharedConfig::openConfig(), QStringLiteral("Ollie"));
grp.writeEntry("CompletionBackend", m_completionBackend);
grp.writeEntry("CompletionModel", m_completionModel);
grp.writeEntry("CompletionEnabled", m_completionEnabled);
grp.writeEntry("DefaultBackend", m_defaultBackend);
grp.writeEntry("DefaultModel", m_defaultModel);
grp.sync();
}
@ -187,11 +253,24 @@ OllieKateView::OllieKateView(OllieKatePlugin *plugin, KTextEditor::MainWindow *m
layout->addWidget(m_cwdLabel);
// Completion status indicator (in the main window status bar)
m_completionStatus = new QLabel(QStringLiteral("✦ completion on"));
m_completionStatus->setFont(smallFont);
m_completionStatus->setStyleSheet(QStringLiteral("color: green; padding: 0px 4px;"));
bool startEnabled = m_plugin->completionEnabled();
if (auto *win = qobject_cast<QMainWindow *>(m_mainWindow->window())) {
win->statusBar()->addPermanentWidget(m_completionStatus);
// Reuse existing widget if another view already created it
m_completionStatus = win->statusBar()->findChild<QLabel *>(QStringLiteral("ollie_completion_status"));
if (!m_completionStatus) {
m_completionStatus = new QLabel();
m_completionStatus->setObjectName(QStringLiteral("ollie_completion_status"));
m_completionStatus->setFont(smallFont);
win->statusBar()->addPermanentWidget(m_completionStatus);
}
m_completionStatus->setText(startEnabled
? QStringLiteral("✦ completion on")
: QStringLiteral("✦ completion off"));
m_completionStatus->setStyleSheet(startEnabled
? QStringLiteral("color: green; padding: 0px 4px;")
: QStringLiteral("color: gray; padding: 0px 4px;"));
} else {
m_completionStatus = nullptr;
}
// Button bar
@ -386,7 +465,9 @@ void OllieKateView::newSession()
cwd = QDir::homePath();
}
QDBusReply<QString> reply = m_iface->call("CreateSession", cwd, QString(), QString(), "default");
QString backend = m_plugin->defaultBackend();
QString model = m_plugin->defaultModel();
QDBusReply<QString> reply = m_iface->call("CreateSession", cwd, backend, model, "default");
if (reply.isValid()) {
m_sessionId = reply.value();
m_chatView->clear();
@ -605,6 +686,7 @@ void OllieKateView::setupGhostProvider()
// Create new ghost provider for the active view
m_ghost = new OllieGhostProvider(view, m_iface, m_plugin, view);
m_ghost->setEnabled(m_plugin->completionEnabled());
// Install event filter on the view widget for Tab interception
if (QWidget *proxy = view->focusProxy()) {

View File

@ -41,6 +41,14 @@ public:
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);
private:
void loadConfig();
@ -48,6 +56,9 @@ private:
QString m_completionBackend;
QString m_completionModel;
bool m_completionEnabled = true;
QString m_defaultBackend;
QString m_defaultModel;
};
class OllieKateView : public QObject