[rkward] rkward/windows: Make manual completion invocation more reliable.
Thomas Friedrichsmeier
null at kde.org
Fri Feb 22 21:14:09 GMT 2019
Git commit 264f6dd0cc6b75044e5faecbf535fb1bf2d2967d by Thomas Friedrichsmeier.
Committed on 22/02/2019 at 21:13.
Pushed by tfry into branch 'master'.
Make manual completion invocation more reliable.
M +33 -26 rkward/windows/rkcodecompletion.cpp
M +4 -3 rkward/windows/rkcodecompletion.h
https://commits.kde.org/rkward/264f6dd0cc6b75044e5faecbf535fb1bf2d2967d
diff --git a/rkward/windows/rkcodecompletion.cpp b/rkward/windows/rkcodecompletion.cpp
index cd66a076..f7d229c4 100644
--- a/rkward/windows/rkcodecompletion.cpp
+++ b/rkward/windows/rkcodecompletion.cpp
@@ -35,13 +35,33 @@
#include "../debug.h"
+class RKCompletionNotifierModel : public RKCompletionModelBase {
+public:
+ RKCompletionNotifierModel (RKCompletionManager *manager) : RKCompletionModelBase (manager) {};
+ KTextEditor::Range completionRange (KTextEditor::View *, const KTextEditor::Cursor &position) override {
+ return KTextEditor::Range (position, position);
+ }
+ /** reimplemented in order to receive notification, when completion is invoked by user shortcut. */
+ void completionInvoked (KTextEditor::View*, const KTextEditor::Range&, KTextEditor::CodeCompletionModel::InvocationType invocationType) override {
+ RK_TRACE (COMMANDEDITOR);
+
+ if (invocationType == KTextEditor::CodeCompletionModel::UserInvocation) {
+ // NOTE: Without this short timeout, the completion window will sometimes disappear, again, right away.
+ QTimer::singleShot (50, manager, SLOT(userTriggeredCompletion()));
+ }
+ }
+ QVariant data (const QModelIndex&, int) const override {
+ return QVariant ();
+ }
+};
+
//////////////////////// RKCompletionManager //////////////////////
RKCompletionManager::RKCompletionManager (KTextEditor::View* view) : QObject (view) {
RK_TRACE (COMMANDEDITOR);
_view = view;
- active = false;
+ keep_active = false;
user_triggered = false;
ignore_next_trigger = false;
update_call = true;
@@ -54,7 +74,7 @@ RKCompletionManager::RKCompletionManager (KTextEditor::View* view) : QObject (vi
file_completion_model = new RKFileCompletionModel (this);
callhint_model = new RKCallHintModel (this);
arghint_model = new RKArgumentHintModel (this);
- cc_iface->registerCompletionModel (completion_model); // (at least) one model needs to be registerd, so we will know, when completion was triggered by the user (shortcut)
+ cc_iface->registerCompletionModel (new RKCompletionNotifierModel (this)); // (at least) one model needs to be registerd, so we will know, when completion was triggered by the user (shortcut)
completion_timer = new QTimer (this);
completion_timer->setSingleShot (true);
connect (completion_timer, &QTimer::timeout, this, &RKCompletionManager::tryCompletion);
@@ -84,7 +104,7 @@ RKCompletionManager::~RKCompletionManager () {
}
void RKCompletionManager::tryCompletionProxy () {
- if (active) {
+ if (cc_iface->isCompletionActive () || keep_active) {
// Handle this in the next event cycle, as more than one event may trigger
completion_timer->start (0);
} else if (RKSettingsModuleCommandEditor::autoCompletionEnabled ()) {
@@ -106,7 +126,6 @@ void RKCompletionManager::userTriggeredCompletion () {
completion_timer->stop ();
tryCompletion ();
user_triggered = false;
- // NOTE: Sometimes (non-determinate) the completion window will disappear directly after this. It does not seem to be our fault, here, according to the tests I did.
}
void RKCompletionManager::tryCompletion () {
@@ -191,7 +210,7 @@ bool isCode (KTextEditor::Document* doc, int line, int column) {
void RKCompletionManager::updateCallHint () {
RK_TRACE (COMMANDEDITOR);
- if (active && !update_call) return;
+ if (cc_iface->isCompletionActive () && !update_call) return;
update_call = false;
int line = cached_position.line () + 1;
@@ -278,16 +297,13 @@ void RKCompletionManager::updateVisibility () {
startModel (cc_iface, callhint_model, true && RKSettingsModuleCommandEditor::isCompletionEnabled (RKSettingsModuleCommandEditor::Calltip), currentCallRange (), &active_models);
startModel (cc_iface, arghint_model, min_len && RKSettingsModuleCommandEditor::isCompletionEnabled (RKSettingsModuleCommandEditor::Arghint), argname_range, &active_models);
- if (!active_models.isEmpty ()) {
- active = true;
- } else {
+ if (active_models.isEmpty ()) {
cc_iface->abortCompletion ();
- active = false;
}
}
void RKCompletionManager::textInserted (KTextEditor::Document*, const KTextEditor::Cursor& position, const QString& text) {
- if (active) {
+ if (cc_iface->isCompletionActive ()) {
if (position < call_opening) update_call = true;
else if (text.contains (QChar ('(')) || text.contains (QChar (')'))) update_call = true;
}
@@ -295,7 +311,7 @@ void RKCompletionManager::textInserted (KTextEditor::Document*, const KTextEdito
}
void RKCompletionManager::textRemoved (KTextEditor::Document*, const KTextEditor::Range& range, const QString& text) {
- if (active) {
+ if (cc_iface->isCompletionActive ()) {
if (range.start () < call_opening) update_call = true;
else if (text.contains (QChar ('(')) || text.contains (QChar (')'))) update_call = true;
}
@@ -313,7 +329,7 @@ void RKCompletionManager::lineUnwrapped (KTextEditor::Document* , int ) {
}
void RKCompletionManager::cursorPositionChanged (KTextEditor::View* view, const KTextEditor::Cursor& newPosition) {
- if (active) {
+ if (cc_iface->isCompletionActive ()) {
if (newPosition < call_opening) update_call = true;
else {
QString text = view->document ()->text (KTextEditor::Range (newPosition, cached_position));
@@ -327,15 +343,16 @@ KTextEditor::Range RKCompletionManager::currentCallRange () const {
return KTextEditor::Range (call_opening, _view->cursorPosition ());
}
-bool RKCompletionManager::eventFilter (QObject* watched, QEvent* event) {
+bool RKCompletionManager::eventFilter (QObject*, QEvent* event) {
if (event->type () == QEvent::KeyPress || event->type () == QEvent::ShortcutOverride) {
RK_TRACE (COMMANDEDITOR); // avoid loads of empty traces, putting this here
QKeyEvent *k = static_cast<QKeyEvent *> (event);
// If only the calltip is active, make sure the tab-key and enter behave as a regular keys. There is no completion in this case.
if (active_models.count () == 1 && active_models[0] == callhint_model) {
- if ((k->key () == Qt::Key_Tab) || (k->key () == Qt::Key_Return) || (k->key () == Qt::Key_Enter) && (!k->modifiers ())) {
- cc_iface->abortCompletion (); // That's a bit lame, but the least hacky way to get the key into the document. Note that we keep active==true, so
+ if (((k->key () == Qt::Key_Tab) || (k->key () == Qt::Key_Return) || (k->key () == Qt::Key_Enter)) && (!k->modifiers ())) {
+ keep_active = true;
+ cc_iface->abortCompletion (); // That's a bit lame, but the least hacky way to get the key into the document. keep_active=true, so
// the completion window should come back up, without delay
return false;
}
@@ -370,7 +387,6 @@ bool RKCompletionManager::eventFilter (QObject* watched, QEvent* event) {
if (exact) {
// Ouch, how messy. We want to make sure completion stops, and is not re-triggered by the insertion, itself
active_models.clear ();
- active = false;
cc_iface->abortCompletion ();
if (RKSettingsModuleCommandEditor::autoCompletionEnabled ()) ignore_next_trigger = true;
}
@@ -399,7 +415,6 @@ bool RKCompletionManager::eventFilter (QObject* watched, QEvent* event) {
return true;
} else {
cc_iface->abortCompletion ();
- active = false;
return false;
}
}
@@ -481,7 +496,7 @@ void RKCodeCompletionModel::updateCompletionList (const QString& symbol) {
endResetModel ();
}
-KTextEditor::Range RKCodeCompletionModel::completionRange (KTextEditor::View *, const KTextEditor::Cursor&c) {
+KTextEditor::Range RKCodeCompletionModel::completionRange (KTextEditor::View *, const KTextEditor::Cursor&) {
return manager->currentSymbolRange ();
}
@@ -569,14 +584,6 @@ QString RKCodeCompletionModel::partialCompletion (bool* exact_match) {
return (findCommonCompletion (shortnames, lead, exact_match));
}
-void RKCodeCompletionModel::completionInvoked (KTextEditor::View* view, const KTextEditor::Range& range, KTextEditor::CodeCompletionModel::InvocationType invocationType) {
- RK_TRACE (COMMANDEDITOR);
-
- if (invocationType == KTextEditor::CodeCompletionModel::UserInvocation) {
- manager->userTriggeredCompletion ();
- }
-}
-
//////////////////////// RKCallHintModel //////////////////////////
RKCallHintModel::RKCallHintModel (RKCompletionManager* manager) : RKCompletionModelBase (manager) {
diff --git a/rkward/windows/rkcodecompletion.h b/rkward/windows/rkcodecompletion.h
index 16e2d091..c9857c6a 100644
--- a/rkward/windows/rkcodecompletion.h
+++ b/rkward/windows/rkcodecompletion.h
@@ -32,6 +32,8 @@ class RKCodeCompletionModel;
class RKFileCompletionModel;
class RKCallHintModel;
class RKArgumentHintModel;
+/** Provides code completions / hints for a KTextEditor::View . Several model are managed, here, with most of the common logic for parsing context, and starting completions is
+ * handled in this class. To use, simply construct a manager as child of the view to provide completions for. */
class RKCompletionManager : public QObject {
Q_OBJECT
public:
@@ -43,6 +45,7 @@ public:
KTextEditor::Range currentArgnameRange () const { return argname_range; };
KTextEditor::Range currentCallRange () const;
KTextEditor::View* view () const { return (_view); };
+public slots:
void userTriggeredCompletion ();
private slots:
void lineWrapped (KTextEditor::Document *document, const KTextEditor::Cursor &position);
@@ -74,7 +77,7 @@ private:
KTextEditor::Range argname_range;
bool update_call;
- bool active;
+ bool keep_active;
bool user_triggered;
bool ignore_next_trigger;
@@ -115,8 +118,6 @@ public:
~RKCodeCompletionModel ();
KTextEditor::Range completionRange (KTextEditor::View *view, const KTextEditor::Cursor &position) override;
- /** reimplemented in one of the models, in order to receive notification, when completion is invoked manually. */
- void completionInvoked (KTextEditor::View* view, const KTextEditor::Range& range, KTextEditor::CodeCompletionModel::InvocationType invocationType) override;
void updateCompletionList (const QString& symbol);
QVariant data (const QModelIndex& index, int role=Qt::DisplayRole) const override;
More information about the rkward-tracker
mailing list