[education/rkward] /: Small cleanups and fixes to code completion
Thomas Friedrichsmeier
null at kde.org
Sat Sep 20 12:11:13 BST 2025
Git commit fa9fad62d70e2c7dfa11b365a3cf1b99c0c17cfb by Thomas Friedrichsmeier.
Committed on 20/09/2025 at 11:10.
Pushed by tfry into branch 'master'.
Small cleanups and fixes to code completion
M +3 -0 ChangeLog
M +14 -27 rkward/windows/rkcodecompletion.cpp
M +1 -4 rkward/windows/rkcodecompletion.h
https://invent.kde.org/education/rkward/-/commit/fa9fad62d70e2c7dfa11b365a3cf1b99c0c17cfb
diff --git a/ChangeLog b/ChangeLog
index 3a7df1455..b8a5d9b71 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,7 @@
--- Version 0.8.2 - UNRELEASED
+- Adeed: Allow to show kate plugin provided code completion lists (e.g. snippets or project plugin)
+- Fixed: Code completion hints would sometimes be misplaced to top-left cursor position
+- Fixed: Call hint did not show active function along with arguments
- Changed: R backend now uses UTF-8 mode on Windows
- Added: options(error) may now be set freely (no longer needs to be .rk.do.error for correct behavior)
- Fixed: Attached windows would not always be placed in the most recently active pane (in a split view)
diff --git a/rkward/windows/rkcodecompletion.cpp b/rkward/windows/rkcodecompletion.cpp
index 117396027..3122151c7 100644
--- a/rkward/windows/rkcodecompletion.cpp
+++ b/rkward/windows/rkcodecompletion.cpp
@@ -60,7 +60,11 @@ RKCompletionManager::RKCompletionManager(KTextEditor::View *view, const RKCodeCo
update_call = true;
cached_position = KTextEditor::Cursor(-1, -1);
+ // NOTE: I just can't seem to make the object name completion model play nice with automatic invocation.
+ // so, instead, we will want to invoke _all_ registered models, ourselves
view->setAutomaticInvocationEnabled(false);
+ builtin_completion_models = view->codeCompletionModels();
+
completion_model = new RKCodeCompletionModel(this);
file_completion_model = new RKFileCompletionModel(this);
callhint_model = new RKCallHintModel(this);
@@ -71,19 +75,11 @@ RKCompletionManager::RKCompletionManager(KTextEditor::View *view, const RKCodeCo
connect(completion_timer, &QTimer::timeout, this, &RKCompletionManager::tryCompletion);
connect(view->document(), &KTextEditor::Document::textInserted, this, &RKCompletionManager::textInserted);
connect(view->document(), &KTextEditor::Document::textRemoved, this, &RKCompletionManager::textRemoved);
- connect(view->document(), &KTextEditor::Document::lineWrapped, this, &RKCompletionManager::lineWrapped);
- connect(view->document(), &KTextEditor::Document::lineUnwrapped, this, &RKCompletionManager::lineUnwrapped);
connect(view, &KTextEditor::View::cursorPositionChanged, this, &RKCompletionManager::cursorPositionChanged);
const QObjectList children = _view->children();
for (QObjectList::const_iterator it = children.constBegin(); it != children.constEnd(); ++it) {
(*it)->installEventFilter(this); // to handle Tab-key; installing on the view, alone, is not enough.
}
-
- // HACK: I just can't see to make the object name completion model play nice with automatic invocation.
- // However, there is no official way to invoke all registered models, manually. So we try to hack our way
- // to a pointer to the default kate keyword completion model
- kate_keyword_completion_model = KTextEditor::Editor::instance()->findChild<KTextEditor::CodeCompletionModel *>();
- if (!kate_keyword_completion_model) kate_keyword_completion_model = view->findChild<KTextEditor::CodeCompletionModel *>(QString());
}
RKCompletionManager::~RKCompletionManager() {
@@ -267,12 +263,10 @@ void RKCompletionManager::updateCallHint() {
}
void RKCompletionManager::startModel(KTextEditor::CodeCompletionModel *model, bool start, const KTextEditor::Range &range) {
- if (start) {
- if (!range.isValid()) start = false;
- }
- if (start) {
+ if (start && range.isValid() && !range.isEmpty()) {
if (!started_models.contains(model)) {
- _view->startCompletion(range, model);
+ // TODO: should merge these calls for several models at once
+ _view->startCompletion(range, QList<KTextEditor::CodeCompletionModel *>({model}), user_triggered ? KTextEditor::CodeCompletionModel::ManualInvocation : KTextEditor::CodeCompletionModel::AutomaticInvocation);
started_models.append(model);
}
auto ci = dynamic_cast<KTextEditor::CodeCompletionModelControllerInterface *>(model);
@@ -292,10 +286,12 @@ void RKCompletionManager::updateVisibility() {
bool min_len = (currentCompletionWord().length() >= settings->autoMinChars()) || user_triggered;
startModel(completion_model, min_len && settings->isEnabled(RKCodeCompletionSettings::Object), symbol_range);
startModel(file_completion_model, min_len && settings->isEnabled(RKCodeCompletionSettings::Filename), symbol_range);
- if (kate_keyword_completion_model && settings->isEnabled(RKCodeCompletionSettings::AutoWord)) {
- // Model needs to update, first, as we have not handled it in tryCompletion:
- if (min_len) kate_keyword_completion_model->completionInvoked(view(), symbol_range, KTextEditor::CodeCompletionModel::ManualInvocation);
- startModel(kate_keyword_completion_model, min_len, symbol_range);
+ if (settings->isEnabled(RKCodeCompletionSettings::AutoWord)) {
+ for (auto model : std::as_const(builtin_completion_models)) {
+ // Model needs to update, first, as we have not handled it in tryCompletion:
+ if (min_len) model->completionInvoked(view(), symbol_range, KTextEditor::CodeCompletionModel::AutomaticInvocation);
+ startModel(model, min_len, symbol_range);
+ }
}
// NOTE: Freaky bug in KF 5.44.0: Call hint will not show for the first time, if logically above the primary screen. TODO: provide patch for kateargumenthinttree.cpp:166pp
startModel(callhint_model, settings->isEnabled(RKCodeCompletionSettings::Calltip), currentCallRange());
@@ -326,16 +322,6 @@ void RKCompletionManager::textRemoved(KTextEditor::Document *, const KTextEditor
tryCompletionProxy();
}
-void RKCompletionManager::lineWrapped(KTextEditor::Document *, const KTextEditor::Cursor &) {
- // should already have been handled by textInserted()
- tryCompletionProxy();
-}
-
-void RKCompletionManager::lineUnwrapped(KTextEditor::Document *, int) {
- // should already have been handled by textRemoved()
- tryCompletionProxy();
-}
-
void RKCompletionManager::cursorPositionChanged(KTextEditor::View *view, const KTextEditor::Cursor &newPosition) {
if (_view->isCompletionActive()) {
if (newPosition < call_opening) update_call = true;
@@ -733,6 +719,7 @@ void RKCallHintModel::setFunction(RObject *_function) {
if (function && function->isType(RObject::Function)) {
// initialize hint
RFunctionObject *fo = static_cast<RFunctionObject *>(function);
+ name = fo->getFullName();
QStringList args = fo->argumentNames();
QStringList defs = fo->argumentDefaults();
diff --git a/rkward/windows/rkcodecompletion.h b/rkward/windows/rkcodecompletion.h
index befb809dc..2645d44f1 100644
--- a/rkward/windows/rkcodecompletion.h
+++ b/rkward/windows/rkcodecompletion.h
@@ -44,8 +44,6 @@ class RKCompletionManager : public QObject {
public Q_SLOTS:
void userTriggeredCompletion();
private Q_SLOTS:
- void lineWrapped(KTextEditor::Document *document, const KTextEditor::Cursor &position);
- void lineUnwrapped(KTextEditor::Document *document, int line);
void textInserted(KTextEditor::Document *document, const KTextEditor::Cursor &position, const QString &text);
void textRemoved(KTextEditor::Document *document, const KTextEditor::Range &range, const QString &text);
void cursorPositionChanged(KTextEditor::View *view, const KTextEditor::Cursor &newPosition);
@@ -64,7 +62,7 @@ class RKCompletionManager : public QObject {
RKFileCompletionModel *file_completion_model;
RKCallHintModel *callhint_model;
RKArgumentHintModel *arghint_model;
- KTextEditor::CodeCompletionModel *kate_keyword_completion_model;
+ QList<KTextEditor::CodeCompletionModel *> builtin_completion_models;
QTimer *completion_timer;
const RKCodeCompletionSettings *settings;
@@ -95,7 +93,6 @@ class RKCompletionModelBase : public KTextEditor::CodeCompletionModel, public KT
QString filterString(KTextEditor::View *, const KTextEditor::Range &, const KTextEditor::Cursor &) override { return QString(); };
bool shouldAbortCompletion(KTextEditor::View *, const KTextEditor::Range &, const QString &) override { return false; }
- KTextEditor::CodeCompletionModelControllerInterface::MatchReaction matchingItem(const QModelIndex &) override { return KTextEditor::CodeCompletionModelControllerInterface::None; };
void executeCompletionItem(KTextEditor::View *view, const KTextEditor::Range &word, const QModelIndex &index) const override;
int rowCount(const QModelIndex &parent) const override;
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
More information about the rkward-tracker
mailing list