[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