summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/plugins/clangcodemodel/clanghoverhandler.cpp77
-rw-r--r--src/plugins/cpptools/cpptoolsreuse.cpp87
-rw-r--r--src/plugins/cpptools/cpptoolsreuse.h1
3 files changed, 79 insertions, 86 deletions
diff --git a/src/plugins/clangcodemodel/clanghoverhandler.cpp b/src/plugins/clangcodemodel/clanghoverhandler.cpp
index 58f414d9f1..c8e87c2577 100644
--- a/src/plugins/clangcodemodel/clanghoverhandler.cpp
+++ b/src/plugins/clangcodemodel/clanghoverhandler.cpp
@@ -93,79 +93,6 @@ ClangHoverHandler::~ClangHoverHandler()
abort();
}
-static int skipChars(QTextCursor *tc,
- QTextCursor::MoveOperation op,
- int offset,
- std::function<bool(const QChar &)> skip)
-{
- const QTextDocument *doc = tc->document();
- QChar ch = doc->characterAt(tc->position() + offset);
- if (ch.isNull())
- return 0;
- int count = 0;
- while (skip(ch)) {
- if (tc->movePosition(op))
- ++count;
- else
- break;
- ch = doc->characterAt(tc->position() + offset);
- }
- return count;
-}
-
-static int skipCharsForward(QTextCursor *tc, std::function<bool(const QChar &)> skip)
-{
- return skipChars(tc, QTextCursor::NextCharacter, 0, skip);
-}
-
-static int skipCharsBackward(QTextCursor *tc, std::function<bool(const QChar &)> skip)
-{
- return skipChars(tc, QTextCursor::PreviousCharacter, -1, skip);
-}
-
-static QStringList fallbackWords(QTextDocument *document, int pos)
-{
- const auto isSpace = [](const QChar &c) { return c.isSpace(); };
- const auto isColon = [](const QChar &c) { return c == ':'; };
- const auto isValidIdentifierChar = [document](const QTextCursor &tc) {
- return CppTools::isValidIdentifierChar(document->characterAt(tc.position()));
- };
- // move to the end
- QTextCursor endCursor(document);
- endCursor.setPosition(pos);
- do {
- CppTools::moveCursorToEndOfIdentifier(&endCursor);
- // possibly skip ::
- QTextCursor temp(endCursor);
- skipCharsForward(&temp, isSpace);
- const int colons = skipCharsForward(&temp, isColon);
- skipCharsForward(&temp, isSpace);
- if (colons == 2 && isValidIdentifierChar(temp))
- endCursor = temp;
- } while (isValidIdentifierChar(endCursor));
-
- QStringList results;
- QTextCursor startCursor(endCursor);
- do {
- CppTools::moveCursorToStartOfIdentifier(&startCursor);
- if (startCursor.position() == endCursor.position())
- break;
- QTextCursor temp(endCursor);
- temp.setPosition(startCursor.position(), QTextCursor::KeepAnchor);
- results.append(temp.selectedText().remove(QRegularExpression("\\s")));
- // possibly skip ::
- temp = startCursor;
- skipCharsBackward(&temp, isSpace);
- const int colons = skipCharsBackward(&temp, isColon);
- skipCharsBackward(&temp, isSpace);
- if (colons == 2
- && CppTools::isValidIdentifierChar(document->characterAt(temp.position() - 1))) {
- startCursor = temp;
- }
- } while (!isValidIdentifierChar(startCursor));
- return results;
-}
-
void ClangHoverHandler::identifyMatch(TextEditorWidget *editorWidget,
int pos,
BaseHoverHandler::ReportPriority report)
@@ -187,7 +114,9 @@ void ClangHoverHandler::identifyMatch(TextEditorWidget *editorWidget,
qCDebug(hoverLog) << "Requesting tooltip info at" << pos;
m_reportPriority = report;
m_futureWatcher.reset(new QFutureWatcher<CppTools::ToolTipInfo>());
- const QStringList fallback = fallbackWords(editorWidget->document(), pos);
+ QTextCursor tc(editorWidget->document());
+ tc.setPosition(pos);
+ const QStringList fallback = CppTools::identifierWordsUnderCursor(tc);
QObject::connect(m_futureWatcher.data(),
&QFutureWatcherBase::finished,
[this, fallback]() {
diff --git a/src/plugins/cpptools/cpptoolsreuse.cpp b/src/plugins/cpptools/cpptoolsreuse.cpp
index c56bfb9160..9bcf806b7d 100644
--- a/src/plugins/cpptools/cpptoolsreuse.cpp
+++ b/src/plugins/cpptools/cpptoolsreuse.cpp
@@ -41,6 +41,7 @@
#include <utils/qtcassert.h>
#include <QDebug>
+#include <QRegularExpression>
#include <QSet>
#include <QStringRef>
#include <QTextCursor>
@@ -50,29 +51,91 @@ using namespace CPlusPlus;
namespace CppTools {
-static void moveCursorToStartOrEndOfIdentifier(QTextCursor *tc,
- QTextCursor::MoveOperation op,
- int posDiff = 0)
+static int skipChars(QTextCursor *tc,
+ QTextCursor::MoveOperation op,
+ int offset,
+ std::function<bool(const QChar &)> skip)
{
- QTextDocument *doc = tc->document();
+ const QTextDocument *doc = tc->document();
if (!doc)
- return;
-
- QChar ch = doc->characterAt(tc->position() - posDiff);
- while (isValidIdentifierChar(ch)) {
- tc->movePosition(op);
- ch = doc->characterAt(tc->position() - posDiff);
+ return 0;
+ QChar ch = doc->characterAt(tc->position() + offset);
+ if (ch.isNull())
+ return 0;
+ int count = 0;
+ while (skip(ch)) {
+ if (tc->movePosition(op))
+ ++count;
+ else
+ break;
+ ch = doc->characterAt(tc->position() + offset);
}
+ return count;
+}
+
+static int skipCharsForward(QTextCursor *tc, std::function<bool(const QChar &)> skip)
+{
+ return skipChars(tc, QTextCursor::NextCharacter, 0, skip);
+}
+
+static int skipCharsBackward(QTextCursor *tc, std::function<bool(const QChar &)> skip)
+{
+ return skipChars(tc, QTextCursor::PreviousCharacter, -1, skip);
+}
+
+QStringList identifierWordsUnderCursor(const QTextCursor &tc)
+{
+ const QTextDocument *document = tc.document();
+ if (!document)
+ return {};
+ const auto isSpace = [](const QChar &c) { return c.isSpace(); };
+ const auto isColon = [](const QChar &c) { return c == ':'; };
+ const auto isValidIdentifierCharAt = [document](const QTextCursor &tc) {
+ return isValidIdentifierChar(document->characterAt(tc.position()));
+ };
+ // move to the end
+ QTextCursor endCursor(tc);
+ do {
+ moveCursorToEndOfIdentifier(&endCursor);
+ // possibly skip ::
+ QTextCursor temp(endCursor);
+ skipCharsForward(&temp, isSpace);
+ const int colons = skipCharsForward(&temp, isColon);
+ skipCharsForward(&temp, isSpace);
+ if (colons == 2 && isValidIdentifierCharAt(temp))
+ endCursor = temp;
+ } while (isValidIdentifierCharAt(endCursor));
+
+ QStringList results;
+ QTextCursor startCursor(endCursor);
+ do {
+ moveCursorToStartOfIdentifier(&startCursor);
+ if (startCursor.position() == endCursor.position())
+ break;
+ QTextCursor temp(endCursor);
+ temp.setPosition(startCursor.position(), QTextCursor::KeepAnchor);
+ results.append(temp.selectedText().remove(QRegularExpression("\\s")));
+ // possibly skip ::
+ temp = startCursor;
+ skipCharsBackward(&temp, isSpace);
+ const int colons = skipCharsBackward(&temp, isColon);
+ skipCharsBackward(&temp, isSpace);
+ if (colons == 2
+ && isValidIdentifierChar(document->characterAt(temp.position() - 1))) {
+ startCursor = temp;
+ }
+ } while (!isValidIdentifierCharAt(startCursor));
+ return results;
}
void moveCursorToEndOfIdentifier(QTextCursor *tc)
{
- moveCursorToStartOrEndOfIdentifier(tc, QTextCursor::NextCharacter);
+ skipCharsForward(tc, isValidIdentifierChar);
}
void moveCursorToStartOfIdentifier(QTextCursor *tc)
{
- moveCursorToStartOrEndOfIdentifier(tc, QTextCursor::PreviousCharacter, 1);
+ skipCharsBackward(tc, isValidIdentifierChar);
}
static bool isOwnershipRAIIName(const QString &name)
diff --git a/src/plugins/cpptools/cpptoolsreuse.h b/src/plugins/cpptools/cpptoolsreuse.h
index d1a1956be3..92e1365d15 100644
--- a/src/plugins/cpptools/cpptoolsreuse.h
+++ b/src/plugins/cpptools/cpptoolsreuse.h
@@ -58,6 +58,7 @@ bool CPPTOOLS_EXPORT isValidFirstIdentifierChar(const QChar &ch);
bool CPPTOOLS_EXPORT isValidIdentifierChar(const QChar &ch);
bool CPPTOOLS_EXPORT isValidIdentifier(const QString &s);
+QStringList CPPTOOLS_EXPORT identifierWordsUnderCursor(const QTextCursor &tc);
QString CPPTOOLS_EXPORT identifierUnderCursor(QTextCursor *cursor);
bool CPPTOOLS_EXPORT isOwnershipRAIIType(CPlusPlus::Symbol *symbol,