[rkward/work/unified_hinting2] rkward/windows: Add argument name hinting, some minor fixes.
Thomas Friedrichsmeier
null at kde.org
Fri Feb 15 21:07:55 GMT 2019
Git commit 28ade2f661bd4b4da8025ced3a3f8e3ba68f32ee by Thomas Friedrichsmeier.
Committed on 15/02/2019 at 21:07.
Pushed by tfry into branch 'work/unified_hinting2'.
Add argument name hinting, some minor fixes.
M +102 -3 rkward/windows/rkcommandeditorwindow.cpp
M +21 -0 rkward/windows/rkcommandeditorwindow.h
https://commits.kde.org/rkward/28ade2f661bd4b4da8025ced3a3f8e3ba68f32ee
diff --git a/rkward/windows/rkcommandeditorwindow.cpp b/rkward/windows/rkcommandeditorwindow.cpp
index 82bee964..a2e79feb 100644
--- a/rkward/windows/rkcommandeditorwindow.cpp
+++ b/rkward/windows/rkcommandeditorwindow.cpp
@@ -1197,6 +1197,7 @@ RKCompletionManager::RKCompletionManager (KTextEditor::View* view) : QObject (vi
completion_model = new RKCodeCompletionModel (this);
file_completion_model = new RKFileCompletionModel (this);
callhint_model = new RKCallHintModel (this);
+ arghint_model = new RKArgumentHintModel (this);
cc_iface->registerCompletionModel (callhint_model);
completion_timer = new QTimer (this);
completion_timer->setSingleShot (true);
@@ -1276,6 +1277,24 @@ void RKCompletionManager::tryCompletion () {
}
updateCallHint ();
+
+ // update ArgHint.
+ argname_range = KTextEditor::Range (-1, -1, -1, -1);
+ // Named arguments are just like regular symbols, *but* we must require that they are preceeded by either a ',', or the opening '(', immediately.
+ // Otherwise, they are an argument value expression, for sure.
+ if (callhint_model->currentFunction ()) {
+ for (int i = symbol_range.start ().column () - 1; i >= 0; --i) {
+ QChar c = current_line.at (i);
+ if (c == ',' || c == '(') {
+ argname_range = symbol_range;
+ break;
+ } else if (!c.isSpace ()) {
+ break;
+ }
+ }
+ }
+ arghint_model->updateCompletionList (callhint_model->currentFunction (), argname_range.isValid () ? doc->text (argname_range) : QString ());
+
updateVisibility ();
}
@@ -1350,9 +1369,14 @@ void RKCompletionManager::updateVisibility () {
bool min_len = (currentCompletionWord ().length () >= RKSettingsModuleCommandEditor::completionMinChars ());
startModel (cc_iface, completion_model, min_len, symbol_range, &active_models);
startModel (cc_iface, file_completion_model, min_len, symbol_range, &active_models);
- if (kate_keyword_completion_model) startModel (cc_iface, kate_keyword_completion_model, min_len, symbol_range, &active_models);
+ if (kate_keyword_completion_model) {
+ // 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 (cc_iface, kate_keyword_completion_model, min_len, symbol_range, &active_models);
+ }
// 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 (cc_iface, callhint_model, true, currentCallRange (), &active_models);
+ startModel (cc_iface, arghint_model, true, argname_range, &active_models);
if (!active_models.isEmpty ()) {
active = true;
@@ -1487,14 +1511,14 @@ void RKCodeCompletionModel::executeCompletionItem (KTextEditor::View *view, cons
RK_TRACE (COMMANDEDITOR);
RK_ASSERT (names.size () > index.row ());
-
- view->document ()->replaceText (word, names[index.row ()]);
+ view->document ()->replaceText (word, names.value (index.row ()));
}
QVariant RKCodeCompletionModel::data (const QModelIndex& index, int role) const {
if (isHeaderItem (index)) {
if (role == Qt::DisplayRole) return i18n ("Objects on search path");
if (role == KTextEditor::CodeCompletionModel::GroupRole) return Qt::DisplayRole;
+ if (role == KTextEditor::CodeCompletionModel::InheritanceDepth) return 1; // sort below arghint model
return QVariant ();
}
@@ -1599,6 +1623,80 @@ KTextEditor::Range RKCallHintModel::completionRange (KTextEditor::View *, const
return manager->currentCallRange ();
}
+//////////////////////// RKArgumentHintModel //////////////////////
+RKArgumentHintModel::RKArgumentHintModel (RKCompletionManager* manager) : RKCompletionModelBase (manager) {
+ RK_TRACE (COMMANDEDITOR);
+
+ function = 0;
+}
+
+void RKArgumentHintModel::updateCompletionList (RObject* _function, const QString &argument) {
+ RK_TRACE (COMMANDEDITOR);
+
+ bool changed = false;
+ if (function != _function) {
+ beginResetModel ();
+ function = _function;
+ if (function && function->isType (RObject::Function)) {
+ // initialize hint
+ RFunctionObject *fo = static_cast<RFunctionObject*> (function);
+ args = fo->argumentNames ();
+ defs = fo->argumentDefaults ();
+ } else {
+ args.clear ();
+ defs.clear ();
+ }
+ }
+
+ if (changed || (argument != fragment)) {
+ if (!changed) {
+ changed = true;
+ beginResetModel ();
+ }
+ fragment = argument;
+ matches.clear ();
+ for (int i = 0; i < args.size (); ++i) {
+ if (args[i].startsWith (fragment)) matches.append (i);
+ }
+ }
+
+ if (changed) {
+ n_completions = matches.size ();
+ endResetModel ();
+ }
+}
+
+QVariant RKArgumentHintModel::data (const QModelIndex& index, int role) const {
+ if (isHeaderItem (index)) {
+ if (role == Qt::DisplayRole) return i18n ("Function arguments");
+ if (role == KTextEditor::CodeCompletionModel::GroupRole) return Qt::DisplayRole;
+ if (role == KTextEditor::CodeCompletionModel::InheritanceDepth) return 0; // Sort above other models (except calltip)
+ return QVariant ();
+ }
+
+ int col = index.column ();
+ int row = index.row ();
+ if (role == Qt::DisplayRole) {
+ if (col == KTextEditor::CodeCompletionModel::Name) return (args.value (matches.value (row)));
+ if (col == KTextEditor::CodeCompletionModel::Postfix) {
+ QString def = defs.value (matches.value (row));
+ if (!def.isEmpty ()) return (QString ('=' + def));
+ }
+ } else if (role == KTextEditor::CodeCompletionModel::InheritanceDepth) {
+ return row; // disable sorting
+ } else if (role == KTextEditor::CodeCompletionModel::CompletionRole) {
+ return KTextEditor::CodeCompletionModel::Function;
+ } else if (role == KTextEditor::CodeCompletionModel::MatchQuality) {
+ return (20);
+ }
+
+ return QVariant ();
+}
+
+KTextEditor::Range RKArgumentHintModel::completionRange (KTextEditor::View*, const KTextEditor::Cursor&) {
+ return manager->currentArgnameRange ();
+}
+
//////////////////////// RKFileCompletionModel ////////////////////
#include <KUrlCompletion>
RKFileCompletionModelWorker::RKFileCompletionModelWorker (const QString &_string) : QThread () {
@@ -1672,6 +1770,7 @@ QVariant RKFileCompletionModel::data (const QModelIndex& index, int role) const
if (isHeaderItem (index)) {
if (role == Qt::DisplayRole) return i18n ("Local file names");
if (role == KTextEditor::CodeCompletionModel::GroupRole) return Qt::DisplayRole;
+ if (role == KTextEditor::CodeCompletionModel::InheritanceDepth) return 1; // Sort below arghint model
return QVariant ();
}
diff --git a/rkward/windows/rkcommandeditorwindow.h b/rkward/windows/rkcommandeditorwindow.h
index c7c41c0d..297a1031 100644
--- a/rkward/windows/rkcommandeditorwindow.h
+++ b/rkward/windows/rkcommandeditorwindow.h
@@ -107,6 +107,7 @@ private:
class RKCodeCompletionModel;
class RKFileCompletionModel;
class RKCallHintModel;
+class RKArgumentHintModel;
class RKCompletionManager : public QObject {
Q_OBJECT
public:
@@ -115,6 +116,7 @@ public:
QString currentCompletionWord () const;
KTextEditor::Range currentSymbolRange () const { return symbol_range; };
+ KTextEditor::Range currentArgnameRange () const { return argname_range; };
KTextEditor::Range currentCallRange () const;
KTextEditor::View* view () const { return (_view); };
private slots:
@@ -134,6 +136,7 @@ private:
RKCodeCompletionModel *completion_model;
RKFileCompletionModel *file_completion_model;
RKCallHintModel *callhint_model;
+ RKArgumentHintModel *arghint_model;
KTextEditor::CodeCompletionModel* kate_keyword_completion_model;
QTimer *completion_timer;
@@ -142,6 +145,7 @@ private:
KTextEditor::Range symbol_range;
KTextEditor::Cursor call_opening;
+ KTextEditor::Range argname_range;
bool update_call;
bool active;
@@ -201,6 +205,7 @@ public:
QVariant data (const QModelIndex& index, int role=Qt::DisplayRole) const override;
KTextEditor::Range completionRange (KTextEditor::View *view, const KTextEditor::Cursor &position) override;
+ RObject *currentFunction () const { return function; };
private:
RObject *function;
QString name;
@@ -208,6 +213,22 @@ private:
QVariantList formatting;
};
+class RKArgumentHintModel : public RKCompletionModelBase {
+ Q_OBJECT
+public:
+ explicit RKArgumentHintModel (RKCompletionManager *manager);
+ void updateCompletionList (RObject *function, const QString& argument);
+
+ QVariant data (const QModelIndex& index, int role=Qt::DisplayRole) const override;
+ KTextEditor::Range completionRange (KTextEditor::View *view, const KTextEditor::Cursor &position) override;
+private:
+ RObject *function;
+ QStringList args;
+ QStringList defs;
+ QString fragment;
+ QList<int> matches;
+};
+
#include <QThread>
class RKFileCompletionModelWorker : public QThread {
Q_OBJECT
More information about the rkward-tracker
mailing list