From 05bb8e9e30169f160bc9159ed9d0945f78298e4d Mon Sep 17 00:00:00 2001 From: Andre Hartmann Date: Sat, 2 Feb 2019 21:14:07 +0100 Subject: [PATCH] DocumentContentCompletion: Don't propose word under cursor ... unless it is already contained in the text. For the following text: Lorem ipsum dolor sit amet, consetetur sadipscing elitr. Typing "con|" now should only provide "consetetur" as proposal, as "con" is just currently typed and therefore no valid completion. This avoids pressing line down before the first valid proposal is available. The exception is, if "con" would already be used elsewhere in the text. Change-Id: I7034f4b2b2ebe70e98acc616fb7590118faac0af Reviewed-by: David Schulz --- .../codeassist/documentcontentcompletion.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/plugins/texteditor/codeassist/documentcontentcompletion.cpp b/src/plugins/texteditor/codeassist/documentcontentcompletion.cpp index 437afcbdb6c..ee0deab71c7 100644 --- a/src/plugins/texteditor/codeassist/documentcontentcompletion.cpp +++ b/src/plugins/texteditor/codeassist/documentcontentcompletion.cpp @@ -80,17 +80,26 @@ DocumentContentCompletionProcessor::~DocumentContentCompletionProcessor() m_watcher.cancel(); } -static void createProposal(QFutureInterface &future, const QString text) +static void createProposal(QFutureInterface &future, const QString &text, + const QString &wordUnderCursor) { const QRegularExpression wordRE("([a-zA-Z_][a-zA-Z0-9_]{2,})"); QSet words; QRegularExpressionMatchIterator it = wordRE.globalMatch(text); + int wordUnderCursorFound = 0; while (it.hasNext()) { if (future.isCanceled()) return; QRegularExpressionMatch match = it.next(); const QString &word = match.captured(); + if (word == wordUnderCursor) { + // Only add the word under cursor if it + // already appears elsewhere in the text + if (++wordUnderCursorFound < 2) + continue; + } + if (!words.contains(word)) words.insert(word); } @@ -113,16 +122,18 @@ IAssistProposal *DocumentContentCompletionProcessor::perform(const AssistInterfa } while (chr.isLetterOrNumber() || chr == '_'); ++pos; + int length = interface->position() - pos; if (interface->reason() == IdleEditor) { QChar characterUnderCursor = interface->characterAt(interface->position()); - if (characterUnderCursor.isLetterOrNumber() || interface->position() - pos < 3) + if (characterUnderCursor.isLetterOrNumber() || length < 3) return nullptr; } + const QString wordUnderCursor = interface->textAt(pos, length); const QString text = interface->textDocument()->toPlainText(); - m_watcher.setFuture(Utils::runAsync(&createProposal, text)); + m_watcher.setFuture(Utils::runAsync(&createProposal, text, wordUnderCursor)); QObject::connect(&m_watcher, &QFutureWatcher::resultReadyAt, &m_watcher, [this, pos](int index){ const TextEditor::SnippetAssistCollector snippetCollector(