[education/rkward] rkward/windows: Some early experiments with integrating dynamic competions.

Thomas Friedrichsmeier null at kde.org
Wed Oct 5 16:33:03 BST 2022


Git commit 992f3cdb80b582d2fc0b57037646db25afc6f297 by Thomas Friedrichsmeier.
Committed on 16/07/2022 at 16:28.
Pushed by tfry into branch 'master'.

Some early experiments with integrating dynamic competions.

M  +53   -1    rkward/windows/rkcodecompletion.cpp
M  +13   -0    rkward/windows/rkcodecompletion.h

https://invent.kde.org/education/rkward/commit/992f3cdb80b582d2fc0b57037646db25afc6f297

diff --git a/rkward/windows/rkcodecompletion.cpp b/rkward/windows/rkcodecompletion.cpp
index c282f9c3..72c93530 100644
--- a/rkward/windows/rkcodecompletion.cpp
+++ b/rkward/windows/rkcodecompletion.cpp
@@ -22,6 +22,8 @@ SPDX-License-Identifier: GPL-2.0-or-later
 #include "../core/rfunctionobject.h"
 #include "../core/robjectlist.h"
 #include "../settings/rksettingsmodulecommandeditor.h"
+#include "../rbackend/rcommand.h"
+#include "../rbackend/rkrinterface.h"
 
 #include "../debug.h"
 
@@ -718,7 +720,8 @@ KTextEditor::Range RKCallHintModel::completionRange (KTextEditor::View *, const
 RKArgumentHintModel::RKArgumentHintModel (RKCompletionManager* manager) : RKCompletionModelBase (manager) {
 	RK_TRACE (COMMANDEDITOR);
 
-	function = 0;
+	function = nullptr;
+	r_completions_function = nullptr;
 }
 
 void RKArgumentHintModel::updateCompletionList (RObject* _function, const QString &argument) {
@@ -733,10 +736,13 @@ void RKArgumentHintModel::updateCompletionList (RObject* _function, const QStrin
 			// initialize hint
 			RFunctionObject *fo = static_cast<RFunctionObject*> (function);
 			args = fo->argumentNames ();
+			n_formals_args = args.size();
 			defs = fo->argumentDefaults ();
+			fetchRCompletions();
 		} else {
 			args.clear ();
 			defs.clear ();
+			n_formals_args = 0;
 		}
 	}
 
@@ -760,6 +766,51 @@ void RKArgumentHintModel::updateCompletionList (RObject* _function, const QStrin
 	}
 }
 
+void RKArgumentHintModel::fetchRCompletions() {
+	RK_TRACE(COMMANDEDITOR);
+	r_completions_function = function;
+	RCommand *command = new RCommand("local({\n"
+	                                 "	f <- function(fname) {\n"
+	                                 "		oldrcs <- utils::rc.settings()\n"
+	                                 "		oldrcopts <- utils::rc.options()\n"
+	                                 "		on.exit({do.call(utils::rc.settings, as.list(oldrcs)); utils::rc.options(oldrcopts)})\n"
+	                                 "		utils::rc.settings(ops=FALSE, ns=FALSE, args=TRUE, dots=FALSE, func=FALSE, ipck=FALSE, S3=TRUE, data=FALSE, help=FALSE, argdb=TRUE, fuzzy=FALSE, quotes=FALSE, files=FALSE)\n"
+	                                 "		utils::rc.options(funarg.suffix=\"\")\n"
+	                                 "		utils:::.assignLinebuffer(paste0(fname, \"(\"))\n"
+	                                 "		utils:::.assignToken(\"\")\n"
+	                                 "		utils:::.assignStart(nchar(fname)+1)\n"
+	                                 "		utils:::.assignEnd(nchar(fname)+1)\n"
+	                                 "		utils:::.completeToken()\n"
+	                                 "		utils:::.retrieveCompletions()\n"
+	                                 "	}\n"
+	                                 "	f(\"plot\")\n"
+	                                 "})\n", RCommand::Sync | RCommand::PriorityCommand | RCommand::GetStringVector);
+	command->whenFinished(this, [this](RCommand *command) {
+		if (r_completions_function != function) {
+			QTimer::singleShot(0, this, &RKArgumentHintModel::fetchRCompletions);
+			return;
+		}
+		if (command->getDataType() == RCommand::StringVector) {
+			QStringList nargs;
+			auto rargs = command->stringVector();
+			for (int i = 0; i < rargs.size(); ++i) {
+				if (!args.contains(rargs.at(i))) {
+					nargs.append(rargs.at(i));
+				}
+			}
+			if (!nargs.isEmpty()) {
+				beginInsertRows(index(0, 0, QModelIndex()), args.size(), args.size()+nargs.size());
+				args.append(nargs);
+				endInsertRows();
+			}
+		} else {
+			RK_ASSERT(false);
+		}
+		r_completions_function = nullptr;
+	});
+	RInterface::issueCommand(command);
+}
+
 QVariant RKArgumentHintModel::data (const QModelIndex& index, int role) const {
 	if (isHeaderItem (index)) {
 		if (role == Qt::DisplayRole) return i18n ("Function arguments");
@@ -781,6 +832,7 @@ QVariant RKArgumentHintModel::data (const QModelIndex& index, int role) const {
 	} else if (role == KTextEditor::CodeCompletionModel::CompletionRole) {
 		return KTextEditor::CodeCompletionModel::Function;
 	} else if (role == KTextEditor::CodeCompletionModel::MatchQuality) {
+		if (matches.value(row) >= n_formals_args) return (0);  // Argument names returned from R completion. This could be _lot_ (S3), so lower priority
 		return (20);
 	}
 
diff --git a/rkward/windows/rkcodecompletion.h b/rkward/windows/rkcodecompletion.h
index 9b9211f8..d67a30d0 100644
--- a/rkward/windows/rkcodecompletion.h
+++ b/rkward/windows/rkcodecompletion.h
@@ -151,9 +151,12 @@ public:
 private:
 	RObject *function;
 	QStringList args;
+	int n_formals_args;
 	QStringList defs;
 	QString fragment;
 	QList<int> matches;
+	void fetchRCompletions();
+	RObject *r_completions_function;
 };
 
 #include <QThread>
@@ -187,4 +190,14 @@ private:
 	RKFileCompletionModelWorker *worker;
 };
 
+/*
+class RKRDynamicCompletionModel : public KTextEditor::CodeCompletionModel, public KTextEditor::CodeCompletionModelControllerInterface {
+	Q_OBJECT
+public:
+	RKRDynamicCompletionModel(RKCompletionManager *manager);
+	void setFunction(RObject *function);
+private:
+	bool waiting_for_reply;
+}; */
+
 #endif



More information about the rkward-tracker mailing list