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 <david.schulz@qt.io>
This commit is contained in:
Andre Hartmann
2019-02-02 21:14:07 +01:00
committed by André Hartmann
parent 55f4c28889
commit 05bb8e9e30

View File

@@ -80,17 +80,26 @@ DocumentContentCompletionProcessor::~DocumentContentCompletionProcessor()
m_watcher.cancel();
}
static void createProposal(QFutureInterface<QStringList> &future, const QString text)
static void createProposal(QFutureInterface<QStringList> &future, const QString &text,
const QString &wordUnderCursor)
{
const QRegularExpression wordRE("([a-zA-Z_][a-zA-Z0-9_]{2,})");
QSet<QString> 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<QStringList>::resultReadyAt,
&m_watcher, [this, pos](int index){
const TextEditor::SnippetAssistCollector snippetCollector(