Add tab-completion for usernames
fixes #394
2 files changed, 49 insertions, 11 deletions
diff --git a/src/TextInputWidget.cpp b/src/TextInputWidget.cpp
index 897e2a76..f3b0f4be 100644
--- a/src/TextInputWidget.cpp
+++ b/src/TextInputWidget.cpp
@@ -107,7 +107,7 @@ FilteredTextEdit::showResults(const QVector<SearchResult> &results)
{
QPoint pos;
- if (atTriggerPosition_ != -1) {
+ if (isAnchorValid()) {
auto cursor = textCursor();
cursor.setPosition(atTriggerPosition_);
pos = viewport()->mapToGlobal(cursorRect(cursor).topLeft());
@@ -134,7 +134,7 @@ FilteredTextEdit::keyPressEvent(QKeyEvent *event)
}
// calculate the new query
- if (textCursor().position() < atTriggerPosition_ || atTriggerPosition_ == -1) {
+ if (textCursor().position() < atTriggerPosition_ || !isAnchorValid()) {
resetAnchor();
closeSuggestions();
}
@@ -165,9 +165,31 @@ FilteredTextEdit::keyPressEvent(QKeyEvent *event)
switch (event->key()) {
case Qt::Key_At:
atTriggerPosition_ = textCursor().position();
+ anchorType_ = AnchorType::Sigil;
QTextEdit::keyPressEvent(event);
break;
+ case Qt::Key_Tab: {
+ auto cursor = textCursor();
+ const int initialPos = cursor.position();
+
+ cursor.movePosition(QTextCursor::StartOfWord, QTextCursor::KeepAnchor);
+ auto word = cursor.selectedText();
+
+ const int startOfWord = cursor.position();
+
+ // There is a word to complete.
+ if (initialPos != startOfWord) {
+ atTriggerPosition_ = startOfWord;
+ anchorType_ = AnchorType::Tab;
+
+ emit showSuggestions(word);
+ } else {
+ QTextEdit::keyPressEvent(event);
+ }
+
+ break;
+ }
case Qt::Key_Return:
case Qt::Key_Enter:
if (!(event->modifiers() & Qt::ShiftModifier)) {
@@ -213,26 +235,27 @@ FilteredTextEdit::keyPressEvent(QKeyEvent *event)
default:
QTextEdit::keyPressEvent(event);
- // Check if the current word should be autocompleted.
- auto cursor = textCursor();
- cursor.movePosition(QTextCursor::StartOfWord, QTextCursor::KeepAnchor);
- auto word = cursor.selectedText();
+ if (isModifier)
+ return;
- if (cursor.position() == 0) {
+ if (textCursor().position() == 0) {
resetAnchor();
closeSuggestions();
return;
}
- if (cursor.position() == atTriggerPosition_ + 1) {
- const auto q = query();
+ // Check if the current word should be autocompleted.
+ auto cursor = textCursor();
+ cursor.movePosition(QTextCursor::StartOfWord, QTextCursor::KeepAnchor);
+ auto word = cursor.selectedText();
- if (q.isEmpty()) {
+ if (hasAnchor(cursor.position(), anchorType_) && isAnchorValid()) {
+ if (word.isEmpty()) {
closeSuggestions();
return;
}
- emit showSuggestions(query());
+ emit showSuggestions(word);
} else {
resetAnchor();
closeSuggestions();
diff --git a/src/TextInputWidget.h b/src/TextInputWidget.h
index e7d5f948..37d73fbb 100644
--- a/src/TextInputWidget.h
+++ b/src/TextInputWidget.h
@@ -94,8 +94,23 @@ private:
SuggestionsPopup popup_;
+ enum class AnchorType
+ {
+ Tab = 0,
+ Sigil = 1,
+ };
+
+ AnchorType anchorType_ = AnchorType::Sigil;
+
+ int anchorWidth(AnchorType anchor) { return static_cast<int>(anchor); }
+
void closeSuggestions() { popup_.hide(); }
void resetAnchor() { atTriggerPosition_ = -1; }
+ bool isAnchorValid() { return atTriggerPosition_ != -1; }
+ bool hasAnchor(int pos, AnchorType anchor)
+ {
+ return pos == atTriggerPosition_ + anchorWidth(anchor);
+ }
QString query()
{
|