CodeAssist: Fix auto completion if function signature is shown

This reverts

    commit 3bf19030ab.
    CodeAssist: Fragile proposals aren't closed by automatic proposals.

which fixed the case [1] but introduced the regression in case [2]. Re-
implement the fix for [1] in a different way: Check whether the new
proposal has any items to show before closing the function signature
hint.

Case [1]
  void f(int);
  void g()
  {
      f(bar // This is what we will have in the end. The steps are:
            // 1. Type "f("
            //    --> OK, function signature pop up is shown.
            // 2. Type "bar"
            //    --> OPS, function signature pop up is closed and no
            //        new completion list is shown because "bar" does
            //        not match any declarations.
  }

Case [2]
  int barman = 0;
  void f(int);
  void g()
  {
      f(bar // This is what we will have in the end. The steps are:
            // 1. Type "f("
            //    --> OK, function signature pop up is shown.
            // 2. Type "bar"
            //    --> OPS, no auto completion list for "barman" is
            //        proposed.
  }

Task-number: QTCREATORBUG-16934
Change-Id: I8456275d951de9e6fc53285a5dbcbd448d49ad08
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
Nikolai Kosjar
2017-04-27 15:44:37 +02:00
parent a4a78ae8b1
commit fab4dd068e
7 changed files with 108 additions and 57 deletions

View File

@@ -145,8 +145,65 @@ void GenericProposalModel::loadContent(const QList<AssistProposalItemInterface *
m_idByText.insert(m_originalItems.at(i)->text(), i);
}
bool GenericProposalModel::hasItemsToPropose(const QString &prefix, AssistReason reason) const
{
return size() != 0 && (keepPerfectMatch(reason) || !isPerfectMatch(prefix));
}
static QString cleanText(const QString &original)
{
QString clean = original;
int ignore = 0;
for (int i = clean.length() - 1; i >= 0; --i, ++ignore) {
const QChar &c = clean.at(i);
if (c.isLetterOrNumber() || c == QLatin1Char('_')
|| c.isHighSurrogate() || c.isLowSurrogate()) {
break;
}
}
if (ignore)
clean.chop(ignore);
return clean;
}
bool GenericProposalModel::isPerfectMatch(const QString &prefix) const
{
if (prefix.isEmpty())
return false;
for (int i = 0; i < size(); ++i) {
const QString &current = cleanText(text(i));
if (!current.isEmpty()) {
CaseSensitivity cs = TextEditorSettings::completionSettings().m_caseSensitivity;
if (cs == TextEditor::CaseSensitive) {
if (prefix == current)
return true;
} else if (cs == TextEditor::CaseInsensitive) {
if (prefix.compare(current, Qt::CaseInsensitive) == 0)
return true;
} else if (cs == TextEditor::FirstLetterCaseSensitive) {
if (prefix.at(0) == current.at(0)
&& prefix.midRef(1).compare(current.midRef(1), Qt::CaseInsensitive) == 0)
return true;
}
}
}
return false;
}
bool GenericProposalModel::isPrefiltered(const QString &prefix) const
{
return !m_prefilterPrefix.isEmpty() && prefix == m_prefilterPrefix;
}
void GenericProposalModel::setPrefilterPrefix(const QString &prefix)
{
m_prefilterPrefix = prefix;
}
void GenericProposalModel::reset()
{
m_prefilterPrefix.clear();
m_currentItems = m_originalItems;
}